Created
January 28, 2015 21:59
-
-
Save darkrishabh/bd461690cde3b63d1287 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// final.cpp : main project file. | |
#include "stdafx.h" | |
#ifdef _CH_ | |
#pragma package <opencv> | |
#endif | |
#ifndef _EiC | |
#include "cv.h" | |
#include "highgui.h" | |
#include <stdio.h> | |
#include <ctype.h> | |
#include <windows.h> | |
#endif | |
IplImage *image = 0, *hsv = 0, *hue = 0, *mask = 0, *backproject = 0, *histimg = 0,*image01=0; | |
CvHistogram *hist = 0; | |
float angle=0; | |
//int count = cont->total; // This is number point in contour | |
CvPoint center_final; | |
CvSize size_final; | |
int m=0; | |
int dx,dy; | |
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; | |
CvConnectedComp track_comp; | |
int hdims = 16; | |
float hranges_arr[] = {0,180}; | |
float* hranges = hranges_arr; | |
int vmin = 40, vmax = 126, smin = 90; | |
//-------------------------------- | |
int _brightness = 100; | |
int _contrast = 100; | |
int hist_size = 64; | |
float range_0[]={0,256}; | |
float* ranges[] = { range_0 }; | |
IplImage *src_image = 0, *dst_image = 0, *hist_image = 0, *frame=0; | |
//CvHistogram *hist; | |
uchar lut[256]; | |
CvMat* lut_mat; | |
IplImage *image02 = 0, *image03 = 0, *image04 = 0; | |
int slider_pos = 70; | |
CvMemStorage* stor; | |
CvSeq* cont; | |
CvBox2D32f* box, box_final; | |
CvPoint* PointArray; | |
CvPoint2D32f* PointArray2D32f; | |
/* brightness/contrast callback function */ | |
void update_brightcont( int arg ) | |
{ | |
int brightness = _brightness - 100; | |
int contrast = _contrast - 100; | |
int i, bin_w; | |
float max_value = 0; | |
if( contrast > 0 ) | |
{ | |
double delta = 127.*contrast/100; | |
double a = 255./(255. - delta*2); | |
double b = a*(brightness - delta); | |
for( i = 0; i < 256; i++ ) | |
{ | |
int v = cvRound(a*i + b); | |
if( v < 0 ) | |
v = 0; | |
if( v > 255 ) | |
v = 255; | |
lut[i] = (uchar)v; | |
} | |
} | |
else | |
{ | |
double delta = -128.*contrast/100; | |
double a = (256.-delta*2)/255.; | |
double b = a*brightness + delta; | |
for( i = 0; i < 256; i++ ) | |
{ | |
int v = cvRound(a*i + b); | |
if( v < 0 ) | |
v = 0; | |
if( v > 255 ) | |
v = 255; | |
lut[i] = (uchar)v; | |
} | |
} | |
cvLUT( frame, dst_image, lut_mat ); | |
} | |
//----------- | |
void on_mouse( int event, int x, int y, int flags, void* param ) | |
{ | |
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 -= selection.y; | |
//process(); | |
} | |
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; | |
break; | |
} | |
/* | |
image03 = cvCloneImage(dst_image); | |
image02 = cvCloneImage( image03 ); | |
image04 = cvCloneImage( image03 ); | |
// Create toolbars. HighGUI use. | |
cvCreateTrackbar( "Threshold", "Result", &slider_pos, 255, process_image ); | |
process_image(0);*/ | |
//process(); | |
} | |
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.033333333333333333333333333333333f; | |
sector = 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; | |
return cvScalar(rgb[2], rgb[1], rgb[0],0); | |
} | |
int main( int argc, char** argv ) | |
{ | |
CvCapture* capture = 0; int entry=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("image", 1); | |
cvNamedWindow("Source", 1); | |
cvNamedWindow("Result", 1);//cvNamedWindow("histogram", 0); | |
cvNamedWindow( "Histogram", 1 ); | |
cvNamedWindow( "CamShift", 1 ); | |
cvSetMouseCallback( "CamShiftDemo", on_mouse, 0 ); | |
cvCreateTrackbar( "Threshold", "Source", &slider_pos, 255, 0 ); | |
cvCreateTrackbar( "Vmin", "CamShift", &vmin, 256, 0 ); | |
cvCreateTrackbar( "Vmax", "CamShift", &vmax, 256, 0 ); | |
cvCreateTrackbar( "Smin", "CamShift", &smin, 256, 0 ); | |
for(;;) | |
{ | |
// IplImage* frame = 0; | |
int i, bin_w, c; | |
frame = cvQueryFrame( capture ); | |
if( !frame ) | |
break; | |
cvFlip(frame,frame,0); | |
dst_image = cvCloneImage(frame); | |
lut_mat = cvCreateMatHeader( 1, 256, CV_8UC1 ); | |
cvSetData( lut_mat, lut, 0 ); | |
cvCreateTrackbar("brightness", "image", &_brightness, 200, update_brightcont); | |
cvCreateTrackbar("contrast", "image", &_contrast, 200, update_brightcont); | |
update_brightcont(0); | |
if( !image ) | |
{ | |
/* allocate all the buffers */ | |
image = cvCreateImage( cvGetSize(frame), 8, 3 ); | |
//image02 = cvCreateImage( cvGetSize(frame), 8, 3); | |
image->origin = frame->origin; | |
//image02->origin = frame->origin; | |
hsv = cvCreateImage( cvGetSize(frame), 8, 3 ); | |
hue = cvCreateImage( cvGetSize(frame), 8, 1 ); | |
mask = cvCreateImage( cvGetSize(frame), 8, 1 ); | |
backproject = cvCreateImage( cvGetSize(frame), 8, 1 ); | |
hist = cvCreateHist( 1, &hdims, CV_HIST_ARRAY, &hranges, 1 ); | |
histimg = cvCreateImage( cvSize(320,200), 8, 3 ); | |
cvZero( histimg ); | |
} | |
cvCopy( dst_image, image, 0 ); | |
cvCvtColor( image, hsv, CV_BGR2HSV ); | |
//cvCopy( dst_image,image03, 0 ); | |
image03 = cvCreateImage( cvGetSize(dst_image), 8, 1); | |
image03->origin = dst_image->origin; | |
cvCvtColor( dst_image, image03, CV_BGR2GRAY ); | |
cvSmooth( image03, image03, CV_MEDIAN, 19, 1 ); | |
//image03=cvCloneImage(image); | |
//image02 = cvCreateImage( cvGetSize(image03), 8, 1); | |
//image02->origin = image03->origin; | |
image02 = cvCloneImage( image03 ); | |
//cvCvtColor( image03, image02, CV_BGR2GRAY ); | |
image04 = cvCloneImage( image03 ); image01 = cvCloneImage( image ); | |
int max=1000; | |
// Create dynamic structure and sequence. | |
stor = cvCreateMemStorage(0); | |
cont = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , stor); | |
// Threshold the source image. This needful for cvFindContours(). | |
//cvWaitKey(1000); | |
cvThreshold( image03, image02, slider_pos, 255, CV_THRESH_BINARY ); | |
//cvShowImage( "Source", image03 ); | |
//cvShowImage( "Result", image02 ); | |
//printf("hello"); | |
// Find all contours. | |
cvFindContours( image02, stor, &cont, sizeof(CvContour), | |
CV_RETR_LIST, CV_CHAIN_APPROX_NONE, cvPoint(0,0)); | |
// Clear images. IPL use. | |
cvZero(image04); | |
//cvZero(image04); | |
//printf("%d",cont); | |
//entry=cvWaitKey(1000); | |
// This cycle draw all contours and approximate it by ellipses. | |
for(;cont;cont = cont->h_next) | |
{ | |
//printf("hello1"); | |
int i; // Indicator of cycle. | |
float angle=0; | |
int count = cont->total; // This is number point in contour | |
CvPoint center; | |
CvSize size; | |
// Number point must be more than or equal to 6 (for cvFitEllipse_32f). | |
if( count < 6 ) | |
continue; | |
// Alloc memory for contour point set. | |
PointArray = (CvPoint*)malloc( count*sizeof(CvPoint) ); | |
PointArray2D32f= (CvPoint2D32f*)malloc( count*sizeof(CvPoint2D32f) ); | |
// Alloc memory for ellipse data. | |
box = (CvBox2D32f*)malloc(sizeof(CvBox2D32f)); | |
// box_final = (CvBox2D32f*)malloc(sizeof(CvBox2D32f)); | |
// Get contour point set. | |
cvCvtSeqToArray(cont, PointArray, CV_WHOLE_SEQ); | |
// Convert CvPoint set to CvBox2D32f set. | |
for(i=0; i<count; i++) | |
{ | |
PointArray2D32f[i].x = (float)PointArray[i].x; | |
PointArray2D32f[i].y = (float)PointArray[i].y; | |
} | |
// Fits ellipse to current contour. | |
cvFitEllipse(PointArray2D32f, count, box); | |
// Draw current contour. | |
//cvDrawContours(image04,cont,CV_RGB(255,255,255),CV_RGB(255,255,255),0,1,8,cvPoint(0,0)); | |
// Convert ellipse data from float to integer representation. | |
center.x = cvRound(box->center.x); | |
center.y = cvRound(box->center.y); | |
size.width = cvRound(box->size.width*0.5); | |
size.height = cvRound(box->size.height*0.5); | |
box->angle = -box->angle; | |
//printf("\n%d\n",((size.width + size.height)/2)); | |
// finding the biggest ellipse | |
if( max > ((size.width + size.height)/2) ) | |
{ | |
max =((size.width + size.height)/2); | |
size_final=size; | |
center_final=center; | |
angle=box->angle; | |
} | |
// Draw ellipse | |
// cvEllipse(image04, center, size,box->angle, 0, 360, CV_RGB(0,0,255), 1, CV_AA, 0); | |
//draw the biggest ellipse | |
// Free memory. | |
free(PointArray); | |
free(PointArray2D32f); | |
free(box); | |
//cvShowImage( "Result", image04 ); | |
//cvShowImage( "Source", image03 ); | |
} | |
cvEllipse(image04, center_final, size_final,angle, 0, 360,CV_RGB(0,0,255), 1, CV_AA, 0); | |
if( track_object ) | |
{ | |
int _vmin = vmin, _vmax = vmax; | |
cvInRangeS( hsv, cvScalar(0,smin,MIN(_vmin,_vmax),0), | |
cvScalar(180,256,MAX(_vmin,_vmax),0), mask ); | |
cvSplit( hsv, hue, 0, 0, 0 ); | |
if( track_object < 0 ) | |
{ | |
float max_val = 0.f; | |
cvSetImageROI( hue, selection ); | |
cvSetImageROI( mask, selection ); | |
cvCalcHist( &hue, hist, 0, mask ); | |
cvGetMinMaxHistValue( hist, 0, &max_val, 0, 0 ); | |
cvConvertScale( hist->bins, hist->bins, max_val ? 255. / max_val : 0., 0 ); | |
cvResetImageROI( hue ); | |
cvResetImageROI( mask ); | |
track_window = selection; | |
dx = selection.x; | |
dy = selection.y; | |
track_object = 1; | |
cvZero( histimg ); | |
bin_w = histimg->width / hdims; | |
for( i = 0; i < hdims; i++ ) | |
{ | |
int val = cvRound( cvGetReal1D(hist->bins,i)*histimg->height/255 ); | |
CvScalar color = hsv2rgb(i*180.f/hdims); | |
cvRectangle( histimg, cvPoint(i*bin_w,histimg->height), | |
cvPoint((i+1)*bin_w,histimg->height - val), | |
color, -1, 8, 0 ); | |
} | |
} | |
cvCalcBackProject( &hue, backproject, hist ); | |
cvAnd( backproject, mask, backproject, 0 ); | |
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 ); | |
if( image->origin ) | |
track_box.angle = -track_box.angle; | |
cvZero(image); | |
cvEllipseBox( image, track_box, CV_RGB(255,0,0), 3, CV_AA, 0 ); | |
cvEllipseBox( image01, track_box, CV_RGB(255,0,0), 3, CV_AA, 0 ); | |
} | |
if( select_object && selection.width > 0 && selection.height > 0 ) | |
{ | |
cvSetImageROI( image, selection ); | |
cvXorS( image, cvScalarAll(255), image, 0 ); | |
cvResetImageROI( image ); | |
} | |
if(m==1) | |
{ | |
printf("%f %f\n",track_box.center.x,track_box.center.y); | |
//SetCursorPos(track_box.center.x*6.683,track_box.center.y*6.683); | |
/* INPUT *buffer = new INPUT[3]; //allocate a buffer | |
buffer->type = INPUT_MOUSE; | |
buffer->mi.dx = 100; | |
buffer->mi.dy = 100; | |
buffer->mi.mouseData = 0; | |
buffer->mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE); | |
buffer->mi.time = 0; | |
buffer->mi.dwExtraInfo = 0; | |
SendInput(3,buffer,sizeof(INPUT)); | |
*/ | |
//track_box.center | |
} | |
cvShowImage( "Source", image03 ); | |
cvShowImage( "Result", image04 ); | |
//process(); | |
//SetCursorPos(0, 0); | |
cvShowImage( "image", image01 ); | |
cvShowImage( "CamShift", image ); | |
cvShowImage( "Histogram", histimg ); | |
c = cvWaitKey(10); | |
if( (char) c == 27 ) | |
break; | |
switch( (char) c ) | |
{ | |
case 'b': | |
backproject_mode ^= 1; | |
break; | |
case 'm': | |
m^= 1; | |
break; | |
case 't': | |
selection.x =center_final.x; | |
selection.y = center_final.y; | |
selection.width = size_final.width; | |
selection.height = size_final.height; | |
track_object = -1; | |
//select_object=1; | |
cvDestroyWindow("Source"); | |
cvDestroyWindow("Result"); | |
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("CamShift"); | |
return 0; | |
} | |
#ifdef _EiC | |
main(1,"camshiftdemo.c"); | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment