The basic patter recognition and classification with openCV

In this tutorial we go to introduce to the pattern recognitions basics in openCV.

In pattern recognitions before we can classificate an element we need train our system. We go to train with 3 class with 100 samples each one.

Then we create 2 matrix trainData and traninClasses with 300 samples:

int train_sample_count = 300;
CvRNG rng_state = cvRNG(-1);
CvMat* trainData = cvCreateMat( train_sample_count, 2, CV_32FC1 );
CvMat* trainClasses = cvCreateMat( train_sample_count, 1, CV_32FC1 );

Where our 100 first data are class 1, the range 100 to 200 are class 2 and last 100 data are class 3, then we set our trainClasses matrix data:

cvGetRows( trainClasses, &trainClasses1, 0, 100 );
cvSet( &trainClasses1, cvScalar(1) );

cvGetRows( trainClasses, &trainClasses2, 100, 200 );
cvSet( &trainClasses2, cvScalar(2) );

cvGetRows( trainClasses, &trainClasses3, 200, 300 );
cvSet( &trainClasses3, cvScalar(3) );

cvGetRows function set a CvMat structure (matrix structure) with selected rows of source matrix.

cvGetRows( srcMatrix, destMatrix, first_row, last_row );

And set all rows to dest class witn cvSet, this function set all values of matrix to a scalar

cvSet( matrix, cv_scalar_value );

We go to use in this tutorial a random normalized sample in 2D (2D gaussian mixture)  that we generate in openCV with cvRandArr function. For create data sample we need create to cvRandArr, one for x values and other for y values.

//Train sample class 1
cvGetRows( trainData, &trainData1, 0, 100 );
cvGetCol( &trainData1, &colData1x, 0);
cvGetCol( &trainData1, &colData1y, 1);
cvRandArr( &rng_state, &colData1x, CV_RAND_NORMAL, cvScalar(200), cvScalar(50) );
cvRandArr( &rng_state, &colData1y, CV_RAND_NORMAL, cvScalar(200), cvScalar(50) );
//Train sample class 2
cvGetRows( trainData, &trainData2, 100, 200 );
cvGetCol( &trainData2, &colData2x, 0);
cvGetCol( &trainData2, &colData2y, 1);
cvRandArr( &rng_state, &colData2x, CV_RAND_NORMAL, cvScalar(300), cvScalar(50) );
cvRandArr( &rng_state, &colData2y, CV_RAND_NORMAL, cvScalar(300), cvScalar(50) );
//Train sample class 3
cvGetRows( trainData, &trainData3, 200, 300 );
cvGetCol( &trainData3, &colData3x, 0);
cvGetCol( &trainData3, &colData3y, 1);
cvRandArr( &rng_state, &colData3x, CV_RAND_NORMAL, cvScalar(100), cvScalar(30) );
cvRandArr( &rng_state, &colData3y, CV_RAND_NORMAL, cvScalar(400), cvScalar(30) );

Now we can train our classifier. In this basic tutorial, we go to use the k nearest neighbour classifier.

This classifier is the most simplest but it’s used in more cases. This algorithm classify an object by a majority vote of its nearest neighbors.

Then we use CvKNearest openCV class

CvKNearest knn( trainData, trainClasses, 0, false, K );

Where first parameter is train data, second the classes, and last parameter is the nomber of k-neighbour value with maximum value is 32.

Now we have in knn instance a k-nn classifier. Now if we want know in wich class is classified point only need call knn.find_nearest and return the nearest class.

Then we go to classify a values for range [0,0] to [500,500] this our classifier, this is the result:

Red points: Train data of class 1.
Green points: Train data of class 2.
Blue points: Train data of class 3.

Red area: classify as class 1 with more than 5 neighbours in class 1
Light red area: classify as class 1 with less than 5 neighbours in class 1
Green area: classify as class 2 with more than 5 neighbours in class 2
Light green area: classify as class 2 with less than 5 neighbours in class 2
Blue area: classify as class 3 with more than 5 neighbours in class 3
Light blue area: classify as class 2 with less than 5 neighbours in class 2
Orange area: don’t classify

Demo source

