Color Detection & Object Tracking


Object detection and segmaentation is the most important and challenging fundamental task of computer visionIt is a critical part in many applications such as image search, image auto-annotation and scene understanding. However it is still an open problem due to the complexity of object classes and images.

The easiest way to detect and segment an object from an image is the color based methods . The colors in the object and the background should have a significant color difference in order to segment objects sucessfully using color based methods.



Simple Example of Detecting Red objects


In this example, I am going to convet a video into a binary image based on the red color. (Red color area of the video is assined to '1' and other area is assigned to '0' in the binary image)

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"

#include <cv.h>
#include <highgui.h>

//This function threshold the HSV image and create a binary image

IplImage* GetThresholdedImage(IplImage* imgHSV){       
       IplImage* imgThresh=cvCreateImage(cvGetSize(imgHSV),IPL_DEPTH_8U, 1);
       cvInRangeS(imgHSV, cvScalar(170,160,60), cvScalar(180,256,256), imgThresh);
       return imgThresh;
} 

 
int main(){
      CvCapture* capture =0;       


      capture = cvCaptureFromCAM(0);
      if(!capture){
printf("Capture failure\n");
return -1;
      }
      
      IplImage* frame=0;
 

      cvNamedWindow("Video");     
      cvNamedWindow("Ball");


      //iterate through each frames of the video     

      while(true){

            frame = cvQueryFrame(capture);           

            if(!frame) break;

            frame=cvCloneImage(frame); 

            cvSmooth(frame, frame, CV_GAUSSIAN,3,3); //smooth the original image using Gaussian kernel

            IplImage* imgHSV = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3);
            cvCvtColor(frame, imgHSV, CV_BGR2HSV); //Change the color format from BGR to HSV
            IplImage* imgThresh = GetThresholdedImage(imgHSV);
          

            cvSmooth(imgThresh, imgThresh, CV_GAUSSIAN,3,3); //smooth the binary image using Gaussian kernel
            
            cvShowImage("Ball", imgThresh);           
            cvShowImage("Video", frame);
           

            //Clean up used images
            cvReleaseImage(&imgHSV);
            cvReleaseImage(&imgThresh);            

            cvReleaseImage(&frame);

            //Wait 50mS
            int c = cvWaitKey(10);
            //If 'ESC' is pressed, break the loop
            if((char)c==27 ) break;      

      }

      cvDestroyAllWindows() ;

      cvReleaseCapture(&capture);     

      return 0;
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

You can download this OpenCV visual c++ project from here(The downloaded file is a compressed .rar folder. So, you have to extract it using Winrar or other suitable software)

Detecting Object using color based method with OpenCV



Explanation

OpenCV usually captures images and videos in 8-bit, unsigned integer, BGR format. In other words, captured images can be considered as 3 matrices, BLUE,RED and GREEN with integer values ranges from 0 to 255.


How BGR image is formed using 3 matrices which represent blue, green and red planes
How BGR image is formed
In the above image, each small box represents a pixel of the image. In real images, these pixels are so small that human eye cannot differentiate.


Usually, one can think that BGR color space is more suitable for color based segmentation. But HSV color space is the most suitable color space for color based image segmentation. So, in the above application, I have converted the color space of original image of the video from BGR to HSV image.

HSV color space is consists of 3 matrices, 'hue', 'saturation' and 'value'. In OpenCV, value range for  'hue', 'saturation' and 'value'  are respectively 0-179, 0-255 and 0-255. 'Hue' represents the color, 'saturation' represents the amount to which that respective color is mixed with white and 'value' represents the  amount to which that respective color is mixed with black.
 

In the above application, I have considered that the red object has 'hue', 'saturation' and 'value' in between 170-180, 160-255, 60-255 respectively. Here the 'hue' is unique for that specific color distribution of that object. But 'saturation' and 'value' may be vary according to the lighting condition of that environment.

Hue values of basic colors
    • Orange  0-22
    • Yellow 22- 38
    • Green 38-75
    • Blue 75-130
    • Violet 130-160
    • Red 160-179
