aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorN.N. <sevyves@users.sourceforge.net>2009-07-14 21:29:37 +0000
committerN.N. <sevyves@users.sourceforge.net>2009-07-14 21:29:37 +0000
commit9952f0e57d7d6b18e8a83257ec89746365c5a0cd (patch)
treefec501e60175e7b5c2fae59ed637775d3c739130
parentfc773dd890ab246d63927ea1a2ceb0c04994040e (diff)
added pix_opencv_cvk
svn path=/trunk/externals/pix_opencv/; revision=11866
-rw-r--r--Makefile2
-rwxr-xr-xpix_opencv_cvk-help.pd87
-rwxr-xr-xpix_opencv_cvk.cc493
-rwxr-xr-xpix_opencv_cvk.h103
-rwxr-xr-xpix_opencv_dft-help.pd8
-rwxr-xr-xpix_opencv_histo.h4
-rwxr-xr-xpix_opencv_lk.h4
7 files changed, 692 insertions, 9 deletions
diff --git a/Makefile b/Makefile
index 358fe44..c00033f 100644
--- a/Makefile
+++ b/Makefile
@@ -36,7 +36,7 @@ endif
.SUFFIXES = $(EXTENSION)
-SOURCES = pix_opencv_edge.cc pix_opencv_laplace.cc pix_opencv_morphology.cc pix_opencv_distrans.cc pix_opencv_motempl.cc pix_opencv_haarcascade.cc pix_opencv_contours_boundingrect.cc pix_opencv_bgsubstract.cc pix_opencv_contours_convexity.cc pix_opencv_dft.cc pix_opencv_lk.cc pix_opencv_histo.cc
+SOURCES = pix_opencv_edge.cc pix_opencv_laplace.cc pix_opencv_morphology.cc pix_opencv_distrans.cc pix_opencv_motempl.cc pix_opencv_haarcascade.cc pix_opencv_contours_boundingrect.cc pix_opencv_bgsubstract.cc pix_opencv_contours_convexity.cc pix_opencv_dft.cc pix_opencv_lk.cc pix_opencv_histo.cc pix_opencv_cvk.cc
all: $(SOURCES:.cc=.$(EXTENSION))
diff --git a/pix_opencv_cvk-help.pd b/pix_opencv_cvk-help.pd
new file mode 100755
index 0000000..b458249
--- /dev/null
+++ b/pix_opencv_cvk-help.pd
@@ -0,0 +1,87 @@
+#N canvas 266 117 1154 642 10;
+#X obj 384 31 gemhead;
+#X obj 365 414 pix_texture;
+#X obj 365 442 square 2;
+#X obj 9 -28 cnv 15 220 70 empty empty empty 20 12 0 14 -195568 -66577
+0;
+#N canvas 5 49 454 304 gemwin 0;
+#X obj 131 180 gemwin;
+#X obj 67 89 outlet;
+#X obj 67 10 inlet;
+#X obj 67 39 route create;
+#X msg 67 70 set destroy;
+#X msg 182 68 set create;
+#X msg 115 143 create \, 1;
+#X msg 238 112 destroy;
+#X msg 191 141 dimen 256 128;
+#X obj 152 119 t b b;
+#X connect 2 0 3 0;
+#X connect 3 0 4 0;
+#X connect 3 0 9 0;
+#X connect 3 1 5 0;
+#X connect 3 1 7 0;
+#X connect 4 0 1 0;
+#X connect 5 0 1 0;
+#X connect 6 0 0 0;
+#X connect 7 0 0 0;
+#X connect 8 0 0 0;
+#X connect 9 0 8 0;
+#X connect 9 1 6 0;
+#X restore 14 16 pd gemwin;
+#X msg 14 -8 destroy;
+#X text 15 -26 Create window and render;
+#X obj 200 368 pix_texture;
+#X obj 200 396 square 2;
+#X obj 367 159 translateXYZ -2 0 0;
+#X obj 367 193 separator;
+#X obj 343 221 cnv 15 700 180 empty empty empty 20 12 0 14 -24198 -66577
+0;
+#X obj 356 -55 bng 25 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 356 -26 openpanel;
+#X msg 356 -6 open \$1;
+#X obj 364 259 translateXYZ 4 0 0;
+#X text 9 -82 based on basic OCR with Open CV tutorial;
+#X text 9 -71 by damiles : http://blog.damiles.com/?p=93;
+#X text 9 -58 adapted to PD by Yves Degoyon ( ydegoyon@gmail.com )
+;
+#X text 9 -93 pix_opencv_cvk : OCR-like pattern recognition;
+#X msg 532 250 bang;
+#X text 628 251 Compare the incoming frame to the patterns;
+#X text 667 281 Load a new set of patterns from a directory;
+#X text 668 293 All patterns should be of the same size;
+#X msg 550 283 load ../plus 50;
+#X floatatom 591 355 10 0 0 0 - - -;
+#X text 663 356 Distance of the incoming frame compared to the patterns
+;
+#X obj 384 72 pix_image;
+#X msg 560 310 load /usr/local/pd/pdp_opencv/doc/plus 50;
+#X obj 365 335 pix_opencv_cvk /usr/local/pd/pdp_opencv/doc/plus 50
+;
+#X obj 592 380 print distance;
+#X obj 572 251 loadbang;
+#X obj 382 110 pix_grey;
+#X text 433 -33 load patterns \, freate the Gem window and then load
+a character image;
+#X connect 0 0 27 0;
+#X connect 1 0 2 0;
+#X connect 4 0 5 0;
+#X connect 5 0 4 0;
+#X connect 7 0 8 0;
+#X connect 9 0 7 0;
+#X connect 9 0 10 0;
+#X connect 10 0 15 0;
+#X connect 12 0 13 0;
+#X connect 12 0 20 0;
+#X connect 13 0 14 0;
+#X connect 14 0 27 0;
+#X connect 15 0 29 0;
+#X connect 20 0 29 0;
+#X connect 24 0 29 0;
+#X connect 27 0 32 0;
+#X connect 28 0 29 0;
+#X connect 29 0 1 0;
+#X connect 29 1 25 0;
+#X connect 29 1 30 0;
+#X connect 31 0 20 0;
+#X connect 32 0 9 0;
diff --git a/pix_opencv_cvk.cc b/pix_opencv_cvk.cc
new file mode 100755
index 0000000..45e5864
--- /dev/null
+++ b/pix_opencv_cvk.cc
@@ -0,0 +1,493 @@
+////////////////////////////////////////////////////////
+//
+// GEM - Graphics Environment for Multimedia
+//
+// zmoelnig@iem.kug.ac.at
+//
+// Implementation file
+//
+// Copyright (c) 1997-2000 Mark Danks.
+// Copyright (c) Günther Geiger.
+// Copyright (c) 2001-2002 IOhannes m zmoelnig. forum::für::umläute. IEM
+// Copyright (c) 2002 James Tittle & Chris Clepper
+// For information on usage and redistribution, and for a DISCLAIMER OF ALL
+// WARRANTIES, see the file, "GEM.LICENSE.TERMS" in this distribution.
+//
+/////////////////////////////////////////////////////////
+
+#include "pix_opencv_cvk.h"
+
+#include <stdio.h>
+
+CPPEXTERN_NEW_WITH_TWO_ARGS(pix_opencv_cvk, t_symbol *, A_DEFSYM, t_floatarg, A_DEFFLOAT )
+
+/////////////////////////////////////////////////////////
+//
+// pix_opencv_cvk
+//
+/////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////
+//
+// Find the min box. The min box respect original aspect ratio image
+// The image is a binary data and background is white.
+//
+/////////////////////////////////////////////////////////
+
+
+void pix_opencv_cvk :: findX(IplImage* imgSrc,int* min, int* max)
+{
+ int i;
+ int minFound=0;
+ CvMat data;
+ CvScalar maxVal=cvRealScalar(imgSrc->width * 255);
+ CvScalar val=cvRealScalar(0);
+
+ // for each col sum, if sum < width*255 then we find the min
+ // then continue to end to search the max, if sum< width*255 then is new max
+ for (i=0; i< imgSrc->width; i++)
+ {
+ cvGetCol(imgSrc, &data, i);
+ val= cvSum(&data);
+ if(val.val[0] < maxVal.val[0])
+ {
+ *max= i;
+ if(!minFound)
+ {
+ *min= i;
+ minFound= 1;
+ }
+ }
+
+ }
+}
+
+void pix_opencv_cvk :: findY(IplImage* imgSrc,int* min, int* max)
+{
+ int i;
+ int minFound=0;
+ CvMat data;
+ CvScalar maxVal=cvRealScalar(imgSrc->width * 255);
+ CvScalar val=cvRealScalar(0);
+
+ // for each col sum, if sum < width*255 then we find the min
+ // then continue to end to search the max, if sum< width*255 then is new max
+ for (i=0; i< imgSrc->height; i++)
+ {
+ cvGetRow(imgSrc, &data, i);
+ val= cvSum(&data);
+ if(val.val[0] < maxVal.val[0])
+ {
+ *max=i;
+ if(!minFound)
+ {
+ *min= i;
+ minFound= 1;
+ }
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////
+//
+// Find the bounding box.
+//
+//
+/////////////////////////////////////////////////////////
+
+CvRect pix_opencv_cvk :: findBB(IplImage* imgSrc)
+{
+ CvRect aux;
+ int xmin, xmax, ymin, ymax;
+ xmin=xmax=ymin=ymax=0;
+
+ this->findX(imgSrc, &xmin, &xmax);
+ this->findY(imgSrc, &ymin, &ymax);
+
+ aux=cvRect(xmin, ymin, xmax-xmin, ymax-ymin);
+
+ return aux;
+}
+
+IplImage pix_opencv_cvk :: preprocessing(IplImage* imgSrc,int new_width, int new_height)
+{
+ IplImage* result;
+ IplImage* scaledResult;
+
+ CvMat data;
+ CvMat dataA;
+ CvRect bb;//bounding box
+ CvRect bba;//boundinb box maintain aspect ratio
+
+ // find bounding box
+ bb=this->findBB(imgSrc);
+
+ if ( ( bb.width == 0 ) || ( bb.height == 0 ) )
+ {
+ bb.x = 0;
+ bb.y = 0;
+ bb.width = imgSrc->width;
+ bb.height = imgSrc->height;
+ }
+
+ // get bounding box data and no with aspect ratio, the x and y can be corrupted
+ cvGetSubRect(imgSrc, &data, cvRect(bb.x, bb.y, bb.width, bb.height));
+ // create image with this data with width and height with aspect ratio 1
+ // then we get highest size betwen width and height of our bounding box
+ int size=(bb.width>bb.height)?bb.width:bb.height;
+ result=cvCreateImage( cvSize( size, size ), 8, 1 );
+ cvSet(result,CV_RGB(255,255,255),NULL);
+ // copy de data in center of image
+ int x=(int)floor((float)(size-bb.width)/2.0f);
+ int y=(int)floor((float)(size-bb.height)/2.0f);
+ cvGetSubRect(result, &dataA, cvRect(x,y,bb.width, bb.height));
+ cvCopy(&data, &dataA, NULL);
+ // scale result
+ scaledResult=cvCreateImage( cvSize( new_width, new_height ), 8, 1 );
+ cvResize(result, scaledResult, CV_INTER_NN);
+
+ // return processed data
+ return *scaledResult;
+
+}
+
+void pix_opencv_cvk :: load_patterns(void)
+{
+ IplImage* src_image;
+ IplImage prs_image;
+ CvMat row,data;
+ char file[255];
+ int i=0,j;
+ CvMat row_header, *row1;
+
+ this->x_rsamples = 0;
+
+ for( j = 0; j< this->x_nsamples; j++)
+ {
+
+ // load file
+ sprintf(file,"%s/%03d.png",this->x_filepath, j);
+ src_image = cvLoadImage(file,0);
+ if(!src_image)
+ {
+ post("pix_opencv_cvk : error: couldn't load image %s\n", file);
+ continue;
+ }
+ if ( ( this->x_pwidth == -1 ) || ( this->x_pheight == -1 ) )
+ {
+ this->x_pwidth = src_image->width;
+ this->x_pheight = src_image->height;
+ // post( "pix_opencv_cvk : loaded : %s (%dx%d)", file, src_image->width, src_image->height);
+ this->x_rsamples++;
+ }
+ else if ( ( src_image->width != this->x_pwidth ) || ( src_image->height != this->x_pheight ) )
+ {
+ post( "pix_opencv_cvk : error : %s (%dx%d) : wrong size ( should be %dx%d )", file, src_image->width, src_image->height, this->x_pwidth, this->x_pheight);
+ continue;
+ }
+ else
+ {
+ // post( "pix_opencv_cvk : loaded : %s (%dx%d)", file, src_image->width, src_image->height);
+ this->x_rsamples++;
+ }
+
+ // process file
+ prs_image = this->preprocessing(src_image, this->x_pwidth, this->x_pheight);
+ // post( "pix_opencv_cvk : preprocessed : %s (%dx%d)", file, this->x_pwidth, this->x_pheight);
+
+ if ( ( this->trainData == NULL ) || ( this->trainClasses == NULL ))
+ {
+ this->trainData = cvCreateMat(this->x_nsamples, this->x_pwidth*this->x_pheight, CV_32FC1);
+ this->trainClasses = cvCreateMat(this->x_nsamples, 1, CV_32FC1);
+ }
+
+ // set class label
+ cvGetRow(this->trainClasses, &row, j);
+ cvSet(&row, cvRealScalar(i), NULL);
+ // set data
+ cvGetRow(this->trainData, &row, j);
+
+ IplImage* img = cvCreateImage( cvSize( this->x_pwidth, this->x_pheight ), IPL_DEPTH_32F, 1 );
+ // convert 8 bits image to 32 float image
+ cvConvertScale(&prs_image, img, 0.0039215, 0);
+
+ cvGetSubRect(img, &data, cvRect( 0, 0, this->x_pwidth, this->x_pheight) );
+
+ // convert data matrix sizexsize to vecor
+ row1 = cvReshape( &data, &row_header, 0, 1 );
+ cvCopy(row1, &row, NULL);
+ cvReleaseImage( &img );
+ }
+
+ // create the classifier
+ post( "pix_opencv_cvk : loaded : %d samples from %s", this->x_rsamples, this->x_filepath);
+ if ( this->x_rsamples == this->x_nsamples )
+ {
+ this->knn=new CvKNearest( this->trainData, this->trainClasses, 0, false, this->x_nsamples );
+ this->x_nearest=cvCreateMat(1,this->x_nsamples,CV_32FC1);
+ this->x_dist=cvCreateMat(1,this->x_nsamples,CV_32FC1);
+ }
+}
+
+
+/////////////////////////////////////////////////////////
+// Constructor
+//
+/////////////////////////////////////////////////////////
+pix_opencv_cvk :: pix_opencv_cvk(t_symbol *path, t_floatarg nsamples)
+{
+ m_dataout = outlet_new(this->x_obj, &s_anything);
+
+ comp_xsize = 320;
+ comp_ysize = 240;
+
+ rgba = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 4 );
+ rgb = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 3 );
+ grey = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 1 );
+
+ x_filepath = ( char * ) getbytes( 1024 );
+ sprintf( x_filepath, path->s_name );
+ x_nsamples = (int)nsamples;
+
+ x_classify = 0;
+ x_pwidth = -1;
+ x_pheight = -1;
+
+ trainData = NULL;
+ trainClasses = NULL;
+
+ this->load_patterns();
+
+}
+
+/////////////////////////////////////////////////////////
+// Destructor
+//
+/////////////////////////////////////////////////////////
+pix_opencv_cvk :: ~pix_opencv_cvk()
+{
+ // destroy cv structures
+ cvReleaseImage( &rgba );
+ cvReleaseImage( &rgb );
+ cvReleaseImage( &grey );
+ cvReleaseMat( &trainData );
+ cvReleaseMat( &trainClasses );
+
+}
+
+/////////////////////////////////////////////////////////
+// processImage
+//
+/////////////////////////////////////////////////////////
+void pix_opencv_cvk :: processRGBAImage(imageStruct &image)
+{
+ int i;
+
+ if ((this->comp_xsize!=image.xsize)&&(this->comp_ysize!=image.ysize))
+ {
+
+ this->comp_xsize = image.xsize;
+ this->comp_ysize = image.ysize;
+
+ // destroy cv_images to clean memory
+ cvReleaseImage( &rgba );
+ cvReleaseImage( &rgb );
+ cvReleaseImage( &grey );
+
+ // create cv_images
+ this->rgba = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 4 );
+ this->rgb = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 3 );
+ this->grey = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 1 );
+
+ }
+
+ memcpy( rgba->imageData, image.data, image.xsize*image.ysize*4 );
+ cvCvtColor(rgba, grey, CV_BGRA2GRAY);
+
+ if ( this->x_classify )
+ {
+ IplImage prs_image;
+ float result;
+ CvMat row_header, *row1, odata;
+
+ // post( "pix_opencv_cvk : size : (%dx%d)", this->x_pwidth, this->x_pheight);
+
+ // process file
+ prs_image = this->preprocessing(this->grey, this->x_pwidth, this->x_pheight);
+
+ //Set data
+ IplImage* img32 = cvCreateImage( cvSize( this->x_pwidth, this->x_pheight ), IPL_DEPTH_32F, 1 );
+ cvConvertScale(&prs_image, img32, 0.0039215, 0);
+ cvGetSubRect(img32, &odata, cvRect(0,0, this->x_pwidth, this->x_pheight));
+ row1 = cvReshape( &odata, &row_header, 0, 1 );
+
+ result=this->knn->find_nearest(row1,this->x_nsamples,0,0,this->x_nearest,this->x_dist);
+ for ( i=0; i<this->x_nsamples; i++ )
+ {
+ // post( "pix_opencv_cvk : distance : %f", this->x_dist->data.fl[i] );
+ }
+ outlet_float(this->m_dataout, this->x_dist->data.fl[0]);
+
+ cvReleaseImage( &img32 );
+ this->x_classify = 0;
+ }
+
+ memcpy( image.data, rgba->imageData, image.xsize*image.ysize*4 );
+}
+
+void pix_opencv_cvk :: processRGBImage(imageStruct &image)
+{
+ int i;
+
+ if ((this->comp_xsize!=image.xsize)&&(this->comp_ysize!=image.ysize))
+ {
+
+ this->comp_xsize = image.xsize;
+ this->comp_ysize = image.ysize;
+
+ // destroy cv_images to clean memory
+ cvReleaseImage( &rgba );
+ cvReleaseImage( &rgb );
+ cvReleaseImage( &grey );
+
+ // create cv_images
+ this->rgba = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 4 );
+ this->rgb = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 3 );
+ this->grey = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 1 );
+
+ }
+
+ memcpy( rgb->imageData, image.data, image.xsize*image.ysize*3 );
+ cvCvtColor(rgb, grey, CV_BGR2GRAY);
+
+ if ( this->x_classify )
+ {
+ IplImage prs_image;
+ float result;
+ CvMat row_header, *row1, odata;
+
+ // post( "pix_opencv_cvk : size : (%dx%d)", this->x_pwidth, this->x_pheight);
+
+ // process file
+ prs_image = this->preprocessing(this->grey, this->x_pwidth, this->x_pheight);
+
+ //Set data
+ IplImage* img32 = cvCreateImage( cvSize( this->x_pwidth, this->x_pheight ), IPL_DEPTH_32F, 1 );
+ cvConvertScale(&prs_image, img32, 0.0039215, 0);
+ cvGetSubRect(img32, &odata, cvRect(0,0, this->x_pwidth, this->x_pheight));
+ row1 = cvReshape( &odata, &row_header, 0, 1 );
+
+ result=this->knn->find_nearest(row1,this->x_nsamples,0,0,this->x_nearest,this->x_dist);
+ for ( i=0; i<this->x_nsamples; i++ )
+ {
+ // post( "pix_opencv_cvk : distance : %f", this->x_dist->data.fl[i] );
+ }
+ outlet_float(this->m_dataout, this->x_dist->data.fl[0]);
+
+ cvReleaseImage( &img32 );
+ this->x_classify = 0;
+ }
+
+ memcpy( image.data, rgb->imageData, image.xsize*image.ysize*3 );
+}
+
+void pix_opencv_cvk :: processYUVImage(imageStruct &image)
+{
+}
+
+void pix_opencv_cvk :: processGrayImage(imageStruct &image)
+{
+ int i;
+
+ if ((this->comp_xsize!=image.xsize)&&(this->comp_ysize!=image.ysize))
+ {
+
+ this->comp_xsize = image.xsize;
+ this->comp_ysize = image.ysize;
+
+ // destroy cv_images to clean memory
+ cvReleaseImage( &rgba );
+ cvReleaseImage( &rgb );
+ cvReleaseImage( &grey );
+
+ // create cv_images
+ this->rgba = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 4 );
+ this->rgb = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 3 );
+ this->grey = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 1 );
+
+ }
+
+ memcpy( grey->imageData, image.data, image.xsize*image.ysize*1 );
+
+ if ( this->x_classify )
+ {
+ IplImage prs_image;
+ float result;
+ CvMat row_header, *row1, odata;
+
+ // post( "pix_opencv_cvk : size : (%dx%d)", this->x_pwidth, this->x_pheight);
+
+ // process file
+ prs_image = this->preprocessing(this->grey, this->x_pwidth, this->x_pheight);
+
+ //Set data
+ IplImage* img32 = cvCreateImage( cvSize( this->x_pwidth, this->x_pheight ), IPL_DEPTH_32F, 1 );
+ cvConvertScale(&prs_image, img32, 0.0039215, 0);
+ cvGetSubRect(img32, &odata, cvRect(0,0, this->x_pwidth, this->x_pheight));
+ row1 = cvReshape( &odata, &row_header, 0, 1 );
+
+ result=this->knn->find_nearest(row1,this->x_nsamples,0,0,this->x_nearest,this->x_dist);
+ for ( i=0; i<this->x_nsamples; i++ )
+ {
+ // post( "pix_opencv_cvk : distance : %f", this->x_dist->data.fl[i] );
+ }
+ outlet_float(this->m_dataout, this->x_dist->data.fl[0]);
+
+ cvReleaseImage( &img32 );
+ this->x_classify = 0;
+ }
+
+ memcpy( image.data, grey->imageData, image.xsize*image.ysize*1 );
+}
+
+/////////////////////////////////////////////////////////
+// static member function
+//
+/////////////////////////////////////////////////////////
+void pix_opencv_cvk :: obj_setupCallback(t_class *classPtr)
+{
+ class_addmethod(classPtr, (t_method)&pix_opencv_cvk::bangMessCallback,
+ gensym("bang"), A_NULL);
+ class_addmethod(classPtr, (t_method)&pix_opencv_cvk::loadMessCallback,
+ gensym("load"), A_SYMBOL, A_DEFFLOAT, A_NULL);
+}
+
+void pix_opencv_cvk :: bangMessCallback(void *data)
+{
+ if ( GetMyClass(data)->trainData == NULL )
+ {
+ ::post( "pix_opencv_cvk : no patterns loaded : cannot process" );
+ return;
+ }
+ GetMyClass(data)->x_classify=1;
+}
+
+void pix_opencv_cvk :: loadMessCallback(void *data, t_symbol *path, t_floatarg nsamples)
+{
+ if ( (int) nsamples <= 0 )
+ {
+ ::post( "pix_opencv_cvk : wrong number of samples : %d", nsamples );
+ return;
+ }
+ else
+ {
+ GetMyClass(data)->x_nsamples = (int)nsamples;
+ GetMyClass(data)->x_rsamples = 0;
+ cvReleaseMat( &GetMyClass(data)->trainData );
+ cvReleaseMat( &GetMyClass(data)->trainClasses );
+ GetMyClass(data)->trainData = NULL;
+ GetMyClass(data)->trainClasses = NULL;
+ }
+ strcpy( GetMyClass(data)->x_filepath, path->s_name );
+ GetMyClass(data)->load_patterns();
+}
diff --git a/pix_opencv_cvk.h b/pix_opencv_cvk.h
new file mode 100755
index 0000000..aaa3195
--- /dev/null
+++ b/pix_opencv_cvk.h
@@ -0,0 +1,103 @@
+/*-----------------------------------------------------------------
+LOG
+ GEM - Graphics Environment for Multimedia
+
+ Change pix to greyscale
+
+ Copyright (c) 1997-1999 Mark Danks. mark@danks.org
+ Copyright (c) Günther Geiger. geiger@epy.co.at
+ Copyright (c) 2001-2002 IOhannes m zmoelnig. forum::für::umläute. IEM. zmoelnig@iem.kug.ac.at
+ Copyright (c) 2002 James Tittle & Chris Clepper
+ For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ WARRANTIES, see the file, "GEM.LICENSE.TERMS" in this distribution.
+
+-----------------------------------------------------------------*/
+
+#ifndef INCLUDE_PIX_OPENCV_CVK_H_
+#define INCLUDE_PIX_OPENCV_CVK_H_
+
+#include "Base/GemPixObj.h"
+
+#ifndef _EiC
+#include "cv.h"
+#include "highgui.h"
+#include "ml.h"
+#endif
+
+/*-----------------------------------------------------------------
+-------------------------------------------------------------------
+CLASS
+
+ pix_opencv_cvk : OCR like pattern recognition
+ based on basic OCR with Open CV tutorial
+ by damiles : http://blog.damiles.com/?p=93
+
+KEYWORDS
+ pix
+
+DESCRIPTION
+
+-----------------------------------------------------------------*/
+class GEM_EXTERN pix_opencv_cvk : public GemPixObj
+{
+ CPPEXTERN_HEADER(pix_opencv_cvk, GemPixObj)
+
+ public:
+
+ //////////
+ // Constructor
+ pix_opencv_cvk(t_symbol *path, t_floatarg nsamples);
+
+ protected:
+
+ //////////
+ // Destructor
+ virtual ~pix_opencv_cvk();
+
+ //////////
+ // Do the processing
+ virtual void processRGBAImage(imageStruct &image);
+ virtual void processRGBImage(imageStruct &image);
+ virtual void processYUVImage(imageStruct &image);
+ virtual void processGrayImage(imageStruct &image);
+
+ void findX(IplImage* imgSrc,int* min, int* max);
+ void findY(IplImage* imgSrc,int* min, int* max);
+ CvRect findBB(IplImage* imgSrc);
+ IplImage preprocessing(IplImage* imgSrc,int new_width, int new_height);
+ void load_patterns(void);
+
+ // to detect changes in the image size
+ int comp_xsize;
+ int comp_ysize;
+
+
+ private:
+
+ //////////
+ // Static member functions
+ static void bangMessCallback(void *data);
+ static void loadMessCallback(void *data, t_symbol *path, t_floatarg nsamples);
+
+ // internal data
+ t_outlet *m_dataout;
+ int x_classify;
+
+ // open cv classifier data
+ char *x_filepath;
+ int x_nsamples;
+ int x_rsamples;
+ CvMat *trainData;
+ CvMat *trainClasses;
+ CvMat *x_nearest;
+ CvMat *x_dist;
+ int x_pwidth;
+ int x_pheight;
+ CvKNearest *knn;
+
+ // The output and temporary images
+ IplImage *rgba, *rgb, *grey;
+
+};
+
+#endif // for header file
diff --git a/pix_opencv_dft-help.pd b/pix_opencv_dft-help.pd
index 6cdde50..39a24c4 100755
--- a/pix_opencv_dft-help.pd
+++ b/pix_opencv_dft-help.pd
@@ -1,7 +1,7 @@
-#N canvas 41 167 1154 642 10;
+#N canvas 46 183 1154 642 10;
#X obj 396 -37 gemhead;
-#X obj 365 370 pix_texture;
-#X obj 365 398 square 2;
+#X obj 365 380 pix_texture;
+#X obj 365 408 square 2;
#X obj 9 -28 cnv 15 220 70 empty empty empty 20 12 0 14 -195568 -66577
0;
#N canvas 0 22 454 304 gemwin 0;
@@ -37,7 +37,7 @@
#X obj 200 396 square 2;
#X obj 367 159 translateXYZ -2 0 0;
#X obj 367 193 separator;
-#X obj 343 221 cnv 15 600 100 empty empty empty 20 12 0 14 -24198 -66577
+#X obj 343 221 cnv 15 600 150 empty empty empty 20 12 0 14 -24198 -66577
0;
#X obj 511 -66 bng 25 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
diff --git a/pix_opencv_histo.h b/pix_opencv_histo.h
index 900a18b..ca27166 100755
--- a/pix_opencv_histo.h
+++ b/pix_opencv_histo.h
@@ -13,8 +13,8 @@ LOG
-----------------------------------------------------------------*/
-#ifndef INCLUDE_PIX_OPENCV_DISTRANS_H_
-#define INCLUDE_PIX_OPENCV_DISTRANS_H_
+#ifndef INCLUDE_PIX_OPENCV_HISTO_H_
+#define INCLUDE_PIX_OPENCV_HISTO_H_
#include "Base/GemPixObj.h"
diff --git a/pix_opencv_lk.h b/pix_opencv_lk.h
index 3f8c8f6..97859a8 100755
--- a/pix_opencv_lk.h
+++ b/pix_opencv_lk.h
@@ -13,8 +13,8 @@ LOG
-----------------------------------------------------------------*/
-#ifndef INCLUDE_PIX_OPENCV_DISTRANS_H_
-#define INCLUDE_PIX_OPENCV_DISTRANS_H_
+#ifndef INCLUDE_PIX_OPENCV_LK_H_
+#define INCLUDE_PIX_OPENCV_LK_H_
#include "Base/GemPixObj.h"