56 Comments to “The basic patter recognition and classification with openCV”

  1. [...] do it, we go to use all we learn in before tutorials, we go to use a simple basic painter and the basic pattern recognition and classification with openCV [...]

  2. Luca 21 November 2008 at 10:16 pm #

    Good tutorial, we definetely need to explore more in depth the machine learning part inside openCV ;)

  3. nico meizano 8 December 2008 at 4:32 pm #

    thank you for your good explaination

    im new at these,
    and im trying to understand how it works at opencv about image processing (in universal)
    i heard about pre-processing and processing on image processing.
    and im confuse about that

  4. damiles 9 December 2008 at 10:11 am #

    Hi nico.
    Thanks for your comment.

    Imagine you have a set of images where sizes are distint, then you want all images with same width and height, this is the pre-processing part, when you adapt your images.

    Next you must get some features of images, for example, pixels, or a image histogram, and then you analyze your image with this features (pixels, histogram, …) this is the processing part, when you work with data you need, a lot of times the image pixels no are the data you work.

  5. Rahul 24 January 2009 at 11:21 am #

    This is a very good article on pattern recognition in Open CV. It helped me, I am still in learning stage in open cv. I am working on a project where i need to classify the image features(RGB values). If you can give me some more tutorials on this subject it will be a lot of help for me.

    Thanking you

  6. damiles 24 January 2009 at 12:27 pm #

    This tutorial about ocr recognition can be a good introduction to image calsify: http://blog.damiles.com/?p=93

    Regards. David.

  7. Rahul 8 May 2009 at 9:39 am #

    Thank you i saw the code i understood the over all concept behind the classification. But i am not able to get the declarataion for CvKNearest and the find_nearest. I got the rest of the code and have written my own version of it . Currently i am using kmeans insted of KNN classifier. If you can sort that out i will be done with my a major part of my project.

  8. damiles 8 May 2009 at 9:53 am #

    it’s simply, with CvKNearest knn(…) you initialize the CvKnearest class with knn variable and with train data, and with knn.find_nearest(…); you can classify a data. knn.find_nearest returns the class the data is classified, and in nearest you have a “k” neighbour values the returned value the data is classified is the more neighbours you have.
    Example if in nearest you have this values with k=6 {3,3,2,3,6,3} you data is classified in class 3, 1 and 6 but you have the class resutl 3 because you have 4/k more proxim of class 3, 1/k of class 2 and 1/k of class 6 then the class 3 is have more neighbours than others.

  9. Rahul 8 May 2009 at 1:15 pm #

    Sir,
    I understood the program. But when i tried to implement the same in my code i am being showed an error. I am working on visual studio express edition.

  10. damiles 8 May 2009 at 1:16 pm #

    Please, send me the error…

  11. Rahul 8 May 2009 at 3:09 pm #

    Sir,
    It is working now. But the trainclasses are all the same.
    I can mail the code. It is some what customized. Can you give me your mailid.

  12. Rahul 9 May 2009 at 8:50 am #

    Sir,
    I sent the code. Please go through them.

  13. Rahul 9 May 2009 at 9:23 am #

    Sir,
    Is there a facility in opencv to append a matrix to another.

  14. Rahul 9 May 2009 at 1:04 pm #

    Sir,
    In opencv
    for image resizing we have cvPyrDown but its uses interpolation wile resizing. I need to get only the samples with out interpolation. Like in matalb
    sub=im(1:interval:r,1:interval:c);

  15. Rahul 11 May 2009 at 9:15 am #

    Sir,
    I solved teh resizing with out interpolation.

    IplImage * subsample(IplImage * input, unsigned int intval_r, unsigned int intval_c) {
    CvMat *subrows=cvCreateMat(input->width/intval_r,input->height,cvGetElemType(input));

    //cout<<”One”<height, intval_r);
    //cvShowImage(“main”,&subrows);
    //printf(“st:%d:\n”,input->depth);
    //cout<<”two”<width, subrows->height,cvGetElemType(input));
    cvTranspose(subrows, temp);

    //cout<<”three”<height/intval_r),(temp->width/intval_c),cvGetElemType(input));
    cvGetRows(temp, out, 1, temp->height, intval_c);
    CvMat * out2=cvCreateMat(out->width,out->height,cvGetElemType(input));
    cvTranspose(out, out2);

    //cout<<”four”<height;
    sz.width=out2->width;

    IplImage *dst=cvCreateImage(sz,input->depth,input->nChannels);
    cvGetImage(out2,dst);
    //dst=&hdr;
    SImage src_dst(&dst);
    src_dst.display(“SAMPLED”);
    cvWaitKey();
    return dst;

    }

  16. Rahul 20 May 2009 at 9:35 am #

    Can you help me with the Knn classifier problem…?

  17. Rahul 22 May 2009 at 9:01 am #

    I understood the program now. Thank you. But o dont know the value of trainClasses. You set the values to 1,2 and 3. I dont have that information about the pixels in the image. Can you suggest me any mehtod to follow now

  18. damiles 22 May 2009 at 9:09 am #

    First. What do you want classify? Faces, pixels, cars, objects, characters, …?
    Second, what properties of objects do you want use?, Pixels, contours…

  19. Gui 23 May 2009 at 6:46 pm #

    first, thanks for the tutorial, it’s exactly what i want to do.
    But, i’m having a problem with train data, i used:
    cvGetRows( trainData, &trainData1, 0, 100 );
    trainData1= cvMat( 100, 3, CV_32F, &dado1[0][0] );
    cvGetRows( trainData, &trainData2, 100, 200 );
    trainData2= cvMat( 100, 3, CV_32F, &dado2[0][0] );
    cvGetRows( trainData, &trainData3, 200, 300 );
    trainData3= cvMat( 100, 3, CV_32F, &dado3[0][0] );

    CvKNearest knn( trainData, trainClasses, 0, false, K );

    where dado1[][],dado2[][] and dado3[][] are a C matrix (float[][])
    it compiles without problem, but when i execute the program it show:
    “Input samples must be
    floating-point matrix (x)”
    What is the problem with my code??
    thanks.

  20. damiles 23 May 2009 at 8:34 pm #

    Please, you must verify that trainData is a floating matrix data.

  21. Gui 23 May 2009 at 10:13 pm #

    i can’t understand that. how can i verify??
    and dado1, dado2 and dado3 are matrix of float (float **dado1,…)
    i’m new with opencv, this matrix structure isn’t that simple for me.
    thanks

  22. damiles 24 May 2009 at 12:31 pm #

    Please post the “trainData” variable definition.

  23. Gui 24 May 2009 at 7:52 pm #

    I have posted some parts of my code at this link:
    http://codepad.org/uI24XAg7
    thanks

  24. damiles 25 May 2009 at 8:22 am #

    I see the code and i think it’s correctly, you sure need debug your app line by line.

  25. Rahul 25 May 2009 at 12:32 pm #

    I am working on retinal images where i have to identify exudates based on pixel properties. A collection of pixel information is stored and then classification is done.
    The collection is like this
    G values
    sum of squares of R and G
    in a window of 3×3 centered on a pixel
    max value in that window
    min value in that window
    mean value in that window
    entropy of that window

    These are the pixel values used for classification.
    G – green channel
    R – Red channel

  26. Gui 26 May 2009 at 12:55 am #

    ok, i will try to do it,
    i’m using VC++ how can i see the data of a CvMat structure??
    i saw only some information, but i can’t find the real data.
    thank for all.

  27. damiles 26 May 2009 at 8:43 am #

    I use linux and gdb or ddd, i can’t help you in this. Sorry.

  28. Gui 27 May 2009 at 3:53 am #

    ok, thanks for all

  29. Rahul 28 May 2009 at 2:48 pm #

    hi Damiles, Thank you i got the problem in my program. ITs working now.

  30. andol 16 June 2009 at 1:40 pm #

    hi Damiles, it is nice post. but, can you share your pattern samples ?

  31. damiles 16 June 2009 at 1:49 pm #

    In this tutorial andol, the pattern samples are random numbers i generate in the code the class 1 samples are:

    cvRandArr( &rng_state, &colData1x, CV_RAND_NORMAL, cvScalar(200), cvScalar(50) );
    cvRandArr( &rng_state, &colData1y, CV_RAND_NORMAL, cvScalar(200), cvScalar(50) );

    are random numbers with normal distribution that position are 200, 200 with a width,height of 50.

  32. piponazo 15 July 2009 at 10:41 am #

    Thanks for your contribution. I’m stating to research in the Action Recognition research area, and to start with easy examples of classification like this is very useful ;) .

  33. bubuzzz 2 September 2009 at 10:37 am #

    Hi damiles,

    I am doing a research on the facial expression detection for my university and really stuck with it. what i try to do is matching images from the webcam with some labelled images and then decide the emotion. Can you give me some suggestion about it? Which algorithm is the most suitable? And with which algorithm can i expand the database (labelled images) for the future use ?

    I am only a 2 nd student so be mercy if these are silly questions :D . thank you very much

  34. damiles 2 September 2009 at 11:33 am #

    hi bubuzzz, i don’t know most suitable algorithm, you must look for paper about it.

    You only need know all patter recognition is:

    1. Processing image
    2. Extract image features
    3. Normalize features
    4. Compare the normalized features with your database of features and classificate it.
    5. If you can classificate get user input for classificate and add it to database if you consider to add.

    Regards david.

  35. dheeraj 22 September 2009 at 3:20 pm #

    great…………………:)

  36. Manivasakan 24 September 2009 at 7:50 am #

    hi,

    I want classify the star shape from image using knn. can you please tell me the how to get the traindata and trainclass information from image.

    thanks in advance
    Manivasakan

  37. damiles 24 September 2009 at 9:14 am #

    if you go to classify only the star then you have only one class, for traindata you can get N images of stars and cvMoments to get the statistical data.

  38. Manivasakan 25 September 2009 at 5:31 am #

    thank you very much for reply.

    How to assign trainclass values from source image and traindata values from star image?

    can you give some code sample?

    Thanks
    Manivasakan.

  39. Sharath 9 October 2009 at 1:56 pm #

    Hi Damiles,
    Its a nice post you have in here. It allowed be to have a start with processing with videos. I was looking for the procedure to create a Video Frame with random numbers.Can u help?

  40. Burak 13 January 2010 at 1:10 pm #

    Hi,

    I need recognize the red objects from webcam stream

    what can i do ? like algorithm classes or comments for it ?

  41. damiles 13 January 2010 at 1:17 pm #

    if you need diference the red objects is very simply, only need chek an histogram of red channel pixels, and do threshold to get as white a objects with red or no.

    It’s simply, get webcam image, for each pixel if red component of pixel > threshold then this is a red object pixel.

    Later you can give a 8-connected algorithm to detect diferent red objects in image.

  42. Burak 13 January 2010 at 10:29 pm #

    if that is like simple can you give me code for it ? it will be very usefull for me (: thx for fast reply !

  43. damiles 14 January 2010 at 7:17 pm #

    Burak, this is your task, i can’t create your work. Instead, i go to create a tutorial with demo code to this tasks.

    Please Wait 1 day please.

  44. Burak 14 January 2010 at 11:27 pm #

    that will be enough for me .

    i check lots of website blog or email grp but none of them answering anything . thx again i will w8

  45. KhaNguyen 15 January 2010 at 5:03 pm #

    Hi Damiles,
    I am new with OpenCV. I would like to recognize some kind of shape like rounded rectangle, circle,trapezium,… Could you please tell me how I can do it with OpenCV?Thanks.

  46. damiles 16 January 2010 at 10:44 pm #

    Hi KhaNguyen, i read your email, but i can’t respond… For this task try to retrive the contours and get a aprox poly of its, and with moments and angles detect the object Type.

  47. cxie 4 February 2010 at 11:10 am #

    If lots of train data, the KNearest constructer will takes longer time to train the class for each time when the program start to run. Is it possible to save the trained result into a file, when the program start to run each time, it just read the train result from the saved file and applied to KNearest object ithout trainning to save the start up time?

  48. damiles 4 February 2010 at 11:13 am #

    Yes of course you can save this data into a file to load in other sessions… To do this there are opencv functions.

  49. KhaNguyen 8 March 2010 at 11:47 pm #

    Hi Damiles,

    Thanks for your reply. So, if i train the system like basicOCR for shape object. Is it possible to do that?
    Thanks.

  50. damiles 9 March 2010 at 10:03 am #

    Hi KhaNguyen, of course, you can train and classify with any vector you want, you can train and clasify for example with a vector with data area, perimeter and radius or any value you want.


Leave a Reply