Created
November 9, 2010 22:20
-
-
Save kasbah/669941 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
// GlowLoop.cpp : Defines the entry point for the console application. | |
// | |
//#include "stdafx.h" | |
/* | |
int _tmain(int argc, _TCHAR* argv[]) | |
{ | |
return 0; | |
} | |
*/ | |
#ifdef _CH_ | |
#pragma package <opencv> | |
#endif | |
#define CV_NO_BACKWARD_COMPATIBILITY | |
#ifndef _EiC | |
#include "cv.h" | |
#include "highgui.h" | |
#include <stdio.h> | |
#include <ctype.h> | |
#endif | |
// Two windows, one to diaplay the output lines | |
#define GLOW_WINDOW_NAME "Glow" | |
// and one for the input image | |
#define INPUT_WINDOW_NAME "Input" | |
#define CONTROL_WINDOW_NAME GLOW_WINDOW_NAME | |
IplImage *image=0, *smoothImage = 0, *edgeImage = 0, *cannyImage = 0, *greyImage = 0; | |
// Our configuration parameters, which are adjusted by the sliders | |
// Initial blurring of the iamge, to get rid of uninteresting details | |
int smoothRadius = 2; | |
// Parameters to the Canny edge-finder | |
int lowThresh = 10; | |
int highThresh = 100; | |
// Shortest vector that we want to keep (as the short vectors are mostly noise we don't care about) | |
int minLength = 100; | |
// Apply straightening to our vectors to reduce the storage requirement in the projector | |
int straightener = 10; | |
void writeContours( CvSeq* contours ); | |
int main( int argc, char** argv ) | |
{ | |
CvCapture* capture = 0; | |
int doWrite = 0; | |
int levels = 3; | |
CvSeq* contours = 0; | |
//CvSeq* filteredContours = 0; | |
CvMemStorage* contourStorage = cvCreateMemStorage(0); | |
//filteredContours = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvSeq), storage ); | |
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" | |
"\tSpacebar - write contours\n" | |
); | |
cvNamedWindow( GLOW_WINDOW_NAME, 1 ); | |
cvNamedWindow( INPUT_WINDOW_NAME, 1 ); | |
//cvSetMouseCallback( INPUT_WINDOW_NAME, on_mouse, 0 ); | |
cvCreateTrackbar( "Blur", CONTROL_WINDOW_NAME, &smoothRadius, 10, 0 ); | |
cvCreateTrackbar( "Canny low", CONTROL_WINDOW_NAME, &lowThresh, 256, 0 ); | |
cvCreateTrackbar( "Canny high", CONTROL_WINDOW_NAME, &highThresh, 256, 0 ); | |
cvCreateTrackbar( "Straighten", CONTROL_WINDOW_NAME, &straightener, 50, 0 ); | |
cvCreateTrackbar( "Min length", CONTROL_WINDOW_NAME, &minLength, 256, 0 ); | |
for(;;) | |
{ | |
IplImage* frame = 0; | |
int c; | |
frame = cvQueryFrame( capture ); | |
if( !frame ) | |
break; | |
if( !image ) | |
{ | |
/* allocate all the buffers */ | |
image = cvCreateImage( cvGetSize(frame), 8, 3 ); | |
image->origin = frame->origin; | |
greyImage = cvCreateImage( cvGetSize(frame), 8, 1 ); | |
greyImage->origin = frame->origin; | |
smoothImage = cvCreateImage( cvGetSize(frame), 8, 1 ); | |
smoothImage->origin = frame->origin; | |
cannyImage = cvCreateImage( cvGetSize(frame), 8, 1 ); | |
cannyImage->origin = frame->origin; | |
edgeImage = cvCreateImage( cvGetSize(frame), 8, 1 ); | |
edgeImage->origin = frame->origin; | |
} | |
cvCopy( frame, image, 0 ); | |
//cvCvtColor( image, hsv, CV_BGR2HSV ); | |
// copy input frame to a greyscale iamge | |
cvCvtColor( frame, greyImage, CV_BGR2GRAY ); | |
if( smoothRadius > 0 ) | |
{ | |
int smoothWidth = (smoothRadius - 1 ) * 2 + 1; | |
cvSmooth( greyImage, smoothImage, CV_GAUSSIAN, smoothWidth, smoothWidth ); | |
} | |
else | |
{ | |
// no smooth, so just copy | |
cvCopy( greyImage, smoothImage, 0 ); | |
} | |
//int g_thresh = 100; | |
// threshold the image - a cheap alternative to canny | |
//cvThreshold( greyImage, cannyImage, g_thresh, 255, CV_THRESH_BINARY ); | |
// Apply Canny edge-find | |
int aperture = 3; | |
cvCanny( smoothImage, cannyImage, lowThresh, highThresh, aperture ); | |
CvContourScanner scanner = cvStartFindContours(cannyImage, contourStorage, sizeof(CvContour), | |
CV_RETR_LIST/*CV_RETR_EXTERNAL*/, | |
CV_CHAIN_APPROX_SIMPLE); | |
CvSeq* contour; | |
while ((contour = cvFindNextContour(scanner)) != NULL) | |
{ | |
double len = cvContourPerimeter(contour); | |
if (len < minLength) | |
{ | |
// contour too short - throw it away | |
cvSubstituteContour(scanner, NULL); | |
} | |
else | |
{ | |
// contour is long enough, so keep it | |
// but apply some straightening to reduce the amount of storage we need to draw it with our projector | |
CvSeq* c_new = cvApproxPoly(contour, sizeof(CvContour), contourStorage, CV_POLY_APPROX_DP, straightener, 0); | |
cvSubstituteContour(scanner, c_new); | |
} | |
} | |
contours = cvEndFindContours(&scanner); | |
// clear our output image | |
cvSet(edgeImage, cvScalar(0)); | |
// draw the finished set of contours into the output image | |
cvDrawContours( | |
edgeImage, | |
contours, | |
cvScalarAll(255), | |
cvScalarAll(255), | |
100 | |
); | |
if( doWrite != 0) | |
{ | |
writeContours( contours ); | |
doWrite = 0; | |
} | |
//cvClearSeq( contours ); does not return the memory used by the contours! Need to clear contourStorage instead | |
cvClearMemStorage(contourStorage); | |
// Show our output image | |
cvShowImage( GLOW_WINDOW_NAME, edgeImage ); | |
// Show the input image for reference | |
cvShowImage( INPUT_WINDOW_NAME, image ); | |
c = cvWaitKey(10); | |
if( (char) c == 27 ) // Hit Esc to quit the app | |
break; | |
switch( (char) c ) | |
{ | |
case ' ': // hit space to write a contour list | |
doWrite = 1; | |
break; | |
case 'b': | |
//backproject_mode ^= 1; | |
break; | |
case 'c': | |
//track_object = 0; | |
//cvZero( histimg ); | |
break; | |
default: | |
; | |
} | |
} | |
cvReleaseCapture( &capture ); | |
cvDestroyWindow(INPUT_WINDOW_NAME); | |
cvDestroyWindow(GLOW_WINDOW_NAME); | |
cvReleaseMemStorage( &contourStorage ); | |
return 0; | |
} | |
void writeContours( CvSeq* contours ) | |
{ | |
printf("%d contours:\n", contours->total ); | |
// loop over all the contours | |
for( CvSeq* c=contours; c!=NULL; c=c->h_next ) | |
{ | |
CvSeqReader reader; | |
cvStartReadSeq(c, &reader); | |
const int points = c->total; | |
//Each contour is a series of points: | |
printf(" %d points:\n", points ); | |
for (int point = 0; point < points; ++point) | |
{ | |
CvPoint p; | |
CV_READ_SEQ_ELEM(p, reader); | |
// Do stuff with p | |
printf(" (%d,%d)\n", p.x, p.y ); | |
} | |
} | |
} | |
//unused | |
//*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; | |
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 = 10, vmax = 256, smin = 30; | |
*/ | |
/* | |
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; | |
} | |
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; | |
} | |
} | |
//unused | |
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); | |
} | |
*/ | |
#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