There is a open source software, called 'ColorWheelHSV', that enables you to find the 'hue', 'saturation' and 'value' for a specific object easily. You can download it from here.

These are approximate values. You have to find the exact range of 'hue' values according to the color of the object. I found that the range of 170-179 is perfect for the range of hue values of my object. The 'saturation' and 'value' is depend on the lighting condition of the environment as well as the surface of the object. 

How to find the exact range of 'hue', 'saturation' and 'value' for a object is discussed later in this post.

Now let's discuss new OpenCV methods in the above application.


  •  cvInRangeS(const CvArr* src, CvScalar lower, CvScalar upper, CvArr* dst)
Checks that each array element of 'src'  lies between 'lower' and 'upper'. If so, array element in the relevant location of  'dst' is assigned '255' , otherwise '0'.

Arguments -
    • const CvArr* src - source array which is the image
    • CvScalar lower - inclusive lower bound (In the above application, it is cvScalar(170,160,60) because my lower bound for 'hue','saturation' and 'value'  is 170,160 and 60 respectively)
    • CvScalar upper -  exclusive upper bound (In the above application, it is cvScalar(180,256,256) because my upper bound for 'hue','saturation' and 'value'  is 179,255 and 255 respectively)
    • CvArr* dst -  destination array which is the binary image (must have 8-bit unsigned integer or 8-bit signed integer type)

Output images of a webcam is little bit noisy. So, I smooth each frame of the video and each binary thresholded images with a Gaussian 3x3 kernel. 

All other methods in the above application have been discussed in early OpenCV tutorials





Simple Example of Tracking Red objects


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include <cv.h>
#include <highgui.h>

IplImage* imgTracking;
int lastX = -1;
int lastY = -1;

//This function threshold the HSV image and create a binary image
IplImage* GetThresholdedImage(IplImage* imgHSV){       
    IplImage* imgThresh=cvCreateImage(cvGetSize(imgHSV),IPL_DEPTH_8U, 1);
    cvInRangeS(imgHSV, cvScalar(170,160,60), cvScalar(180,2556,256), imgThresh); 
    return imgThresh;
}

void trackObject(IplImage* imgThresh){
// Calculate the moments of 'imgThresh'
CvMoments *moments = (CvMoments*)malloc(sizeof(CvMoments));
cvMoments(imgThresh, moments, 1);
double moment10 = cvGetSpatialMoment(moments, 1, 0);
double moment01 = cvGetSpatialMoment(moments, 0, 1);
double area = cvGetCentralMoment(moments, 0, 0);

     // if the area<1000, I consider that the there are no object in the image and it's because of the noise, the area is not zero 
if(area>1000){
        // calculate the position of the ball
int posX = moment10/area;
int posY = moment01/area;  
        
       if(lastX>=0 && lastY>=0 && posX>=0 && posY>=0)
{
// Draw a yellow line from the previous point to the current point
cvLine(imgTracking, cvPoint(posX, posY), cvPoint(lastX, lastY), cvScalar(0,0,255), 4);
}

lastX = posX;
lastY = posY;
}

free(moments);
}


int main(){
  
      CvCapture* capture =0;       
      capture = cvCaptureFromCAM(0);
      if(!capture){
printf("Capture failure\n");
return -1;
      }
      
      IplImage* frame=0;
      frame = cvQueryFrame(capture);           
      if(!frame) return -1;
  
     //create a blank image and assigned to 'imgTracking' which has the same size of original video
     imgTracking=cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U, 3);
     cvZero(imgTracking); //covert the image, 'imgTracking' to black

     cvNamedWindow("Video");     
     cvNamedWindow("Ball");

      //iterate through each frames of the video     
      while(true){

            frame = cvQueryFrame(capture);           
            if(!frame) break;
            frame=cvCloneImage(frame); 
            
           cvSmooth(frame, frame, CV_GAUSSIAN,3,3); //smooth the original image using Gaussian kernel

            IplImage* imgHSV = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3); 
            cvCvtColor(frame, imgHSV, CV_BGR2HSV); //Change the color format from BGR to HSV
            IplImage* imgThresh = GetThresholdedImage(imgHSV);
          
            cvSmooth(imgThresh, imgThresh, CV_GAUSSIAN,3,3); //smooth the binary image using Gaussian kernel
            
          //track the possition of the ball
          trackObject(imgThresh);

            // Add the tracking image and the frame
          cvAdd(frame, imgTracking, frame);

          cvShowImage("Ball", imgThresh);           
           cvShowImage("Video", frame);
           
           //Clean up used images
           cvReleaseImage(&imgHSV);
           cvReleaseImage(&imgThresh);            
           cvReleaseImage(&frame);

            //Wait 10mS
            int c = cvWaitKey(10);
            //If 'ESC' is pressed, break the loop
            if((char)c==27 ) break;      
      }

      cvDestroyAllWindows() ;
      cvReleaseImage(&imgTracking);
      cvReleaseCapture(&capture);     

      return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

You can download this OpenCV visual c++ project from here(The downloaded file is a compressed .rar folder. So, you have to extract it using Winrar or other suitable software)

how to track object using color based method with OpenCV
Object Tracking



Explanation


In this application, I use moments to calculate the position of the center of the object. We have to calculate 1st order spacial moments around x-axis and y-axis and the 0th order central moments of the binary image.

0th order central moments of the binary image is equal to the white area of the image in pixels.


  • X coordinate of the position of the center of the object  =  1st order spacial moment around x-axis /  0th order central moment
  • Y coordinate of the position of the center of the object  =  1st order spacial moment around y-axis /  0th order central moment
If there are 2 or more objects in the image, we cannot use this method. And noise of the binary image is also should be at minimum level to get accurate results.

In the above application, I considered that if the white area of the binary image is less than 1000 in pixels, there is no objects in the image because there may be noisy white areas that may have been identified as the object. Usually my object always have an area more than 1000 pixels.

Now, let's discuss new OpenCV methods that can be found in the above application.


Allocate a block of memory which have x bytes and returns a pointer to the beginning of the block. 
The content of the newly allocated block of memory is not initialized, remaining with undetermined values.


  • cvMoments(
    const CvArr* arr, CvMoments* moments, int isBinary=0
    )
Calculates all of the spacial and central moments up to the third order

Arguments -
    • const CvArr* arr - source image which we are going to find the moment
    • CvMoments* moments - Pointer to a memory block to store calculated moments
    • int isBinary - If this argument is equal to non-zero value, all non-zero pixel values are considered as 1 when calculating moments. 



A block of memory previously allocated using a call to malloc is deallocated, making it available again for further allocations.




  •  cvGetSpatialMoment(CvMoments* ptr, int x_order, int y_order)
Retrieve calculated spacial moments from ptr memory block

Arguments -
    • CvMoments* ptr -  pointer to allocated memory block  which store all moments
    • int x_order  -  order of x (>=0)
    • int y_order  -  order of y (>=0)

e.g. -
      cvGetSpatialMoment(moments, 1, 0) retrieves 1st order spacial moment around x-axis
      cvGetSpatialMoment(moments, 0, 1) retrieves 1st order spacial moment around y-axis
      



  • cvGetCentralMoment CvMoments* ptr, int x_order, int y_order )
Retrieve calculated central moments from ptr memory block

Arguments -
  • CvMoments* ptr -  pointer to allocated memory block  which store all moments
  • int x_order  -  order of x (>=0)
  • int y_order  -  order of y (>=0)
e.g. -
cvGetCentralMoment(moments, 0, 0) retrieves 0th order central moment


  • cvLine (CvArr* img, CvPoint pt1CvPoint pt2CvScalar color, int thickness=1)
Draw a line between 2 points, pt1 and pt2

Arguments - 
    • CvArr* img - source image
    • CvPoint pt1 - starting point of the line
    • CvPoint pt2 - ending point of the line
    • CvScalar color - color of the line (in the Blue, Green, Red order)
    • int thickness - thickness of the line in pixels


Except to the  'void trackObject(IplImage* imgThresh)'  method, all other code in the above application is almost same to the 1st application in this post.




How to Find Exact Range for 'Hue', 'Saturation' and 'Value' for a Given Object

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include <cv.h>
#include <highgui.h>

int lowerH=0;
int lowerS=0;
int lowerV=0;

int upperH=180;
int upperS=256;
int upperV=256;

//This function threshold the HSV image and create a binary image
IplImage* GetThresholdedImage(IplImage* imgHSV){

IplImage* imgThresh=cvCreateImage(cvGetSize(imgHSV),IPL_DEPTH_8U, 1);
cvInRangeS(imgHSV, cvScalar(lowerH,lowerS,lowerV), cvScalar(upperH,upperS,upperV), imgThresh);

return imgThresh;

}

//This function create two windows and 6 trackbars for the "Ball" window
void setwindowSettings(){
cvNamedWindow("Video");
cvNamedWindow("Ball");

cvCreateTrackbar("LowerH", "Ball", &lowerH, 180, NULL);
        cvCreateTrackbar("UpperH", "Ball", &upperH, 180, NULL);

cvCreateTrackbar("LowerS", "Ball", &lowerS, 256, NULL);
        cvCreateTrackbar("UpperS", "Ball", &upperS, 256, NULL);

cvCreateTrackbar("LowerV", "Ball", &lowerV, 256, NULL);
        cvCreateTrackbar("UpperV", "Ball", &upperV, 256, NULL);
}

int main(){
CvCapture* capture =0;

capture = cvCaptureFromCAM(0);
if(!capture){
printf("Capture failure\n");
return -1;
}

        IplImage* frame=0;

setwindowSettings();

//iterate through each frames of the video
while(true){

frame = cvQueryFrame(capture);
if(!frame)  break;
frame=cvCloneImage(frame);

IplImage* imgHSV = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3);
cvCvtColor(frame, imgHSV, CV_BGR2HSV); //Change the color format from BGR to HSV

IplImage* imgThresh = GetThresholdedImage(imgHSV);

cvShowImage("Ball", imgThresh);
                cvShowImage("Video", frame);

//Clean up used images
cvReleaseImage(&imgHSV);
cvReleaseImage(&imgThresh);
cvReleaseImage(&frame);

//Wait 80mS
int c = cvWaitKey(80);
//If 'ESC' is pressed, break the loop
if((char)c==27 ) break;

}

cvDestroyAllWindows();
cvReleaseCapture(&capture);

       return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

You can download this OpenCV visual c++ project from here(The downloaded file is a compressed .rar folder. So, you have to extract it using Winrar or other suitable software)



How to adjust ranges of H, S, V to detect the object with minimum noise with OpenCV



Finding the optimum 'hue', 'saturation' and 'value' ranges for an object is a 4 step process.

1) At the beginning, track bars are placed so that maximum ranges for 'hue', 'saturation' and 'value' are set. In other words, 'hue', 'saturation' and 'value'have ranges 0-179, 0-255 and 0-255 respectively. So, we will see a complete white image in the 'Ball' window.

2) First, adjust 'LowerH' and 'UpperH' track bars so that the gap between 'LowerH' and 'UpperH' is minimized. Here you have to be careful that white area in 'Ball' window that represents the object should not be affected, while you are trying to minimize the gap.

3) Then, adjust 'LowerS' and 'UpperS' track bars so that the gap between 'LowerS' and 'UpperS' is minimized. Here you have to be careful that white area in 'Ball' window that represents the object should not be affected, while you are trying to minimize the gap.  

4) Finally, adjust 'LowerV' and 'UpperV' track bars so that the gap between 'LowerV' and 'UpperV' is minimized. Here you have to be careful that white area in 'Ball' window that represents the object should not be affected, while you are trying to minimize the gap.

Now you know the  optimum 'hue', 'saturation' and 'value' ranges for the object. It is 163-179, 126-217 and 68-127 in my case as you can see in the below picture.


H, S and V are properly adjusted to detect the object with lesser noise with OpenCV








Next Tutorial : Object Detection & Shape Recognition using Contours

Previous Tutorial : Rotate Image & Video


