The CAMSHIFT algorithm is used to quickly track and detect the C / C source code of the moving target, and the OpenCV Beta 4.0 is given this example in its SAMPLE. The algorithm is a brief description (English):
This application demonstrates a fast, simple color tracking algorithm that can be used to track faces, hands. The CAMSHIFT algorithm is a modification of the Meanshift algorithm which is a robust statistical method of finding the mode (top) of a probability distribution. Both CAMSHIFT and Meanshift algorithms exist in the library. While it is a very fast and simple method of tracking, because CAMSHIFT tracks the center and size of the probability distribution of an object, it is only as good as the probability distribution that you produce for the object . Typically the probability distribution is derived from color via a histogram, although it could be produced from correlation, recognition scores or bolstered by frame differencing or motion detection schemes, or joint probabilities of different colors / motions etc. In this application, we use only THE MOST SIMPLISTIC Approach: a 1-D Hue Histogram Is Sampled from The Object in An HSV Color Space Version of The Image. To Produce The PRO Bability Image to Track, Histogram "Back Projection" (We Replace Image Pixels By Their Histogram Hue Value) is used.
Details of the algorithm, please see the paper:
http://www.assuredigit.com/incoming/camshift.pdf
For the use of the OpenCV B4.0 library, please refer to the following related articles:
Http://forum.assuredigit.com/display_topic_threads.asp?forumid=11&topicid=3471
Run file download:
http://www.assuredigit.com/product_tech/demo_download_files/camshiftdemo.exe
This running file compiles through the VC6.0 environment, is a Stand-Alone running program that does not require OpenCV's DLL library support. Before run, connect the camera to the USB interface. You can then use the mouse to select the target.
=====
#ifdef _ch_ # pragma package
IPLIMAGE * image = 0, * HSV = 0, * hue = 0, * mask = 0, * backproject = 0, * histimg = 0; cvhistogram * hist = 0;
int backproject_mode = 0; int select_object = 0; int track_object = 0; int show_hist = 1; CvPoint origin; CvRect selection; CvRect track_window; CvBox2D track_box; // tracking area return box, angled CvConnectedComp track_comp; int hdims = 48; / / Divide the number of HIST, the more precise, the more precise float hranges_arr [] = {0,180}; float * hranges = HRANGES_ARR; int vmin = 10, Vmax = 256, SMIN = 30;
Void on_mouse (int Event, int x, int y, int flags) {if (! image) return;
IF (image-> origin) y = image-> height - y;
IF (select_Object) {selection.x = min (x, origin.x); selection.y = min (y, origin.y); selection.width = selection.x CV_IABS (x - Origin.x); Selection. Height = Selection.y CV_iabs (Y - Origin.y); Selection.x = max (Selection.x, 0); Selection.y = max (Selection.y, 0); Selection.Width = Min (Selection.Width Image-> width; selection.height = min (selection.height, image-> height); selection.width - = selection.x; selection.height - = select;
}
switch (event) {case CV_EVENT_LBUTTONDOWN: origin = cvPoint (x, y); selection = cvRect (x, y, 0,0); select_object = 1; break; case CV_EVENT_LBUTTONUP: select_object = 0; if (selection.width> 0 && selection.height> 0) Track_Object = -1; #ifdef _debug printf ("/ N # Mouse selection area:"); printf ("/ n x =% D, y =% d, width =% D, Height =% D ", selection.x, selection.y, selection.width, selection.height); # endif break;}} cvscalar HSV2RGB (FLOAT HUE) {Int RGB [3], P, Sector; Static Const Int Sector_Data [ ] [3] = {{0, 2, 1}, {1, 2, 0}, {1,0,2}, {2,0,1}, {2, 1, 0}, {0,1 , 2}}; hue * = 0.033333333333333333333331 = CVFLOOR (HUE); P = CVROUND (255 * (hue - sector)); p ^ = SECTOR & 1? 255: 0;
RGB [sector_data [sector] [0]] = 255; RGB [sector_data [sector] [1]] = 0; RGB [sector_data [sector] [2]] = P;
#ifdef _debug printf ("/ N # Convert HSV TO RGB:"); Printf ("/ n hue =% f", hue; printf ("/ n r =% D, g =% D, B =% D ", RGB [0], RGB [1], RGB [2]); # ENDIF
Return Cvscalar (RGB [2], RGB [1], RGB [0], 0);
INT main (int Argc, char ** argv) {cvcapture * capture = 0; iPlimage * frame = 0; if (argc == 1 || (argc == 2 && strlen (argv [1]) == 1 && isdigit (Argv [1] [0])))) Capture = CVCaptureFromCam (argc == 2? Argv [1] [0] - '0': 0); Else IF (argc == 2) Capture = CVCaptureFromavi (Argv [1 ]);
If (! capture) {fprintf (stderr, "could not initialize capturing ... / n"); return -1;} Printf ("Hot Keys: / N" "/ TESC - Quit the Program / N" "/ TC - stop the tracking / n "" / tb - switch to / from backprojection view / n "/ th - show / hide object histogram / n" "to initialize tracking, select the object with mouse / n");
// cvNamedWindow ( "Histogram", 1); cvNamedWindow ( "CamShiftDemo", 1); cvSetMouseCallback ( "CamShiftDemo", on_mouse); // on_mouse custom event cvCreateTrackbar ( "Vmin", "CamShiftDemo", & vmin, 256, 0 ); CvcreateTrackbar ("Vmax", "CamshiftDemo", & Vmax, 256, 0); CvcreateTrackbar ("SMIN", "CamshiftDemo", & SMIN, 256, 0);
For (;;) {INT I, BIN_W, C;
Frame = CVQueryFrame (Capture); if (! frame) Break;
If (! Image) {/ * allocate all the buffers * / image = Cvgetsize (Frame), 8, 3); Image-> Origin = frame-> Origin; HSV = CVCreateImage (Cvgetsize (Frame), 8, 3 Hue = CvccreateImage (Cvgetsize (Frame), 8, 1); Mask = CvcreateImage (Cvgettsize (Frame), 8, 1); BackProject = CvcreateImage (Cvgetsize (Frame), 8, 1); Hist = CvcreateHist (1, & HDIMS, CV_HIST_ARRAY, & HRANGES, 1); // Calculation Temperature Chart Histimg = CVCreateImage (CVSIZE (320, 200), 8, 3); Cvzero (Histimg);
CVCopy (frame, image, 0); CVCVTCOLOR (Image, HSV, CV_BGR2HSV); // Color Space Conversion Bgr TO HSV
IF (Track_Object) {INT _VMIN = VMIN, _VMAX = Vmax; CvinRanges (HSV, Cvscalar (0, Smin, Min (_VMIN), 0), CVSCALAR (180, 256, Max (_VMIN, _VMAX), 0), MASK) ; // Get a binary Mask Cvsplit (HSV, Hue, 0, 0, 0); // only extract the Hue component
IF (Track_Object <0) {float max_val = 0.f; cvsetimageroi (hue, selection); // Get selected Area for ROI CVSetImageRoi (MASK, Selection); // Get Select Area for Mask CvCalchist (& Hue, Hist, 0, Mask); // Calculate the histogram CvgetminmaxHistValue (Hist, 0, & max_val, 0, 0); // only look for maximum CVConvertscale (hist-> bins, hist-> bins, max_val? 255. / max_val: 0., 0 ); // Zoom bin to the interval [0,255] cvresetimageRoi (hue); // Remove ROI CVRESETIMAGEROI (MASK); track_window = selection; track_Object = 1;
Cvzero (Histimg); bin_w = histimg-> width / hdims; // HDIMS: Bin number, bin_w is the width // Painted Direction Map for (i = 0; I
cvCalcBackProject (& hue, backproject, hist); // Use back project methods cvAnd (backproject, mask, backproject, 0); // calling CAMSHIFT algorithm module cvCamShift (backproject, track_window, cvTermCriteria (CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1), & track_comp , & track_box); track_window = track_comp.rect; if (backproject_mode) cvCvtColor (backproject, image, CV_GRAY2BGR); // use backproject grayscale image if (image-> origin) track_box.angle = -track_box.angle; cvEllipseBox (image, TRACK_BOX, CV_RGB (255, 0), 3, CV_AA, 0);} IF (Select_Object && Selection.width> 0 && Selection.Height> 0) {cvsetimageroi (Image, Selection); CVXors (Image, CvscalataLL (255 ), image, 0); cvresetimageroi (image); CvShowImage ("CamshiftDemo", Image); CVShowImage ("Histogram "HISTIMG);
C = CvwaitKey (10); if (c == 27) Break; // exit from for-loop switch (c) {case 'b': backproject_mode ^ = 1; Break; Case 'c': TRACK_Object = 0; Cvzero (Histimg); Break; Case 'h': show_hist ^ = 1; if (! show_hist) cvdestroywindow ("Histogram"); Else CvnamedWindow ("Histogram", 1); Break; default:;}}
CVRELEASECAPTURE (& CAPTURE); CVDESTROYWINDOW ("CamshiftDemo");
Return 0;}