64 comments:

  1. hi, how to detect and track four different colored markers on fingertips?
    above you showed only for one color...
    hope to hear from you soon

    ReplyDelete
    Replies
    1. You have to find suitable HSV ranges for those 4 colors. Then you can track them easily.

      Delete
    2. using same method above to detect those 4colors?
      how to find suitable HSV ranges for those 4 colors?

      Delete
    3. I have explained how to find suitable HSV ranges in this post. Pls go through it. To detect 4 colors, you have to generate 4 different binary images.

      Delete
    4. I hate to push thus further but I really really need help. How would you generate 4 different binary images? I know how to find the hsv ranges but how do you code all that together. This would be a HUGE help to me. It may not be much but I need help for a big project deadline

      Delete
    5. IplImage* imgThresh1 = GetThresholdedImage1(imgHSV);
      IplImage* imgThresh2 = GetThresholdedImage2(imgHSV);
      IplImage* imgThresh3 = GetThresholdedImage3(imgHSV);
      IplImage* imgThresh4 = GetThresholdedImage4(imgHSV);

      You have to implement 4 versions of GetThresholdedImage(..) method with different upper and lower bounds to threshold.
      Best way is to define a new function which can take upper and lower bound as its arguments

      Delete
  2. I want to adjust the contrast of a video/frane with histogram equalization. I Converted my RGB image to HSV but how can I discard the latter component V (luminance) to make the algorithm less sensitive to light conditions in the video?.
    I guess apply cv::equalizeHist() to the V channel but it works only for grayscale image
    http://docs.opencv.org/modules/imgproc/doc/histograms.html#equalizehist
    any idea?

    ReplyDelete
    Replies
    1. You can use equalizeHist() function twice for H and S plane of the image. Otherwise you have to write a code to equalize the histogram in H and S plane.

      Delete
  3. hi, is it possible to access kinect camera from your program? I tried connecting kinect and i was using capture = cvCaptureFromCAM(0);
    so i expected kinect shall be detected and will function as normal camera but i see a blank screen. could you please suggest me some work around?

    ReplyDelete
    Replies
    1. Some cameras are not compatible with OpenCV2.1. Try a latest version of OpenCV

      Delete
    2. hi..really good work. helpfull. can you help me this in any color object detection? like human or vehicle? how to do that? and I am using opencv2.4.2.I used your code in video also. but not getting exact result. plsease guide me how to detect object and draw bounding box for that.
      thanx.

      Delete
  4. thank you very much for your tutorial!

    ReplyDelete
  5. how to track the pixel level targets using opencv? tell me the best method to do that tracking

    ReplyDelete
  6. Hi Fernando,
    Thank you very much for great tutorial. It is very helpful for me and who are new to OpenCV. I hope you will provide some more documents.

    Thanks

    ReplyDelete
  7. i am identifying hand gestures first but can not because of my project requirements were not meet but now i am working on gloves having light sources and detect them but this white light is too luminous i am new at OpenCv what should i identify lights or leds then i perform mouse functionality from this identification from some distance
    . 640 *4 480 camera

    ReplyDelete
  8. Can anyone provide code in opencv for background subtraction of images.

    ReplyDelete
  9. hi...i m trying to implement a code for converting a video into gray scale video. i m getting run time error.i tried orielly book code only.bt its nt wrking.i have pasted my code here.can anybody help me plz??
    #include "stdafx.h"
    #include "cv.h"
    #include "highgui.h"

    int main( int argc, char* argv[] )
    {
    CvCapture* capture = 0;
    capture = cvCreateFileCapture("D://Sample.avi" );

    if(!capture)
    { return -1; }

    IplImage *bgr_frame=cvQueryFrame(capture);//Init the video read
    double fps = cvGetCaptureProperty ( capture, CV_CAP_PROP_FPS );

    CvSize size = cvSize( (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH),
    (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT) );

    // creates video: file to write -- codec that's gonna be used -- frame per second -- size of video frames -- grayscale or not
    CvVideoWriter *writer = cvCreateVideoWriter( "D://sample3.avi", CV_FOURCC('M','J','P','G'), fps, size, 1 );

    IplImage* logpolar_frame = cvCreateImage( size, IPL_DEPTH_8U, 1 );

    while( (bgr_frame=cvQueryFrame(capture)) != NULL )
    {
    /* cvLogPolar( bgr_frame,
    logpolar_frame,
    cvPoint2D32f(bgr_frame->width/2, bgr_frame->height/2),
    40,
    CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS );
    */
    cvWriteFrame( writer, bgr_frame );

    }//

    cvReleaseVideoWriter( &writer );
    cvReleaseImage( &logpolar_frame );
    cvReleaseCapture( &capture );

    return(0);

    }

    ReplyDelete
  10. Thanks for sharing this tutorial.

    ReplyDelete
  11. Thanks for the tutorial, I want to ask how to calculate the number of moving vehicle from the contour?
    1 vehicle will detect in some frame...
    Thanks before, anyone could help? please...

    ReplyDelete
  12. Really awesome tutorial, i really want to ask about how to handle mouse click events and mouse movements with my finger using object tracking . thanks in advance!!

    ReplyDelete
  13. Guys, I'm looking for an updated object recognition API that has the ability to count objects such as cars, as well as facial recognition. Any suggestions?

    ReplyDelete
  14. can some one tell how to install stdafx at linux?

    ReplyDelete
    Replies
    1. That header file is automatically generated by the visual studio. You can simply ignore that line

      Delete
  15. I'm trying to use OpenCV to detect the movement (including locations) of a person's feet (heel and toes) while they walk. Is there a way to do this with OpenCV?

    ReplyDelete
  16. Hi, when i work with covariance matrix in opencv, i used 2-dimentions to store the matrixs like in the following code:


    void covariance( IplImage* img_src, int x0, int y0, int height, int width)
    {
    CvMat* output;
    uchar *img_data;
    img_data = (uchar*)img_src->imageData;

    CvMat** img_matcovar;
    img_matcovar = new CvMat*[height];
    for ( int i=0; iwidthStep + (i+y0)*img_src->nChannels]);
    }
    }

    output = cvCreateMat( width, width, CV_64FC1);
    CvMat* meanvec = cvCreateMat( 1, width, CV_32FC1);
    cvCalcCovarMatrix( (const void**)img_matcovar, height, output, meanvec, CV_COVAR_NORMAL);

    }

    but when i changed it into 3-Dimentions matrixs, i could not get the data of the elements, an error occurred at line "printf("%0.2f \n", cvGetReal3D(input,1,1,1));" here is my code, does anyone can help me with this. Thank you so much.

    int main()
    {
    const int rows = 3;
    const int cols = 4;
    const int channels = 3;

    CvMat*** input = new CvMat**[channels];
    for (int i=0; i<channels; i++)
    {
    input[i] = new CvMat*[rows];
    for ( int j=0; j<rows; j++)
    {
    input[i][j] = cvCreateMat( 1, cols, CV_32FC1);
    for ( int k=0; k<cols; k++)
    {
    cvmSet( input[i][j], 0, k, 1);
    }
    }
    }

    printf("%0.2f \n", cvGetReal3D(input,1,1,1));

    while(1)
    {if (cvWaitKey(15) == 27) break;}
    }

    ReplyDelete
  17. Hi, in my project i want to identify objects and then detect what are they(water bottle, ball, etc).
    So can you pls suggest me a method for it. I thought of identifying the objects in the image and then match that object with a object database using SURF method. But the problem is to identfy the whether my image has a object or not. Thanks

    ReplyDelete
  18. hello, i have a picture "leaf color chart", you may search in internet what it look like..
    how can i crop the picture onto 6 part based on the green color automatically.. actually i want to deploy it in android using open cv.. but overall i want to know, is it possible in openCV ? pls help me :(
    thanks

    ReplyDelete
  19. I have had problem with the first example. At first I couldn't to compile for following code "IplImage* frame=0;", I delete it and rewrite it and it works. Later after compiling, the video capture didn't work, when I debug the program and the debugger gave the following message "Bad argument in unknown function, modules\core\Sic\array.cpp". I guess that I failed to link to one of the header. Have you any experience with this error and do you know how to fix it?

    ReplyDelete
    Replies
    1. Hello again, I fixed the problem. Just I added cvRetrieveFrame(capture) before frame = cvQueryFrame(capture);

      Delete
  20. A special thanks for this informative post. I definitely learned a few new things here.

    ReplyDelete
  21. HI, How can threshold the motion of a single person using opencv.

    ReplyDelete
    Replies
    1. If your background is not changing, you can use background subtraction algorithm to detect the motion

      Delete
  22. If we want to track two object what function we have to use instead of moments. Can you please explain with code

    ReplyDelete
  23. Excellent explanation.After tracking the red object can i use the object to move into the 3d room done using opengl.Room construction is done using opengl & i want to control the movement using red object.Thanks in advance

    ReplyDelete
  24. i am running this code to track the red color ball but it is not tracking ball window is showing black not detecting

    ReplyDelete
  25. I try to use some codes to character segment by using OpenCV 2.3.1. But it doesnot work is there any code that help me?

    ReplyDelete
  26. Dude these tutorials could be in a very expensive book. I stumbled across your site after searching for something to help me get started with OpenCV. Thanks so much for helping me to get started with the image processing I'm doing.

    ReplyDelete
  27. Nice bro !! Could you please make a tutorial for Pseudocolor using opencv?? very grateful if you can make it. I'm a newbie in this field. Hope you can teach me..

    Thank you

    ReplyDelete
  28. Hello

    i' have implemented your code and it's working great.
    But when i combine it with my another code, it's getting laggy

    May i ask why you use malloc ?

    Thank you

    ReplyDelete
    Replies
    1. Above OpenCV examples have been written in C. I will convert to C++ soon. (malloc belongs to C style)

      Delete
  29. First of all Fernando thank you very much for this tutorial its by far the best I've found. but i was wondering when will you be updating the rest of the tutorials to C++ I got very confused when I got to color detection. one more thing if you have the time and want to, if you could do a small tutorial on how to get video from an ip camera. Once more thank you very much for all this it has been very very helpful

    ReplyDelete
  30. Hi, i am working on automatic number plate recognition and i need to separate the number plate contour from the rest of the image.Can somebody help me out with this ? Thanks in advance.

    ReplyDelete
  31. hey, it's showing this error
    error C3861: 'cvCvtColor': identifier not found
    error C3861: 'cvCvtColor': identifier not found
    may u tell me how to solve it

    ReplyDelete
  32. hello ,very useful blog for me ! Another question is what if I want to track two red apples ? How to get each posX and posY ?
    would you please teach me how to do this ? Thank you in advance, learningpro.dong@gmail.com.

    ReplyDelete
  33. #include "stdafx.h"
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    #include

    using namespace cv;
    using namespace std;

    Mat imgtrack;
    int lastX=-1;
    int lastY=-1;

    Mat Getthresh(Mat imgHSV,double x,double y)
    {
    Mat imgthresh((int)x,(int)y,CV_8UC1);
    inRange(imgHSV,Scalar(170,160,60),Scalar(180,256,256),imgthresh);
    return imgthresh;
    }


    void trackobj(Mat imgthresh)
    {
    Moments m=moments(imgthresh,true);
    double moment10=m.m10;
    double moment01=m.m01;
    double area=m.m00;
    if(area>1000)
    {
    int posX=moment10/area;
    int posY=moment01/area;
    if(lastX>=0 && lastY>=0 && posX>=0 && posY>=0)
    {
    line(imgtrack,Point(posX,posY),Point(lastX,lastY),Scalar(255,0,0),4);
    }
    lastX=posX;
    lastY=posY;
    }
    }


    int main( int argc, const char** argv )
    {
    VideoCapture cap(0);
    namedWindow("Video");
    namedWindow("Track");
    double dwidth=cap.get(CV_CAP_PROP_FRAME_WIDTH);
    double dheight=cap.get(CV_CAP_PROP_FRAME_HEIGHT);
    Mat imgtrack(dwidth,dheight,CV_8UC3);
    imgtrack.setTo(0);
    while(true)
    {
    Mat frame;
    bool bSuccess=cap.read(frame);
    GaussianBlur(frame,frame,Size (3,3),0,0);
    Mat imgHSV;
    cvtColor(frame,imgHSV,CV_BGR2HSV);
    Mat imgthresh=Getthresh(imgHSV,dwidth,dheight);
    GaussianBlur(imgthresh,imgthresh,Size(3,3),0,0);
    trackobj(imgthresh);
    add(frame,imgtrack,frame);
    imshow("Video",frame);
    imshow("Track",imgthresh);
    if (waitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
    {
    cout << "esc key is pressed by user" << endl;
    }
    }
    return 0;
    }

    I have written the object tracking in c++. The compiler is building but during Run there is an exception of memory handle. Anything wrong with this

    ReplyDelete
  34. so pleased for these lessons, but i have one question, why you use the type C ? I have understood all the lessons until now because you were using Mat type, but now you use IplImage* all changes, for example what before was imread now it has to be cvLoadImage, why occurs this? i don't understand, i'm a begginer and I would appreciatte a pedagogic answer, so much thanks.

    ReplyDelete
    Replies
    1. I agree. From what I understand, opencv2 introduced Mat for C++ which is easier to us, IplImage is for the old opencv and C. I really need a version of this for opencv2 because I dont even want to waste my brain cells on IplImage.

      Delete
  35. simplyfing, how could I pass from IplImage* to Mat and what are the differences between these two types, I mean, a Mat, like you've explained, it's a matrix type where you can put an image , but the type IplImage* it's an image? andhow can i transform one to the other, thanks

    ReplyDelete
    Replies
    1. Codes in this lessons are written in C. If you want to do it in C++, you can convert it very easily. But you should convert every OpenCV/C functions to OpenCV/C++ equivalent.

      Delete
  36. Hello sir, first I want to thank you for all your guides.
    I am using these codes to make a color detector for my robot. How can i change the "Simple Example of Tracking Red objects" so that: IF it tracks the red objet it does smth, ELSE it does smth else. What i mean is that i put the tracking event in a IF-ELSE loop. Thanks ^^

    ReplyDelete
  37. thanks for this great tutorial

    ReplyDelete
  38. can you suggest me function or macros that can control moment of cursor i.e. I want to control cursor position with my application not by mouse?Your help would be appreciated
    Thank you
    -Jay Kothari

    ReplyDelete
  39. Hi I have an image with apple and other background. I would like to extract only apple. When i do it with cvInRangeS of OpenCV, the resultant image is a binary image, which i dont want. I want only the apple with its original color. Could anyone help me out..?

    ReplyDelete
  40. hi i have my final year project to use windows phone by habd gesture movements like scrolling,selecting,sliding mean whole windowsphone(Os) use by finger movements is there opencv work with that????? any idea??? i implemented it to control mouse function in windows destop but i want it for phone camera.......

    ReplyDelete
  41. thanks for the great tutorial :)

    I was wondering if it is possible to modify the code of opencv functions. recently i ve been playing around with houghLines function to detect lines. This functions searches for any lines that have an angle between 0 and 180 degrees, however I know that the lines im looking for will be in the range between 80 and 110 degrees. Is there a way to customise the function to reduce unnecessary processing?

    ReplyDelete
  42. I was wondering, how can I use the data that I got from C++ and use in C#? Is that possible?

    ReplyDelete
  43. I have successfully got your example working on my linux ubuntu laptop . I could compile and run the code after I commented the line #include stdafx.h . Now I am replicating the same thing with raspberry pi and raspicamera but it is giving capture failure . any ideas?

    ReplyDelete
  44. Sir I have a doubt What will happen if the other objects in the screen also have red color?

    ReplyDelete
  45. Thanks for the tutorial :) it works in c++ with a little of change
    I want to ask how to get an average X and Y position of moving object?
    BR

    ReplyDelete
  46. Thank you very much for good tutorial.

    ReplyDelete