converted some OpenCV C samples to C++

This commit is contained in:
Vadim Pisarevsky 2010-11-27 23:15:16 +00:00
parent f40e51588b
commit ee3618243d
69 changed files with 22799 additions and 1788 deletions

View File

@ -1,97 +0,0 @@
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#define ARRAY 1
int main( int argc, char** argv )
{
IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );
#if !ARRAY
CvMemStorage* storage = cvCreateMemStorage(0);
#endif
cvNamedWindow( "hull", 1 );
for(;;)
{
char key;
int i, count = rand()%100 + 1, hullcount;
CvPoint pt0;
#if !ARRAY
CvSeq* ptseq = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvContour),
sizeof(CvPoint), storage );
CvSeq* hull;
for( i = 0; i < count; i++ )
{
pt0.x = rand() % (img->width/2) + img->width/4;
pt0.y = rand() % (img->height/2) + img->height/4;
cvSeqPush( ptseq, &pt0 );
}
hull = cvConvexHull2( ptseq, 0, CV_CLOCKWISE, 0 );
hullcount = hull->total;
#else
CvPoint* points = (CvPoint*)malloc( count * sizeof(points[0]));
int* hull = (int*)malloc( count * sizeof(hull[0]));
CvMat pointMat = cvMat( 1, count, CV_32SC2, points );
CvMat hullMat = cvMat( 1, count, CV_32SC1, hull );
for( i = 0; i < count; i++ )
{
pt0.x = rand() % (img->width/2) + img->width/4;
pt0.y = rand() % (img->height/2) + img->height/4;
points[i] = pt0;
}
cvConvexHull2( &pointMat, &hullMat, CV_CLOCKWISE, 0 );
hullcount = hullMat.cols;
#endif
cvZero( img );
for( i = 0; i < count; i++ )
{
#if !ARRAY
pt0 = *CV_GET_SEQ_ELEM( CvPoint, ptseq, i );
#else
pt0 = points[i];
#endif
cvCircle( img, pt0, 2, CV_RGB( 255, 0, 0 ), CV_FILLED, CV_AA, 0 );
}
#if !ARRAY
pt0 = **CV_GET_SEQ_ELEM( CvPoint*, hull, hullcount - 1 );
#else
pt0 = points[hull[hullcount-1]];
#endif
for( i = 0; i < hullcount; i++ )
{
#if !ARRAY
CvPoint pt = **CV_GET_SEQ_ELEM( CvPoint*, hull, i );
#else
CvPoint pt = points[hull[i]];
#endif
cvLine( img, pt0, pt, CV_RGB( 0, 255, 0 ), 1, CV_AA, 0 );
pt0 = pt;
}
cvShowImage( "hull", img );
key = (char) cvWaitKey(0);
if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC'
break;
#if !ARRAY
cvClearMemStorage( storage );
#else
free( points );
free( hull );
#endif
}
cvDestroyWindow( "hull" );
return 0;
}
#ifdef _EiC
main(1,"convexhull.c");
#endif

View File

@ -1,120 +0,0 @@
#include <opencv2/imgproc/imgproc_c.h>
#include <opencv2/highgui/highgui.hpp>
#include <stdio.h>
char file_name[] = "baboon.jpg";
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;
CvHistogram *hist;
uchar lut[256];
CvMat* lut_mat;
/* 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;
/*
* The algorithm is by Werner D. Streidt
* (http://visca.com/ffactory/archives/5-99/msg00021.html)
*/
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( src_image, dst_image, lut_mat );
cvShowImage( "image", dst_image );
cvCalcHist( &dst_image, hist, 0, NULL );
cvZero( dst_image );
cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 );
cvScale( hist->bins, hist->bins, ((double)hist_image->height)/max_value, 0 );
/*cvNormalizeHist( hist, 1000 );*/
cvSet( hist_image, cvScalarAll(255), 0 );
bin_w = cvRound((double)hist_image->width/hist_size);
for( i = 0; i < hist_size; i++ )
cvRectangle( hist_image, cvPoint(i*bin_w, hist_image->height),
cvPoint((i+1)*bin_w, hist_image->height - cvRound(cvGetReal1D(hist->bins,i))),
cvScalarAll(0), -1, 8, 0 );
cvShowImage( "histogram", hist_image );
}
int main( int argc, char** argv )
{
// Load the source image. HighGUI use.
src_image = cvLoadImage( argc == 2 ? argv[1] : file_name, 0 );
if( !src_image )
{
printf("Image was not loaded.\n");
return -1;
}
dst_image = cvCloneImage(src_image);
hist_image = cvCreateImage(cvSize(320,200), 8, 1);
hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
lut_mat = cvCreateMatHeader( 1, 256, CV_8UC1 );
cvSetData( lut_mat, lut, 0 );
cvNamedWindow("image", 0);
cvNamedWindow("histogram", 0);
cvCreateTrackbar("brightness", "image", &_brightness, 200, update_brightcont);
cvCreateTrackbar("contrast", "image", &_contrast, 200, update_brightcont);
update_brightcont(0);
cvWaitKey(0);
cvReleaseImage(&src_image);
cvReleaseImage(&dst_image);
cvReleaseHist(&hist);
return 0;
}
#ifdef _EiC
main(1,"demhist.c");
#endif

View File

@ -1,136 +0,0 @@
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
// Rearrange the quadrants of Fourier image so that the origin is at
// the image center
// src & dst arrays of equal size & type
void cvShiftDFT(CvArr * src_arr, CvArr * dst_arr )
{
CvMat * tmp=0;
CvMat q1stub, q2stub;
CvMat q3stub, q4stub;
CvMat d1stub, d2stub;
CvMat d3stub, d4stub;
CvMat * q1, * q2, * q3, * q4;
CvMat * d1, * d2, * d3, * d4;
CvSize size = cvGetSize(src_arr);
CvSize dst_size = cvGetSize(dst_arr);
int cx, cy;
if(dst_size.width != size.width ||
dst_size.height != size.height){
cvError( CV_StsUnmatchedSizes, "cvShiftDFT", "Source and Destination arrays must have equal sizes", __FILE__, __LINE__ );
}
if(src_arr==dst_arr){
tmp = cvCreateMat(size.height/2, size.width/2, cvGetElemType(src_arr));
}
cx = size.width/2;
cy = size.height/2; // image center
q1 = cvGetSubRect( src_arr, &q1stub, cvRect(0,0,cx, cy) );
q2 = cvGetSubRect( src_arr, &q2stub, cvRect(cx,0,cx,cy) );
q3 = cvGetSubRect( src_arr, &q3stub, cvRect(cx,cy,cx,cy) );
q4 = cvGetSubRect( src_arr, &q4stub, cvRect(0,cy,cx,cy) );
d1 = cvGetSubRect( src_arr, &d1stub, cvRect(0,0,cx,cy) );
d2 = cvGetSubRect( src_arr, &d2stub, cvRect(cx,0,cx,cy) );
d3 = cvGetSubRect( src_arr, &d3stub, cvRect(cx,cy,cx,cy) );
d4 = cvGetSubRect( src_arr, &d4stub, cvRect(0,cy,cx,cy) );
if(src_arr!=dst_arr){
if( !CV_ARE_TYPES_EQ( q1, d1 )){
cvError( CV_StsUnmatchedFormats, "cvShiftDFT", "Source and Destination arrays must have the same format", __FILE__, __LINE__ );
}
cvCopy(q3, d1, 0);
cvCopy(q4, d2, 0);
cvCopy(q1, d3, 0);
cvCopy(q2, d4, 0);
}
else{
cvCopy(q3, tmp, 0);
cvCopy(q1, q3, 0);
cvCopy(tmp, q1, 0);
cvCopy(q4, tmp, 0);
cvCopy(q2, q4, 0);
cvCopy(tmp, q2, 0);
}
}
int main(int argc, char ** argv)
{
const char* filename = argc >=2 ? argv[1] : "lena.jpg";
IplImage * im;
IplImage * realInput;
IplImage * imaginaryInput;
IplImage * complexInput;
int dft_M, dft_N;
CvMat* dft_A, tmp;
IplImage * image_Re;
IplImage * image_Im;
double m, M;
im = cvLoadImage( filename, CV_LOAD_IMAGE_GRAYSCALE );
if( !im )
return -1;
realInput = cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 1);
imaginaryInput = cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 1);
complexInput = cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 2);
cvScale(im, realInput, 1.0, 0.0);
cvZero(imaginaryInput);
cvMerge(realInput, imaginaryInput, NULL, NULL, complexInput);
dft_M = cvGetOptimalDFTSize( im->height - 1 );
dft_N = cvGetOptimalDFTSize( im->width - 1 );
dft_A = cvCreateMat( dft_M, dft_N, CV_64FC2 );
image_Re = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1);
image_Im = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1);
// copy A to dft_A and pad dft_A with zeros
cvGetSubRect( dft_A, &tmp, cvRect(0,0, im->width, im->height));
cvCopy( complexInput, &tmp, NULL );
if( dft_A->cols > im->width )
{
cvGetSubRect( dft_A, &tmp, cvRect(im->width,0, dft_A->cols - im->width, im->height));
cvZero( &tmp );
}
// no need to pad bottom part of dft_A with zeros because of
// use nonzero_rows parameter in cvDFT() call below
cvDFT( dft_A, dft_A, CV_DXT_FORWARD, complexInput->height );
cvNamedWindow("win", 0);
cvNamedWindow("magnitude", 0);
cvShowImage("win", im);
// Split Fourier in real and imaginary parts
cvSplit( dft_A, image_Re, image_Im, 0, 0 );
// Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2)
cvPow( image_Re, image_Re, 2.0);
cvPow( image_Im, image_Im, 2.0);
cvAdd( image_Re, image_Im, image_Re, NULL);
cvPow( image_Re, image_Re, 0.5 );
// Compute log(1 + Mag)
cvAddS( image_Re, cvScalarAll(1.0), image_Re, NULL ); // 1 + Mag
cvLog( image_Re, image_Re ); // log(1 + Mag)
// Rearrange the quadrants of Fourier image so that the origin is at
// the image center
cvShiftDFT( image_Re, image_Re );
cvMinMaxLoc(image_Re, &m, &M, NULL, NULL, NULL);
cvScale(image_Re, image_Re, 1.0/(M-m), 1.0*(-m)/(M-m));
cvShowImage("magnitude", image_Re);
cvWaitKey(-1);
return 0;
}

View File

@ -1,184 +0,0 @@
#include <opencv2/imgproc/imgproc_c.h>
#include <opencv2/highgui/highgui.hpp>
#include <stdio.h>
char wndname[] = "Distance transform";
char tbarname[] = "Threshold";
int mask_size = CV_DIST_MASK_5;
int build_voronoi = 0;
int edge_thresh = 100;
int dist_type = CV_DIST_L1;
// The output and temporary images
IplImage* dist = 0;
IplImage* dist8u1 = 0;
IplImage* dist8u2 = 0;
IplImage* dist8u = 0;
IplImage* dist32s = 0;
IplImage* gray = 0;
IplImage* edge = 0;
IplImage* labels = 0;
// threshold trackbar callback
void on_trackbar( int dummy )
{
static const uchar colors[][3] =
{
{0,0,0},
{255,0,0},
{255,128,0},
{255,255,0},
{0,255,0},
{0,128,255},
{0,255,255},
{0,0,255},
{255,0,255}
};
int msize = mask_size;
int _dist_type = build_voronoi ? CV_DIST_L2 : dist_type;
cvThreshold( gray, edge, (float)edge_thresh, (float)edge_thresh, CV_THRESH_BINARY );
if( build_voronoi )
msize = CV_DIST_MASK_5;
if( _dist_type == CV_DIST_L1 )
{
cvDistTransform( edge, edge, _dist_type, msize, NULL, NULL );
cvConvert( edge, dist );
}
else
cvDistTransform( edge, dist, _dist_type, msize, NULL, build_voronoi ? labels : NULL );
if( !build_voronoi )
{
// begin "painting" the distance transform result
cvConvertScale( dist, dist, 5000.0, 0 );
cvPow( dist, dist, 0.5 );
cvConvertScale( dist, dist32s, 1.0, 0.5 );
cvAndS( dist32s, cvScalarAll(255), dist32s, 0 );
cvConvertScale( dist32s, dist8u1, 1, 0 );
cvConvertScale( dist32s, dist32s, -1, 0 );
cvAddS( dist32s, cvScalarAll(255), dist32s, 0 );
cvConvertScale( dist32s, dist8u2, 1, 0 );
cvMerge( dist8u1, dist8u2, dist8u2, 0, dist8u );
// end "painting" the distance transform result
}
else
{
int i, j;
for( i = 0; i < labels->height; i++ )
{
int* ll = (int*)(labels->imageData + i*labels->widthStep);
float* dd = (float*)(dist->imageData + i*dist->widthStep);
uchar* d = (uchar*)(dist8u->imageData + i*dist8u->widthStep);
for( j = 0; j < labels->width; j++ )
{
int idx = ll[j] == 0 || dd[j] == 0 ? 0 : (ll[j]-1)%8 + 1;
int b = cvRound(colors[idx][0]);
int g = cvRound(colors[idx][1]);
int r = cvRound(colors[idx][2]);
d[j*3] = (uchar)b;
d[j*3+1] = (uchar)g;
d[j*3+2] = (uchar)r;
}
}
}
cvShowImage( wndname, dist8u );
}
int main( int argc, char** argv )
{
char* filename = argc == 2 ? argv[1] : (char*)"stuff.jpg";
if( (gray = cvLoadImage( filename, 0 )) == 0 )
return -1;
printf( "Hot keys: \n"
"\tESC - quit the program\n"
"\tC - use C/Inf metric\n"
"\tL1 - use L1 metric\n"
"\tL2 - use L2 metric\n"
"\t3 - use 3x3 mask\n"
"\t5 - use 5x5 mask\n"
"\t0 - use precise distance transform\n"
"\tv - switch Voronoi diagram mode on/off\n"
"\tSPACE - loop through all the modes\n" );
dist = cvCreateImage( cvGetSize(gray), IPL_DEPTH_32F, 1 );
dist8u1 = cvCloneImage( gray );
dist8u2 = cvCloneImage( gray );
dist8u = cvCreateImage( cvGetSize(gray), IPL_DEPTH_8U, 3 );
dist32s = cvCreateImage( cvGetSize(gray), IPL_DEPTH_32S, 1 );
edge = cvCloneImage( gray );
labels = cvCreateImage( cvGetSize(gray), IPL_DEPTH_32S, 1 );
cvNamedWindow( wndname, 1 );
cvCreateTrackbar( tbarname, wndname, &edge_thresh, 255, on_trackbar );
for(;;)
{
int c;
// Call to update the view
on_trackbar(0);
c = cvWaitKey(0);
if( (char)c == 27 )
break;
if( (char)c == 'c' || (char)c == 'C' )
dist_type = CV_DIST_C;
else if( (char)c == '1' )
dist_type = CV_DIST_L1;
else if( (char)c == '2' )
dist_type = CV_DIST_L2;
else if( (char)c == '3' )
mask_size = CV_DIST_MASK_3;
else if( (char)c == '5' )
mask_size = CV_DIST_MASK_5;
else if( (char)c == '0' )
mask_size = CV_DIST_MASK_PRECISE;
else if( (char)c == 'v' )
build_voronoi ^= 1;
else if( (char)c == ' ' )
{
if( build_voronoi )
{
build_voronoi = 0;
mask_size = CV_DIST_MASK_3;
dist_type = CV_DIST_C;
}
else if( dist_type == CV_DIST_C )
dist_type = CV_DIST_L1;
else if( dist_type == CV_DIST_L1 )
dist_type = CV_DIST_L2;
else if( mask_size == CV_DIST_MASK_3 )
mask_size = CV_DIST_MASK_5;
else if( mask_size == CV_DIST_MASK_5 )
mask_size = CV_DIST_MASK_PRECISE;
else if( mask_size == CV_DIST_MASK_PRECISE )
build_voronoi = 1;
}
}
cvReleaseImage( &gray );
cvReleaseImage( &edge );
cvReleaseImage( &dist );
cvReleaseImage( &dist8u );
cvReleaseImage( &dist8u1 );
cvReleaseImage( &dist8u2 );
cvReleaseImage( &dist32s );
cvReleaseImage( &labels );
cvDestroyWindow( wndname );
return 0;
}

View File

@ -1,177 +0,0 @@
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#define NUMBER 100
#define DELAY 5
char wndname[] = "Drawing Demo";
CvScalar random_color(CvRNG* rng)
{
int icolor = cvRandInt(rng);
return CV_RGB(icolor&255, (icolor>>8)&255, (icolor>>16)&255);
}
int main( int argc, char** argv )
{
int line_type = CV_AA; // change it to 8 to see non-antialiased graphics
int i;
CvPoint pt1,pt2;
double angle;
CvSize sz;
CvPoint ptt[6];
CvPoint* pt[2];
int arr[2];
CvFont font;
CvRNG rng;
int width = 1000, height = 700;
int width3 = width*3, height3 = height*3;
CvSize text_size;
int ymin = 0;
// Load the source image
IplImage* image = cvCreateImage( cvSize(width,height), 8, 3 );
IplImage* image2;
// Create a window
cvNamedWindow(wndname, 1 );
cvZero( image );
cvShowImage(wndname,image);
cvWaitKey(DELAY);
rng = cvRNG((unsigned)-1);
pt[0] = &(ptt[0]);
pt[1] = &(ptt[3]);
arr[0] = 3;
arr[1] = 3;
for (i = 0; i< NUMBER; i++)
{
pt1.x=cvRandInt(&rng) % width3 - width;
pt1.y=cvRandInt(&rng) % height3 - height;
pt2.x=cvRandInt(&rng) % width3 - width;
pt2.y=cvRandInt(&rng) % height3 - height;
cvLine( image, pt1, pt2, random_color(&rng), cvRandInt(&rng)%10, line_type, 0 );
cvShowImage(wndname,image);
if(cvWaitKey(DELAY) >= 0) return 0;
}
for (i = 0; i< NUMBER; i++)
{
pt1.x=cvRandInt(&rng) % width3 - width;
pt1.y=cvRandInt(&rng) % height3 - height;
pt2.x=cvRandInt(&rng) % width3 - width;
pt2.y=cvRandInt(&rng) % height3 - height;
cvRectangle( image,pt1, pt2, random_color(&rng), cvRandInt(&rng)%10-1, line_type, 0 );
cvShowImage(wndname,image);
if(cvWaitKey(DELAY) >= 0) return 0;
}
for (i = 0; i< NUMBER; i++)
{
pt1.x=cvRandInt(&rng) % width3 - width;
pt1.y=cvRandInt(&rng) % height3 - height;
sz.width =cvRandInt(&rng)%200;
sz.height=cvRandInt(&rng)%200;
angle = (cvRandInt(&rng)%1000)*0.180;
cvEllipse( image, pt1, sz, angle, angle - 100, angle + 200,
random_color(&rng), cvRandInt(&rng)%10-1, line_type, 0 );
cvShowImage(wndname,image);
if(cvWaitKey(DELAY) >= 0) return 0;
}
for (i = 0; i< NUMBER; i++)
{
pt[0][0].x=cvRandInt(&rng) % width3 - width;
pt[0][0].y=cvRandInt(&rng) % height3 - height;
pt[0][1].x=cvRandInt(&rng) % width3 - width;
pt[0][1].y=cvRandInt(&rng) % height3 - height;
pt[0][2].x=cvRandInt(&rng) % width3 - width;
pt[0][2].y=cvRandInt(&rng) % height3 - height;
pt[1][0].x=cvRandInt(&rng) % width3 - width;
pt[1][0].y=cvRandInt(&rng) % height3 - height;
pt[1][1].x=cvRandInt(&rng) % width3 - width;
pt[1][1].y=cvRandInt(&rng) % height3 - height;
pt[1][2].x=cvRandInt(&rng) % width3 - width;
pt[1][2].y=cvRandInt(&rng) % height3 - height;
cvPolyLine( image, pt, arr, 2, 1, random_color(&rng), cvRandInt(&rng)%10, line_type, 0 );
cvShowImage(wndname,image);
if(cvWaitKey(DELAY) >= 0) return 0;
}
for (i = 0; i< NUMBER; i++)
{
pt[0][0].x=cvRandInt(&rng) % width3 - width;
pt[0][0].y=cvRandInt(&rng) % height3 - height;
pt[0][1].x=cvRandInt(&rng) % width3 - width;
pt[0][1].y=cvRandInt(&rng) % height3 - height;
pt[0][2].x=cvRandInt(&rng) % width3 - width;
pt[0][2].y=cvRandInt(&rng) % height3 - height;
pt[1][0].x=cvRandInt(&rng) % width3 - width;
pt[1][0].y=cvRandInt(&rng) % height3 - height;
pt[1][1].x=cvRandInt(&rng) % width3 - width;
pt[1][1].y=cvRandInt(&rng) % height3 - height;
pt[1][2].x=cvRandInt(&rng) % width3 - width;
pt[1][2].y=cvRandInt(&rng) % height3 - height;
cvFillPoly( image, pt, arr, 2, random_color(&rng), line_type, 0 );
cvShowImage(wndname,image);
if(cvWaitKey(DELAY) >= 0) return 0;
}
for (i = 0; i< NUMBER; i++)
{
pt1.x=cvRandInt(&rng) % width3 - width;
pt1.y=cvRandInt(&rng) % height3 - height;
cvCircle( image, pt1, cvRandInt(&rng)%300, random_color(&rng),
cvRandInt(&rng)%10-1, line_type, 0 );
cvShowImage(wndname,image);
if(cvWaitKey(DELAY) >= 0) return 0;
}
for (i = 1; i< NUMBER; i++)
{
pt1.x=cvRandInt(&rng) % width3 - width;
pt1.y=cvRandInt(&rng) % height3 - height;
cvInitFont( &font, cvRandInt(&rng) % 8,
(cvRandInt(&rng)%100)*0.05+0.1, (cvRandInt(&rng)%100)*0.05+0.1,
(cvRandInt(&rng)%5)*0.1, cvRound(cvRandInt(&rng)%10), line_type );
cvPutText( image, "Testing text rendering!", pt1, &font, random_color(&rng));
cvShowImage(wndname,image);
if(cvWaitKey(DELAY) >= 0) return 0;
}
cvInitFont( &font, CV_FONT_HERSHEY_COMPLEX, 3, 3, 0.0, 5, line_type );
cvGetTextSize( "OpenCV forever!", &font, &text_size, &ymin );
pt1.x = (width - text_size.width)/2;
pt1.y = (height + text_size.height)/2;
image2 = cvCloneImage(image);
for( i = 0; i < 255; i++ )
{
cvSubS( image2, cvScalarAll(i), image, 0 );
cvPutText( image, "OpenCV forever!", pt1, &font, CV_RGB(255,i,i));
cvShowImage(wndname,image);
if(cvWaitKey(DELAY) >= 0) return 0;
}
// Wait for a key stroke; the same function arranges events processing
cvWaitKey(0);
cvReleaseImage(&image);
cvReleaseImage(&image2);
cvDestroyWindow(wndname);
return 0;
}
#ifdef _EiC
main(1,"drawing.c");
#endif

View File

@ -1,62 +0,0 @@
#include <opencv2/imgproc/imgproc_c.h>
#include <opencv2/highgui/highgui.hpp>
char wndname[] = "Edge";
char tbarname[] = "Threshold";
int edge_thresh = 1;
IplImage *image = 0, *cedge = 0, *gray = 0, *edge = 0;
// define a trackbar callback
void on_trackbar(int h)
{
cvSmooth( gray, edge, CV_BLUR, 3, 3, 0, 0 );
cvNot( gray, edge );
// Run the edge detector on grayscale
cvCanny(gray, edge, (float)edge_thresh, (float)edge_thresh*3, 3);
cvZero( cedge );
// copy edge points
cvCopy( image, cedge, edge );
cvShowImage(wndname, cedge);
}
int main( int argc, char** argv )
{
char* filename = argc == 2 ? argv[1] : (char*)"fruits.jpg";
if( (image = cvLoadImage( filename, 1)) == 0 )
return -1;
// Create the output image
cedge = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 3);
// Convert to grayscale
gray = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 1);
edge = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 1);
cvCvtColor(image, gray, CV_BGR2GRAY);
// Create a window
cvNamedWindow(wndname, 1);
// create a toolbar
cvCreateTrackbar(tbarname, wndname, &edge_thresh, 100, on_trackbar);
// Show the image
on_trackbar(0);
// Wait for a key stroke; the same function arranges events processing
cvWaitKey(0);
cvReleaseImage(&image);
cvReleaseImage(&gray);
cvReleaseImage(&edge);
cvDestroyWindow(wndname);
return 0;
}
#ifdef _EiC
main(1,"edge.c");
#endif

View File

@ -1,177 +0,0 @@
#include <opencv2/imgproc/imgproc_c.h>
#include <opencv2/highgui/highgui.hpp>
IplImage* color_img0;
IplImage* mask;
IplImage* color_img;
IplImage* gray_img0 = NULL;
IplImage* gray_img = NULL;
int ffill_case = 1;
int lo_diff = 20, up_diff = 20;
int connectivity = 4;
int is_color = 1;
int is_mask = 0;
int new_mask_val = 255;
void on_mouse( int event, int x, int y, int flags, void* param )
{
if( !color_img )
return;
switch( event )
{
case CV_EVENT_LBUTTONDOWN:
{
CvPoint seed = cvPoint(x,y);
int lo = ffill_case == 0 ? 0 : lo_diff;
int up = ffill_case == 0 ? 0 : up_diff;
int flags = connectivity + (new_mask_val << 8) +
(ffill_case == 1 ? CV_FLOODFILL_FIXED_RANGE : 0);
int b = rand() & 255, g = rand() & 255, r = rand() & 255;
CvConnectedComp comp;
if( is_mask )
cvThreshold( mask, mask, 1, 128, CV_THRESH_BINARY );
if( is_color )
{
CvScalar color = CV_RGB( r, g, b );
cvFloodFill( color_img, seed, color, CV_RGB( lo, lo, lo ),
CV_RGB( up, up, up ), &comp, flags, is_mask ? mask : NULL );
cvShowImage( "image", color_img );
}
else
{
CvScalar brightness = cvRealScalar((r*2 + g*7 + b + 5)/10);
cvFloodFill( gray_img, seed, brightness, cvRealScalar(lo),
cvRealScalar(up), &comp, flags, is_mask ? mask : NULL );
cvShowImage( "image", gray_img );
}
printf("%g pixels were repainted\n", comp.area );
if( is_mask )
cvShowImage( "mask", mask );
}
break;
}
}
int main( int argc, char** argv )
{
char* filename = argc >= 2 ? argv[1] : (char*)"fruits.jpg";
if( (color_img0 = cvLoadImage(filename,1)) == 0 )
return 0;
printf( "Hot keys: \n"
"\tESC - quit the program\n"
"\tc - switch color/grayscale mode\n"
"\tm - switch mask mode\n"
"\tr - restore the original image\n"
"\ts - use null-range floodfill\n"
"\tf - use gradient floodfill with fixed(absolute) range\n"
"\tg - use gradient floodfill with floating(relative) range\n"
"\t4 - use 4-connectivity mode\n"
"\t8 - use 8-connectivity mode\n" );
color_img = cvCloneImage( color_img0 );
gray_img0 = cvCreateImage( cvSize(color_img->width, color_img->height), 8, 1 );
cvCvtColor( color_img, gray_img0, CV_BGR2GRAY );
gray_img = cvCloneImage( gray_img0 );
mask = cvCreateImage( cvSize(color_img->width + 2, color_img->height + 2), 8, 1 );
cvNamedWindow( "image", 0 );
cvCreateTrackbar( "lo_diff", "image", &lo_diff, 255, NULL );
cvCreateTrackbar( "up_diff", "image", &up_diff, 255, NULL );
cvSetMouseCallback( "image", on_mouse, 0 );
for(;;)
{
int c;
if( is_color )
cvShowImage( "image", color_img );
else
cvShowImage( "image", gray_img );
c = cvWaitKey(0);
switch( (char) c )
{
case '\x1b':
printf("Exiting ...\n");
goto exit_main;
case 'c':
if( is_color )
{
printf("Grayscale mode is set\n");
cvCvtColor( color_img, gray_img, CV_BGR2GRAY );
is_color = 0;
}
else
{
printf("Color mode is set\n");
cvCopy( color_img0, color_img, NULL );
cvZero( mask );
is_color = 1;
}
break;
case 'm':
if( is_mask )
{
cvDestroyWindow( "mask" );
is_mask = 0;
}
else
{
cvNamedWindow( "mask", 0 );
cvZero( mask );
cvShowImage( "mask", mask );
is_mask = 1;
}
break;
case 'r':
printf("Original image is restored\n");
cvCopy( color_img0, color_img, NULL );
cvCopy( gray_img0, gray_img, NULL );
cvZero( mask );
break;
case 's':
printf("Simple floodfill mode is set\n");
ffill_case = 0;
break;
case 'f':
printf("Fixed Range floodfill mode is set\n");
ffill_case = 1;
break;
case 'g':
printf("Gradient (floating range) floodfill mode is set\n");
ffill_case = 2;
break;
case '4':
printf("4-connectivity mode is set\n");
connectivity = 4;
break;
case '8':
printf("8-connectivity mode is set\n");
connectivity = 8;
break;
}
}
exit_main:
cvDestroyWindow( "test" );
cvReleaseImage( &gray_img );
cvReleaseImage( &gray_img0 );
cvReleaseImage( &color_img );
cvReleaseImage( &color_img0 );
cvReleaseImage( &mask );
return 1;
}
#ifdef _EiC
main(1,"ffilldemo.c");
#endif

View File

@ -14,113 +14,70 @@
*
*
********************************************************************************/
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
int slider_pos = 70;
#include <iostream>
// Load the source image. HighGUI use.
IplImage *image02 = 0, *image03 = 0, *image04 = 0;
using namespace cv;
using namespace std;
void process_image(int h);
int sliderPos = 70;
Mat image;
void processImage(int, void*);
int main( int argc, char** argv )
{
const char* filename = argc == 2 ? argv[1] : (char*)"stuff.jpg";
image = imread(filename, 0);
if( image.empty() )
{
cout << "Usage: fitellipse <image_name>\n";
return 0;
}
// load image and force it to be grayscale
if( (image03 = cvLoadImage(filename, 0)) == 0 )
return -1;
// Create the destination images
image02 = cvCloneImage( image03 );
image04 = cvCloneImage( image03 );
// Create windows.
cvNamedWindow("Source", 1);
cvNamedWindow("Result", 1);
// Show the image.
cvShowImage("Source", image03);
imshow("source", image);
namedWindow("result", 1);
// Create toolbars. HighGUI use.
cvCreateTrackbar( "Threshold", "Result", &slider_pos, 255, process_image );
process_image(0);
createTrackbar( "threshold", "result", &sliderPos, 255, processImage );
processImage(0, 0);
// Wait for a key stroke; the same function arranges events processing
cvWaitKey(0);
cvReleaseImage(&image02);
cvReleaseImage(&image03);
cvDestroyWindow("Source");
cvDestroyWindow("Result");
waitKey();
return 0;
}
// Define trackbar callback functon. This function find contours,
// draw it and approximate it by ellipses.
void process_image(int h)
void processImage(int h, void*)
{
CvMemStorage* storage;
CvSeq* contour;
vector<vector<Point> > contours;
Mat bimage = image >= sliderPos;
findContours(bimage, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
// Create dynamic structure and sequence.
storage = cvCreateMemStorage(0);
contour = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , storage);
Mat cimage = Mat::zeros(bimage.size(), CV_8UC3);
// Threshold the source image. This needful for cvFindContours().
cvThreshold( image03, image02, slider_pos, 255, CV_THRESH_BINARY );
// Find all contours.
cvFindContours( image02, storage, &contour, sizeof(CvContour),
CV_RETR_LIST, CV_CHAIN_APPROX_NONE, cvPoint(0,0));
// Clear images. IPL use.
cvZero(image02);
cvZero(image04);
// This cycle draw all contours and approximate it by ellipses.
for(;contour;contour = contour->h_next)
for(size_t i = 0; i < contours.size(); i++)
{
int count = contour->total; // This is number point in contour
CvPoint center;
CvSize size;
CvBox2D box;
// Number point must be more than or equal to 6 (for cvFitEllipse_32f).
size_t count = contours[i].size();
if( count < 6 )
continue;
Mat pointsf;
Mat(contours[i]).convertTo(pointsf, CV_32F);
RotatedRect box = fitEllipse(pointsf);
box.angle = -box.angle;
if( MAX(box.size.width, box.size.height) > MIN(box.size.width, box.size.height)*30 )
continue;
drawContours(cimage, contours, (int)i, Scalar::all(255), 1, 8);
CvMat* points_f = cvCreateMat( 1, count, CV_32FC2 );
CvMat points_i = cvMat( 1, count, CV_32SC2, points_f->data.ptr );
cvCvtSeqToArray( contour, points_f->data.ptr, CV_WHOLE_SEQ );
cvConvert( &points_i, points_f );
// Fits ellipse to current contour.
box = cvFitEllipse2( points_f );
// Draw current contour.
cvDrawContours(image04,contour,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 = cvPointFrom32f(box.center);
size.width = cvRound(box.size.width*0.5);
size.height = cvRound(box.size.height*0.5);
// Draw ellipse.
cvEllipse(image04, center, size,
-box.angle, 0, 360,
CV_RGB(0,0,255), 1, CV_AA, 0);
cvReleaseMat(&points_f);
ellipse(cimage, box, Scalar(0,0,255), 1, CV_AA);
}
// Show image. HighGUI use.
cvShowImage( "Result", image04 );
imshow("result", cimage);
}
#ifdef _EiC
main(1,"fitellipse.c");
#endif

23
samples/c/intrinsics.yml Normal file
View File

@ -0,0 +1,23 @@
%YAML:1.0
M1: !!opencv-matrix
rows: 3
cols: 3
dt: d
data: [ 5.3480326845051309e+02, 0., 3.3568643204394891e+02, 0.,
5.3480326845051309e+02, 2.4066183054066337e+02, 0., 0., 1. ]
D1: !!opencv-matrix
rows: 1
cols: 5
dt: d
data: [ 2.9589439552724328e-01, -1.0354662043042675e+00, 0., 0., 0. ]
M2: !!opencv-matrix
rows: 3
cols: 3
dt: d
data: [ 5.3480326845051309e+02, 0., 3.3455744527912015e+02, 0.,
5.3480326845051309e+02, 2.4205324573376600e+02, 0., 0., 1. ]
D2: !!opencv-matrix
rows: 1
cols: 5
dt: d
data: [ -1.6916358306948096e-01, -1.1214173641213163e-01, 0., 0., 0. ]

View File

@ -1,84 +0,0 @@
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
int main( int argc, char** argv )
{
#define MAX_CLUSTERS 5
CvScalar color_tab[MAX_CLUSTERS];
IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );
CvRNG rng = cvRNG(-1);
CvPoint ipt;
color_tab[0] = CV_RGB(255,0,0);
color_tab[1] = CV_RGB(0,255,0);
color_tab[2] = CV_RGB(100,100,255);
color_tab[3] = CV_RGB(255,0,255);
color_tab[4] = CV_RGB(255,255,0);
cvNamedWindow( "clusters", 1 );
for(;;)
{
char key;
int k, cluster_count = cvRandInt(&rng)%MAX_CLUSTERS + 1;
int i, sample_count = cvRandInt(&rng)%1000 + 1;
CvMat* points = cvCreateMat( sample_count, 1, CV_32FC2 );
CvMat* clusters = cvCreateMat( sample_count, 1, CV_32SC1 );
cluster_count = MIN(cluster_count, sample_count);
/* generate random sample from multigaussian distribution */
for( k = 0; k < cluster_count; k++ )
{
CvPoint center;
CvMat point_chunk;
center.x = cvRandInt(&rng)%img->width;
center.y = cvRandInt(&rng)%img->height;
cvGetRows( points, &point_chunk, k*sample_count/cluster_count,
k == cluster_count - 1 ? sample_count :
(k+1)*sample_count/cluster_count, 1 );
cvRandArr( &rng, &point_chunk, CV_RAND_NORMAL,
cvScalar(center.x,center.y,0,0),
cvScalar(img->width*0.1,img->height*0.1,0,0));
}
/* shuffle samples */
for( i = 0; i < sample_count/2; i++ )
{
CvPoint2D32f* pt1 = (CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count;
CvPoint2D32f* pt2 = (CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count;
CvPoint2D32f temp;
CV_SWAP( *pt1, *pt2, temp );
}
printf( "iterations=%d\n", cvKMeans2( points, cluster_count, clusters,
cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0 ),
5, 0, 0, 0, 0 ));
cvZero( img );
for( i = 0; i < sample_count; i++ )
{
int cluster_idx = clusters->data.i[i];
ipt.x = (int)points->data.fl[i*2];
ipt.y = (int)points->data.fl[i*2+1];
cvCircle( img, ipt, 2, color_tab[cluster_idx], CV_FILLED, CV_AA, 0 );
}
cvReleaseMat( &points );
cvReleaseMat( &clusters );
cvShowImage( "clusters", img );
key = (char) cvWaitKey(0);
if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC'
break;
}
cvDestroyWindow( "clusters" );
return 0;
}
#ifdef _EiC
main(1,"kmeans.c");
#endif

View File

@ -1,76 +0,0 @@
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <ctype.h>
#include <stdio.h>
int sigma = 3;
int smoothType = CV_GAUSSIAN;
int main( int argc, char** argv )
{
IplImage* laplace = 0;
IplImage* colorlaplace = 0;
IplImage* planes[3] = { 0, 0, 0 };
CvCapture* capture = 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;
}
cvNamedWindow( "Laplacian", 0 );
cvCreateTrackbar( "Sigma", "Laplacian", &sigma, 15, 0 );
for(;;)
{
IplImage* frame = 0;
int i, c, ksize;
frame = cvQueryFrame( capture );
if( !frame )
break;
if( !laplace )
{
for( i = 0; i < 3; i++ )
planes[i] = cvCreateImage( cvGetSize(frame), 8, 1 );
laplace = cvCreateImage( cvGetSize(frame), IPL_DEPTH_16S, 1 );
colorlaplace = cvCreateImage( cvGetSize(frame), 8, 3 );
}
ksize = (sigma*5)|1;
cvSmooth( frame, colorlaplace, smoothType, ksize, ksize, sigma, sigma );
cvSplit( colorlaplace, planes[0], planes[1], planes[2], 0 );
for( i = 0; i < 3; i++ )
{
cvLaplace( planes[i], laplace, 5 );
cvConvertScaleAbs( laplace, planes[i], (sigma+1)*0.25, 0 );
}
cvMerge( planes[0], planes[1], planes[2], 0, colorlaplace );
colorlaplace->origin = frame->origin;
cvShowImage("Laplacian", colorlaplace );
c = cvWaitKey(30);
if( c == ' ' )
smoothType = smoothType == CV_GAUSSIAN ? CV_BLUR : smoothType == CV_BLUR ? CV_MEDIAN : CV_GAUSSIAN;
if( c == 'q' || c == 'Q' || (c & 255) == 27 )
break;
}
cvReleaseCapture( &capture );
cvDestroyWindow("Laplacian");
return 0;
}
#ifdef _EiC
main(1,"laplace.c");
#endif

View File

@ -1,100 +0,0 @@
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#define ARRAY 1
int main( int argc, char** argv )
{
IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );
#if !ARRAY
CvMemStorage* storage = cvCreateMemStorage(0);
#endif
cvNamedWindow( "rect & circle", 1 );
for(;;)
{
char key;
int i, count = rand()%100 + 1;
CvPoint pt0, pt;
CvBox2D box;
CvPoint2D32f box_vtx[4];
CvPoint2D32f center;
CvPoint icenter;
float radius;
#if !ARRAY
CvSeq* ptseq = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvContour),
sizeof(CvPoint), storage );
for( i = 0; i < count; i++ )
{
pt0.x = rand() % (img->width/2) + img->width/4;
pt0.y = rand() % (img->height/2) + img->height/4;
cvSeqPush( ptseq, &pt0 );
}
#ifndef _EiC /* unfortunately, here EiC crashes */
box = cvMinAreaRect2( ptseq, 0 );
#endif
cvMinEnclosingCircle( ptseq, &center, &radius );
#else
CvPoint* points = (CvPoint*)malloc( count * sizeof(points[0]));
CvMat pointMat = cvMat( 1, count, CV_32SC2, points );
for( i = 0; i < count; i++ )
{
pt0.x = rand() % (img->width/2) + img->width/4;
pt0.y = rand() % (img->height/2) + img->height/4;
points[i] = pt0;
}
#ifndef _EiC
box = cvMinAreaRect2( &pointMat, 0 );
#endif
cvMinEnclosingCircle( &pointMat, &center, &radius );
#endif
cvBoxPoints( box, box_vtx );
cvZero( img );
for( i = 0; i < count; i++ )
{
#if !ARRAY
pt0 = *CV_GET_SEQ_ELEM( CvPoint, ptseq, i );
#else
pt0 = points[i];
#endif
cvCircle( img, pt0, 2, CV_RGB( 255, 0, 0 ), CV_FILLED, CV_AA, 0 );
}
#ifndef _EiC
pt0.x = cvRound(box_vtx[3].x);
pt0.y = cvRound(box_vtx[3].y);
for( i = 0; i < 4; i++ )
{
pt.x = cvRound(box_vtx[i].x);
pt.y = cvRound(box_vtx[i].y);
cvLine(img, pt0, pt, CV_RGB(0, 255, 0), 1, CV_AA, 0);
pt0 = pt;
}
#endif
icenter.x = cvRound(center.x);
icenter.y = cvRound(center.y);
cvCircle( img, icenter, cvRound(radius), CV_RGB(255, 255, 0), 1, CV_AA, 0 );
cvShowImage( "rect & circle", img );
key = (char) cvWaitKey(0);
if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC'
break;
#if !ARRAY
cvClearMemStorage( storage );
#else
free( points );
#endif
}
cvDestroyWindow( "rect & circle" );
return 0;
}
#ifdef _EiC
main(1,"convexhull.c");
#endif

View File

@ -1,146 +0,0 @@
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/highgui/highgui.hpp"
#include <stdio.h>
#include <stdlib.h>
IplImage* marker_mask = 0;
IplImage* markers = 0;
IplImage* img0 = 0, *img = 0, *img_gray = 0, *wshed = 0;
CvPoint prev_pt = {-1,-1};
void on_mouse( int event, int x, int y, int flags, void* )
{
if( !img )
return;
if( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON) )
prev_pt = cvPoint(-1,-1);
else if( event == CV_EVENT_LBUTTONDOWN )
prev_pt = cvPoint(x,y);
else if( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON) )
{
CvPoint pt = cvPoint(x,y);
if( prev_pt.x < 0 )
prev_pt = pt;
cvLine( marker_mask, prev_pt, pt, cvScalarAll(255), 5, 8, 0 );
cvLine( img, prev_pt, pt, cvScalarAll(255), 5, 8, 0 );
prev_pt = pt;
cvShowImage( "image", img );
}
}
int main( int argc, char** argv )
{
char* filename = argc >= 2 ? argv[1] : (char*)"fruits.jpg";
CvMemStorage* storage = cvCreateMemStorage(0);
CvRNG rng = cvRNG(-1);
if( (img0 = cvLoadImage(filename,1)) == 0 )
return 0;
printf( "Hot keys: \n"
"\tESC - quit the program\n"
"\tr - restore the original image\n"
"\tw or SPACE - run watershed algorithm\n"
"\t\t(before running it, roughly mark the areas on the image)\n"
"\t (before that, roughly outline several markers on the image)\n" );
cvNamedWindow( "image", 1 );
cvNamedWindow( "watershed transform", 1 );
img = cvCloneImage( img0 );
img_gray = cvCloneImage( img0 );
wshed = cvCloneImage( img0 );
marker_mask = cvCreateImage( cvGetSize(img), 8, 1 );
markers = cvCreateImage( cvGetSize(img), IPL_DEPTH_32S, 1 );
cvCvtColor( img, marker_mask, CV_BGR2GRAY );
cvCvtColor( marker_mask, img_gray, CV_GRAY2BGR );
cvZero( marker_mask );
cvZero( wshed );
cvShowImage( "image", img );
cvShowImage( "watershed transform", wshed );
cvSetMouseCallback( "image", on_mouse, 0 );
for(;;)
{
int c = cvWaitKey(0);
if( (char)c == 27 )
break;
if( (char)c == 'r' )
{
cvZero( marker_mask );
cvCopy( img0, img );
cvShowImage( "image", img );
}
if( (char)c == 'w' || (char)c == ' ' )
{
CvSeq* contours = 0;
CvMat* color_tab = 0;
int i, j, comp_count = 0;
cvClearMemStorage(storage);
//cvSaveImage( "wshed_mask.png", marker_mask );
//marker_mask = cvLoadImage( "wshed_mask.png", 0 );
cvFindContours( marker_mask, storage, &contours, sizeof(CvContour),
CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
cvZero( markers );
for( ; contours != 0; contours = contours->h_next, comp_count++ )
{
cvDrawContours( markers, contours, cvScalarAll(comp_count+1),
cvScalarAll(comp_count+1), -1, -1, 8, cvPoint(0,0) );
}
if( comp_count == 0 )
continue;
color_tab = cvCreateMat( 1, comp_count, CV_8UC3 );
for( i = 0; i < comp_count; i++ )
{
uchar* ptr = color_tab->data.ptr + i*3;
ptr[0] = (uchar)(cvRandInt(&rng)%180 + 50);
ptr[1] = (uchar)(cvRandInt(&rng)%180 + 50);
ptr[2] = (uchar)(cvRandInt(&rng)%180 + 50);
}
{
double t = (double)cvGetTickCount();
cvWatershed( img0, markers );
t = (double)cvGetTickCount() - t;
printf( "exec time = %gms\n", t/(cvGetTickFrequency()*1000.) );
}
// paint the watershed image
for( i = 0; i < markers->height; i++ )
for( j = 0; j < markers->width; j++ )
{
int idx = CV_IMAGE_ELEM( markers, int, i, j );
uchar* dst = &CV_IMAGE_ELEM( wshed, uchar, i, j*3 );
if( idx == -1 )
dst[0] = dst[1] = dst[2] = (uchar)255;
else if( idx <= 0 || idx > comp_count )
dst[0] = dst[1] = dst[2] = (uchar)0; // should not get here
else
{
uchar* ptr = color_tab->data.ptr + (idx-1)*3;
dst[0] = ptr[0]; dst[1] = ptr[1]; dst[2] = ptr[2];
}
}
cvAddWeighted( wshed, 0.5, img_gray, 0.5, 0, wshed );
cvShowImage( "watershed transform", wshed );
cvReleaseMat( &color_tab );
}
}
return 1;
}
#ifdef _EiC
main(1,"watershed.cpp");
#endif

View File

@ -1,7 +1,7 @@
#include <opencv2/video/tracking.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <stdio.h>
#include <iostream>
#include <ctype.h>
IplImage *image = 0, *hsv = 0, *hue = 0, *mask = 0, *backproject = 0, *histimg = 0;
@ -21,25 +21,19 @@ 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 )
void onMouse( int event, int x, int y, int flags, void* param )
{
if( !image )
return;
if( image->origin )
y = image->height - y;
if( select_object )
if( selectObject )
{
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 = MIN(x, origin.x);
selection.y = MIN(y, origin.y);
selection.width = selection.x + std::abs(x - origin.x);
selection.height = selection.y + std::abs(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.x = MAX(selection.x, 0);
selection.y = MAX(selection.y, 0);
selection.width = MIN(selection.width, image.cols);
selection.height = MIN(selection.height, image.rows);
selection.width -= selection.x;
selection.height -= selection.y;
}
@ -47,23 +41,23 @@ void on_mouse( int event, int x, int y, int flags, void* param )
switch( event )
{
case CV_EVENT_LBUTTONDOWN:
origin = cvPoint(x,y);
selection = cvRect(x,y,0,0);
select_object = 1;
origin = Point(x,y);
selection = Rect(x,y,0,0);
selectObject = true;
break;
case CV_EVENT_LBUTTONUP:
select_object = 0;
selectObject = false;
if( selection.width > 0 && selection.height > 0 )
track_object = -1;
trackObject = -1;
break;
}
}
CvScalar hsv2rgb( float hue )
Scalar hsv2rgb( float hue )
{
int rgb[3], p, sector;
static const int sector_data[][3]=
static const int sectorData[][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);
@ -218,7 +212,3 @@ int main( int argc, char** argv )
return 0;
}
#ifdef _EiC
main(1,"camshiftdemo.c");
#endif

View File

@ -0,0 +1,52 @@
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main( int argc, char** argv )
{
Mat img(500, 500, CV_8UC3);
RNG& rng = theRNG();
for(;;)
{
char key;
int i, count = (unsigned)rng%100 + 1;
vector<Point> points;
for( i = 0; i < count; i++ )
{
Point pt;
pt.x = rng.uniform(img.cols/4, img.cols*3/4);
pt.y = rng.uniform(img.rows/4, img.rows*3/4);
points.push_back(pt);
}
vector<int> hull;
convexHull(Mat(points), hull, CV_CLOCKWISE);
img = Scalar::all(0);
for( i = 0; i < count; i++ )
circle(img, points[i], 3, Scalar(0, 0, 255), CV_FILLED, CV_AA);
int hullcount = (int)hull.size();
Point pt0 = points[hull[hullcount-1]];
for( i = 0; i < hullcount; i++ )
{
Point pt = points[hull[i]];
line(img, pt0, pt, Scalar(0, 255, 0), 1, CV_AA);
pt0 = pt;
}
imshow("hull", img);
key = (char)waitKey();
if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC'
break;
}
return 0;
}

80
samples/cpp/demhist.cpp Normal file
View File

@ -0,0 +1,80 @@
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int _brightness = 100;
int _contrast = 100;
Mat image;
/* brightness/contrast callback function */
void updateBrightnessContrast( int arg, void* )
{
int histSize = 64;
int brightness = _brightness - 100;
int contrast = _contrast - 100;
/*
* The algorithm is by Werner D. Streidt
* (http://visca.com/ffactory/archives/5-99/msg00021.html)
*/
double a, b;
if( contrast > 0 )
{
double delta = 127.*contrast/100;
a = 255./(255. - delta*2);
b = a*(brightness - delta);
}
else
{
double delta = -128.*contrast/100;
a = (256.-delta*2)/255.;
b = a*brightness + delta;
}
Mat dst, hist;
image.convertTo(dst, CV_8U, a, b);
imshow("image", dst);
calcHist(&dst, 1, 0, Mat(), hist, 1, &histSize, 0);
Mat histImage = Mat::ones(200, 320, CV_8U)*255;
normalize(hist, hist, 0, histImage.rows, CV_MINMAX, CV_32F);
histImage = Scalar::all(255);
int binW = cvRound((double)histImage.cols/histSize);
for( int i = 0; i < histSize; i++ )
rectangle( histImage, Point(i*binW, histImage.rows),
Point((i+1)*binW, histImage.rows - cvRound(hist.at<float>(i))),
Scalar::all(0), -1, 8, 0 );
imshow("histogram", histImage);
}
int main( int argc, char** argv )
{
// Load the source image. HighGUI use.
image = imread( argc == 2 ? argv[1] : "baboon.jpg", 0 );
if( image.empty() )
{
cout << "Image was not loaded.\n";
return -1;
}
namedWindow("image", 0);
namedWindow("histogram", 0);
createTrackbar("brightness", "image", &_brightness, 200, updateBrightnessContrast);
createTrackbar("contrast", "image", &_contrast, 200, updateBrightnessContrast);
updateBrightnessContrast(0, 0);
waitKey();
return 0;
}

67
samples/cpp/dft.cpp Normal file
View File

@ -0,0 +1,67 @@
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char ** argv)
{
const char* filename = argc >=2 ? argv[1] : "lena.jpg";
Mat img = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);
if( img.empty() )
{
cout << "Usage: dft <image_name>" << endl;
return -1;
}
int M = getOptimalDFTSize( img.rows );
int N = getOptimalDFTSize( img.cols );
Mat padded;
copyMakeBorder(img, padded, 0, M - img.rows, 0, N - img.cols, BORDER_CONSTANT, Scalar::all(0));
Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
Mat complexImg;
merge(planes, 2, complexImg);
dft(complexImg, complexImg);
// compute log(1 + sqrt(Re(DFT(img))**2 + Im(DFT(img))**2))
split(complexImg, planes);
magnitude(planes[0], planes[1], planes[0]);
Mat mag = planes[0];
mag += Scalar::all(1);
log(mag, mag);
// crop the spectrum, if it has an odd number of rows or columns
mag = mag(Rect(0, 0, mag.cols & -2, mag.rows & -2));
int cx = mag.cols/2;
int cy = mag.rows/2;
// rearrange the quadrants of Fourier image
// so that the origin is at the image center
Mat tmp;
Mat q0(mag, Rect(0, 0, cx, cy));
Mat q1(mag, Rect(cx, 0, cx, cy));
Mat q2(mag, Rect(0, cy, cx, cy));
Mat q3(mag, Rect(cx, cy, cx, cy));
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
normalize(mag, mag, 0, 1, CV_MINMAX);
imshow("spectrum magnitude", mag);
waitKey();
return 0;
}

156
samples/cpp/distrans.cpp Normal file
View File

@ -0,0 +1,156 @@
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <stdio.h>
using namespace cv;
int maskSize0 = CV_DIST_MASK_5;
bool buildVoronoi = false;
int edgeThresh = 100;
int distType0 = CV_DIST_L1;
// The output and temporary images
Mat gray;
// threshold trackbar callback
void onTrackbar( int, void* )
{
static const Scalar colors[] =
{
Scalar(0,0,0),
Scalar(255,0,0),
Scalar(255,128,0),
Scalar(255,255,0),
Scalar(0,255,0),
Scalar(0,128,255),
Scalar(0,255,255),
Scalar(0,0,255),
Scalar(255,0,255)
};
int maskSize = buildVoronoi ? CV_DIST_MASK_5 : maskSize0;
int distType = buildVoronoi ? CV_DIST_L2 : distType0;
Mat edge = gray >= edgeThresh, dist, labels, dist8u;
if( !buildVoronoi )
distanceTransform( edge, dist, distType, maskSize );
else
distanceTransform( edge, dist, labels, distType, maskSize );
if( !buildVoronoi )
{
// begin "painting" the distance transform result
dist *= 5000;
pow(dist, 0.5, dist);
Mat dist32s, dist8u1, dist8u2;
dist.convertTo(dist32s, CV_32S, 1, 0.5);
dist32s &= Scalar::all(255);
dist32s.convertTo(dist8u1, CV_8U, 1, 0);
dist32s *= -1;
dist32s += Scalar::all(255);
dist32s.convertTo(dist8u2, CV_8U);
Mat planes[] = {dist8u1, dist8u2, dist8u2};
merge(planes, 3, dist8u);
}
else
{
dist8u.create(labels.size(), CV_8UC3);
for( int i = 0; i < labels.rows; i++ )
{
const int* ll = (const int*)labels.ptr(i);
const float* dd = (const float*)dist.ptr(i);
uchar* d = (uchar*)dist8u.ptr(i);
for( int j = 0; j < labels.cols; j++ )
{
int idx = ll[j] == 0 || dd[j] == 0 ? 0 : (ll[j]-1)%8 + 1;
int b = cvRound(colors[idx][0]);
int g = cvRound(colors[idx][1]);
int r = cvRound(colors[idx][2]);
d[j*3] = (uchar)b;
d[j*3+1] = (uchar)g;
d[j*3+2] = (uchar)r;
}
}
}
imshow("Distance Map", dist8u );
}
int main( int argc, char** argv )
{
char* filename = argc == 2 ? argv[1] : (char*)"stuff.jpg";
gray = imread(filename, 0);
if(gray.empty())
{
printf("Usage: distrans <image_name>\n");
return 0;
}
printf( "Hot keys: \n"
"\tESC - quit the program\n"
"\tC - use C/Inf metric\n"
"\tL1 - use L1 metric\n"
"\tL2 - use L2 metric\n"
"\t3 - use 3x3 mask\n"
"\t5 - use 5x5 mask\n"
"\t0 - use precise distance transform\n"
"\tv - switch Voronoi diagram mode on/off\n"
"\tSPACE - loop through all the modes\n" );
namedWindow("Distance Map", 1);
createTrackbar("Brightness Threshold", "Distance Map", &edgeThresh, 255, onTrackbar, 0);
for(;;)
{
// Call to update the view
onTrackbar(0, 0);
int c = cvWaitKey(0);
if( (char)c == 27 )
break;
if( (char)c == 'c' || (char)c == 'C' )
distType0 = CV_DIST_C;
else if( (char)c == '1' )
distType0 = CV_DIST_L1;
else if( (char)c == '2' )
distType0 = CV_DIST_L2;
else if( (char)c == '3' )
maskSize0 = CV_DIST_MASK_3;
else if( (char)c == '5' )
maskSize0 = CV_DIST_MASK_5;
else if( (char)c == '0' )
maskSize0 = CV_DIST_MASK_PRECISE;
else if( (char)c == 'v' )
buildVoronoi = !buildVoronoi;
else if( (char)c == ' ' )
{
if( buildVoronoi )
{
buildVoronoi = false;
maskSize0 = CV_DIST_MASK_3;
distType0 = CV_DIST_C;
}
else if( distType0 == CV_DIST_C )
distType0 = CV_DIST_L1;
else if( distType0 == CV_DIST_L1 )
distType0 = CV_DIST_L2;
else if( maskSize0 == CV_DIST_MASK_3 )
maskSize0 = CV_DIST_MASK_5;
else if( maskSize0 == CV_DIST_MASK_5 )
maskSize0 = CV_DIST_MASK_PRECISE;
else if( maskSize0 == CV_DIST_MASK_PRECISE )
buildVoronoi = true;
}
}
return 0;
}

174
samples/cpp/drawing.cpp Normal file
View File

@ -0,0 +1,174 @@
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
static Scalar randomColor(RNG& rng)
{
int icolor = (unsigned)rng;
return Scalar(icolor&255, (icolor>>8)&255, (icolor>>16)&255);
}
int main( int argc, char** argv )
{
char wndname[] = "Drawing Demo";
const int NUMBER = 100;
const int DELAY = 5;
int lineType = CV_AA; // change it to 8 to see non-antialiased graphics
int i, width = 1000, height = 700;
int x1 = -width/2, x2 = width*3/2, y1 = -height/2, y2 = height*3/2;
RNG rng(-1);
Mat image = Mat::zeros(height, width, CV_8UC3);
imshow(wndname, image);
waitKey(DELAY);
for (i = 0; i < NUMBER; i++)
{
Point pt1, pt2;
pt1.x = rng.uniform(x1, x2);
pt1.y = rng.uniform(y1, y2);
pt2.x = rng.uniform(x1, x2);
pt2.y = rng.uniform(y1, y2);
line( image, pt1, pt2, randomColor(rng), rng.uniform(1,10), lineType );
imshow(wndname, image);
if(waitKey(DELAY) >= 0)
return 0;
}
for (i = 0; i < NUMBER; i++)
{
Point pt1, pt2;
pt1.x = rng.uniform(x1, x2);
pt1.y = rng.uniform(y1, y2);
pt2.x = rng.uniform(x1, x2);
pt2.y = rng.uniform(y1, y2);
int thickness = rng.uniform(-3, 10);
rectangle( image, pt1, pt2, randomColor(rng), MAX(thickness, -1), lineType );
imshow(wndname, image);
if(waitKey(DELAY) >= 0)
return 0;
}
for (i = 0; i < NUMBER; i++)
{
Point center;
center.x = rng.uniform(x1, x2);
center.y = rng.uniform(y1, y2);
Size axes;
axes.width = rng.uniform(0, 200);
axes.height = rng.uniform(0, 200);
double angle = rng.uniform(0, 180);
ellipse( image, center, axes, angle, angle - 100, angle + 200,
randomColor(rng), rng.uniform(-1,9), lineType );
imshow(wndname, image);
if(waitKey(DELAY) >= 0)
return 0;
}
for (i = 0; i< NUMBER; i++)
{
Point pt[2][3];
pt[0][0].x = rng.uniform(x1, x2);
pt[0][0].y = rng.uniform(y1, y2);
pt[0][1].x = rng.uniform(x1, x2);
pt[0][1].y = rng.uniform(y1, y2);
pt[0][2].x = rng.uniform(x1, x2);
pt[0][2].y = rng.uniform(y1, y2);
pt[1][0].x = rng.uniform(x1, x2);
pt[1][0].y = rng.uniform(y1, y2);
pt[1][1].x = rng.uniform(x1, x2);
pt[1][1].y = rng.uniform(y1, y2);
pt[1][2].x = rng.uniform(x1, x2);
pt[1][2].y = rng.uniform(y1, y2);
const Point* ppt[2] = {pt[0], pt[1]};
int npt[] = {3, 3};
polylines(image, ppt, npt, 2, true, randomColor(rng), rng.uniform(1,10), lineType);
imshow(wndname, image);
if(waitKey(DELAY) >= 0)
return 0;
}
for (i = 0; i< NUMBER; i++)
{
Point pt[2][3];
pt[0][0].x = rng.uniform(x1, x2);
pt[0][0].y = rng.uniform(y1, y2);
pt[0][1].x = rng.uniform(x1, x2);
pt[0][1].y = rng.uniform(y1, y2);
pt[0][2].x = rng.uniform(x1, x2);
pt[0][2].y = rng.uniform(y1, y2);
pt[1][0].x = rng.uniform(x1, x2);
pt[1][0].y = rng.uniform(y1, y2);
pt[1][1].x = rng.uniform(x1, x2);
pt[1][1].y = rng.uniform(y1, y2);
pt[1][2].x = rng.uniform(x1, x2);
pt[1][2].y = rng.uniform(y1, y2);
const Point* ppt[2] = {pt[0], pt[1]};
int npt[] = {3, 3};
fillPoly(image, ppt, npt, 2, randomColor(rng), lineType);
imshow(wndname, image);
if(waitKey(DELAY) >= 0)
return 0;
}
for (i = 0; i < NUMBER; i++)
{
Point center;
center.x = rng.uniform(x1, x2);
center.y = rng.uniform(y1, y2);
circle(image, center, rng.uniform(0, 300), randomColor(rng),
rng.uniform(-1, 9), lineType);
imshow(wndname, image);
if(waitKey(DELAY) >= 0)
return 0;
}
for (i = 1; i < NUMBER; i++)
{
Point org;
org.x = rng.uniform(x1, x2);
org.y = rng.uniform(y1, y2);
putText(image, "Testing text rendering", org, rng.uniform(0,8),
rng.uniform(0,100)*0.05+0.1, randomColor(rng), rng.uniform(1, 10), lineType);
imshow(wndname, image);
if(waitKey(DELAY) >= 0)
return 0;
}
Size textsize = getTextSize("OpenCV forever!", CV_FONT_HERSHEY_COMPLEX, 3, 5, 0);
Point org((width - textsize.width)/2, (height - textsize.height)/2);
Mat image2;
for( i = 0; i < 255; i += 2 )
{
image2 = image - Scalar::all(i);
putText(image2, "OpenCV forever!", org, CV_FONT_HERSHEY_COMPLEX, 3,
Scalar(i, i, 255), 5, lineType);
imshow(wndname, image2);
if(waitKey(DELAY) >= 0)
return 0;
}
waitKey();
return 0;
}
#ifdef _EiC
main(1,"drawing.c");
#endif

52
samples/cpp/edge.cpp Normal file
View File

@ -0,0 +1,52 @@
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int edgeThresh = 1;
Mat image, gray, edge, cedge;
// define a trackbar callback
void onTrackbar(int, void*)
{
blur(gray, edge, Size(3,3));
// Run the edge detector on grayscale
Canny(edge, edge, edgeThresh, edgeThresh*3, 3);
cedge = Scalar::all(0);
image.copyTo(cedge, edge);
imshow("Edge map", cedge);
}
int main( int argc, char** argv )
{
char* filename = argc == 2 ? argv[1] : (char*)"fruits.jpg";
image = imread(filename, 1);
if(image.empty())
{
cout << "Usage: edge <image_name>" << endl;
return -1;
}
cedge.create(image.size(), image.type());
cvtColor(image, gray, CV_BGR2GRAY);
// Create a window
namedWindow("Edge map", 1);
// create a toolbar
createTrackbar("Canny threshold", "Edge map", &edgeThresh, 100, onTrackbar);
// Show the image
onTrackbar(0, 0);
// Wait for a key stroke; the same function arranges events processing
waitKey(0);
return 0;
}

156
samples/cpp/ffilldemo.cpp Normal file
View File

@ -0,0 +1,156 @@
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
Mat image0, image, gray, mask;
int ffillMode = 1;
int loDiff = 20, upDiff = 20;
int connectivity = 4;
int isColor = true;
bool useMask = false;
int newMaskVal = 255;
void onMouse( int event, int x, int y, int, void* param )
{
if( event != CV_EVENT_LBUTTONDOWN )
return;
Point seed = Point(x,y);
int lo = ffillMode == 0 ? 0 : loDiff;
int up = ffillMode == 0 ? 0 : upDiff;
int flags = connectivity + (newMaskVal << 8) +
(ffillMode == 1 ? CV_FLOODFILL_FIXED_RANGE : 0);
int b = (unsigned)theRNG() & 255;
int g = (unsigned)theRNG() & 255;
int r = (unsigned)theRNG() & 255;
Rect ccomp;
Scalar newVal = isColor ? Scalar(b, g, r) : Scalar(r*0.299 + g*0.587 + b*0.114);
Mat dst = isColor ? image : gray;
int area;
if( useMask )
{
threshold(mask, mask, 1, 128, CV_THRESH_BINARY);
area = floodFill(dst, mask, seed, newVal, &ccomp, Scalar(lo, lo, lo),
Scalar(up, up, up), flags);
imshow( "mask", mask );
}
else
{
area = floodFill(dst, seed, newVal, &ccomp, Scalar(lo, lo, lo),
Scalar(up, up, up), flags);
}
imshow("image", dst);
cout << area << " pixels were repainted\n";
}
int main( int argc, char** argv )
{
char* filename = argc >= 2 ? argv[1] : (char*)"fruits.jpg";
image0 = imread(filename, 1);
if( image0.empty() )
{
cout << "Usage: ffilldemo <image_name>\n";
return 0;
}
cout << "Hot keys: \n"
"\tESC - quit the program\n"
"\tc - switch color/grayscale mode\n"
"\tm - switch mask mode\n"
"\tr - restore the original image\n"
"\ts - use null-range floodfill\n"
"\tf - use gradient floodfill with fixed(absolute) range\n"
"\tg - use gradient floodfill with floating(relative) range\n"
"\t4 - use 4-connectivity mode\n"
"\t8 - use 8-connectivity mode\n";
image0.copyTo(image);
cvtColor(image0, gray, CV_BGR2GRAY);
mask.create(image0.rows+2, image0.cols+2, CV_8UC1);
namedWindow( "image", 0 );
createTrackbar( "lo_diff", "image", &loDiff, 255, 0 );
createTrackbar( "up_diff", "image", &upDiff, 255, 0 );
setMouseCallback( "image", onMouse, 0 );
for(;;)
{
imshow("image", isColor ? image : gray);
int c = waitKey(0);
switch( (char)c )
{
case 27:
cout << "Exiting ...\n";
return 0;
case 'c':
if( isColor )
{
cout << "Grayscale mode is set\n";
cvtColor(image0, gray, CV_BGR2GRAY);
mask = Scalar::all(0);
isColor = false;
}
else
{
cout << "Color mode is set\n";
image0.copyTo(image);
mask = Scalar::all(0);
isColor = true;
}
break;
case 'm':
if( useMask )
{
destroyWindow( "mask" );
useMask = false;
}
else
{
namedWindow( "mask", 0 );
mask = Scalar::all(0);
imshow("mask", mask);
useMask = true;
}
break;
case 'r':
cout << "Original image is restored\n";
image0.copyTo(image);
cvtColor(image, gray, CV_BGR2GRAY);
mask = Scalar::all(0);
break;
case 's':
cout << "Simple floodfill mode is set\n";
ffillMode = 0;
break;
case 'f':
cout << "Fixed Range floodfill mode is set\n";
ffillMode = 1;
break;
case 'g':
cout << "Gradient (floating range) floodfill mode is set\n";
ffillMode = 2;
break;
case '4':
cout << "4-connectivity mode is set\n";
connectivity = 4;
break;
case '8':
cout << "8-connectivity mode is set\n";
connectivity = 8;
break;
}
}
return 0;
}

BIN
samples/cpp/fruits.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

View File

@ -1,318 +1,318 @@
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
const Scalar RED = Scalar(0,0,255);
const Scalar PINK = Scalar(230,130,255);
const Scalar BLUE = Scalar(255,0,0);
const Scalar LIGHTBLUE = Scalar(255,255,160);
const Scalar GREEN = Scalar(0,255,0);
const int BGD_KEY = CV_EVENT_FLAG_CTRLKEY;
const int FGD_KEY = CV_EVENT_FLAG_SHIFTKEY;
void getBinMask( const Mat& comMask, Mat& binMask )
{
if( comMask.empty() || comMask.type()!=CV_8UC1 )
CV_Error( CV_StsBadArg, "comMask is empty or has incorrect type (not CV_8UC1)" );
if( binMask.empty() || binMask.rows!=comMask.rows || binMask.cols!=comMask.cols )
binMask.create( comMask.size(), CV_8UC1 );
binMask = comMask & 1;
}
class GCApplication
{
public:
enum{ NOT_SET = 0, IN_PROCESS = 1, SET = 2 };
static const int radius = 2;
static const int thickness = -1;
void reset();
void setImageAndWinName( const Mat& _image, const string& _winName );
void showImage() const;
void mouseClick( int event, int x, int y, int flags, void* param );
int nextIter();
int getIterCount() const { return iterCount; }
private:
void setRectInMask();
void setLblsInMask( int flags, Point p, bool isPr );
const string* winName;
const Mat* image;
Mat mask;
Mat bgdModel, fgdModel;
uchar rectState, lblsState, prLblsState;
bool isInitialized;
Rect rect;
vector<Point> fgdPxls, bgdPxls, prFgdPxls, prBgdPxls;
int iterCount;
};
void GCApplication::reset()
{
if( !mask.empty() )
mask.setTo(Scalar::all(GC_BGD));
bgdPxls.clear(); fgdPxls.clear();
prBgdPxls.clear(); prFgdPxls.clear();
isInitialized = false;
rectState = NOT_SET;
lblsState = NOT_SET;
prLblsState = NOT_SET;
iterCount = 0;
}
void GCApplication::setImageAndWinName( const Mat& _image, const string& _winName )
{
if( _image.empty() || _winName.empty() )
return;
image = &_image;
winName = &_winName;
mask.create( image->size(), CV_8UC1);
reset();
}
void GCApplication::showImage() const
{
if( image->empty() || winName->empty() )
return;
Mat res;
Mat binMask;
if( !isInitialized )
image->copyTo( res );
else
{
getBinMask( mask, binMask );
image->copyTo( res, binMask );
}
vector<Point>::const_iterator it;
for( it = bgdPxls.begin(); it != bgdPxls.end(); ++it )
circle( res, *it, radius, BLUE, thickness );
for( it = fgdPxls.begin(); it != fgdPxls.end(); ++it )
circle( res, *it, radius, RED, thickness );
for( it = prBgdPxls.begin(); it != prBgdPxls.end(); ++it )
circle( res, *it, radius, LIGHTBLUE, thickness );
for( it = prFgdPxls.begin(); it != prFgdPxls.end(); ++it )
circle( res, *it, radius, PINK, thickness );
if( rectState == IN_PROCESS || rectState == SET )
rectangle( res, Point( rect.x, rect.y ), Point(rect.x + rect.width, rect.y + rect.height ), GREEN, 2);
imshow( *winName, res );
}
void GCApplication::setRectInMask()
{
assert( !mask.empty() );
mask.setTo( GC_BGD );
rect.x = max(0, rect.x);
rect.y = max(0, rect.y);
rect.width = min(rect.width, image->cols-rect.x);
rect.height = min(rect.height, image->rows-rect.y);
(mask(rect)).setTo( Scalar(GC_PR_FGD) );
}
void GCApplication::setLblsInMask( int flags, Point p, bool isPr )
{
vector<Point> *bpxls, *fpxls;
uchar bvalue, fvalue;
if( !isPr )
{
bpxls = &bgdPxls;
fpxls = &fgdPxls;
bvalue = GC_BGD;
fvalue = GC_FGD;
}
else
{
bpxls = &prBgdPxls;
fpxls = &prFgdPxls;
bvalue = GC_PR_BGD;
fvalue = GC_PR_FGD;
}
if( flags & BGD_KEY )
{
bpxls->push_back(p);
circle( mask, p, radius, bvalue, thickness );
}
if( flags & FGD_KEY )
{
fpxls->push_back(p);
circle( mask, p, radius, fvalue, thickness );
}
}
void GCApplication::mouseClick( int event, int x, int y, int flags, void* )
{
// TODO add bad args check
switch( event )
{
case CV_EVENT_LBUTTONDOWN: // set rect or GC_BGD(GC_FGD) labels
{
bool isb = (flags & BGD_KEY) != 0,
isf = (flags & FGD_KEY) != 0;
if( rectState == NOT_SET && !isb && !isf )
{
rectState = IN_PROCESS;
rect = Rect( x, y, 1, 1 );
}
if ( (isb || isf) && rectState == SET )
lblsState = IN_PROCESS;
}
break;
case CV_EVENT_RBUTTONDOWN: // set GC_PR_BGD(GC_PR_FGD) labels
{
bool isb = (flags & BGD_KEY) != 0,
isf = (flags & FGD_KEY) != 0;
if ( (isb || isf) && rectState == SET )
prLblsState = IN_PROCESS;
}
break;
case CV_EVENT_LBUTTONUP:
if( rectState == IN_PROCESS )
{
rect = Rect( Point(rect.x, rect.y), Point(x,y) );
rectState = SET;
setRectInMask();
assert( bgdPxls.empty() && fgdPxls.empty() && prBgdPxls.empty() && prFgdPxls.empty() );
showImage();
}
if( lblsState == IN_PROCESS )
{
setLblsInMask(flags, Point(x,y), false);
lblsState = SET;
showImage();
}
break;
case CV_EVENT_RBUTTONUP:
if( prLblsState == IN_PROCESS )
{
setLblsInMask(flags, Point(x,y), true);
prLblsState = SET;
showImage();
}
break;
case CV_EVENT_MOUSEMOVE:
if( rectState == IN_PROCESS )
{
rect = Rect( Point(rect.x, rect.y), Point(x,y) );
assert( bgdPxls.empty() && fgdPxls.empty() && prBgdPxls.empty() && prFgdPxls.empty() );
showImage();
}
else if( lblsState == IN_PROCESS )
{
setLblsInMask(flags, Point(x,y), false);
showImage();
}
else if( prLblsState == IN_PROCESS )
{
setLblsInMask(flags, Point(x,y), true);
showImage();
}
break;
}
}
int GCApplication::nextIter()
{
if( isInitialized )
grabCut( *image, mask, rect, bgdModel, fgdModel, 1 );
else
{
if( rectState != SET )
return iterCount;
if( lblsState == SET || prLblsState == SET )
grabCut( *image, mask, rect, bgdModel, fgdModel, 1, GC_INIT_WITH_MASK );
else
grabCut( *image, mask, rect, bgdModel, fgdModel, 1, GC_INIT_WITH_RECT );
isInitialized = true;
}
iterCount++;
bgdPxls.clear(); fgdPxls.clear();
prBgdPxls.clear(); prFgdPxls.clear();
return iterCount;
}
GCApplication gcapp;
void on_mouse( int event, int x, int y, int flags, void* param )
{
gcapp.mouseClick( event, x, y, flags, param );
}
int main( int argc, char** argv )
{
if( argc==1 )
return 1;
string filename = argv[1];
if( filename.empty() )
return 1;
Mat image = imread( filename, 1 );
if( image.empty() )
return 1;
cout << "First, select the rectangular area\n" <<
"Hot keys: \n"
"\tESC - quit the program\n"
"\tr - restore the original image\n"
"\tn - next iteration\n"
"\n"
"\tleft mouse button - set rectangle\n"
"\n"
"\tCTRL+left mouse button - set GC_BGD pixels\n"
"\tSHIFT+left mouse button - set CG_FGD pixels\n"
"\n"
"\tCTRL+right mouse button - set GC_PR_BGD pixels\n"
"\tSHIFT+right mouse button - set CG_PR_FGD pixels\n";
const string winName = "image";
cvNamedWindow( winName.c_str(), CV_WINDOW_AUTOSIZE );
cvSetMouseCallback( winName.c_str(), on_mouse, 0 );
gcapp.setImageAndWinName( image, winName );
gcapp.showImage();
for(;;)
{
int c = cvWaitKey(0);
switch( (char) c )
{
case '\x1b':
cout << "Exiting ..." << endl;
goto exit_main;
case 'r':
cout << endl;
gcapp.reset();
gcapp.showImage();
break;
case 'n':
int iterCount = gcapp.getIterCount();
cout << "<" << iterCount << "... ";
int newIterCount = gcapp.nextIter();
if( newIterCount > iterCount )
{
gcapp.showImage();
cout << iterCount << ">" << endl;
}
else
cout << "rect must be determined>" << endl;
break;
}
}
exit_main:
cvDestroyWindow( winName.c_str() );
return 0;
}
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
const Scalar RED = Scalar(0,0,255);
const Scalar PINK = Scalar(230,130,255);
const Scalar BLUE = Scalar(255,0,0);
const Scalar LIGHTBLUE = Scalar(255,255,160);
const Scalar GREEN = Scalar(0,255,0);
const int BGD_KEY = CV_EVENT_FLAG_CTRLKEY;
const int FGD_KEY = CV_EVENT_FLAG_SHIFTKEY;
void getBinMask( const Mat& comMask, Mat& binMask )
{
if( comMask.empty() || comMask.type()!=CV_8UC1 )
CV_Error( CV_StsBadArg, "comMask is empty or has incorrect type (not CV_8UC1)" );
if( binMask.empty() || binMask.rows!=comMask.rows || binMask.cols!=comMask.cols )
binMask.create( comMask.size(), CV_8UC1 );
binMask = comMask & 1;
}
class GCApplication
{
public:
enum{ NOT_SET = 0, IN_PROCESS = 1, SET = 2 };
static const int radius = 2;
static const int thickness = -1;
void reset();
void setImageAndWinName( const Mat& _image, const string& _winName );
void showImage() const;
void mouseClick( int event, int x, int y, int flags, void* param );
int nextIter();
int getIterCount() const { return iterCount; }
private:
void setRectInMask();
void setLblsInMask( int flags, Point p, bool isPr );
const string* winName;
const Mat* image;
Mat mask;
Mat bgdModel, fgdModel;
uchar rectState, lblsState, prLblsState;
bool isInitialized;
Rect rect;
vector<Point> fgdPxls, bgdPxls, prFgdPxls, prBgdPxls;
int iterCount;
};
void GCApplication::reset()
{
if( !mask.empty() )
mask.setTo(Scalar::all(GC_BGD));
bgdPxls.clear(); fgdPxls.clear();
prBgdPxls.clear(); prFgdPxls.clear();
isInitialized = false;
rectState = NOT_SET;
lblsState = NOT_SET;
prLblsState = NOT_SET;
iterCount = 0;
}
void GCApplication::setImageAndWinName( const Mat& _image, const string& _winName )
{
if( _image.empty() || _winName.empty() )
return;
image = &_image;
winName = &_winName;
mask.create( image->size(), CV_8UC1);
reset();
}
void GCApplication::showImage() const
{
if( image->empty() || winName->empty() )
return;
Mat res;
Mat binMask;
if( !isInitialized )
image->copyTo( res );
else
{
getBinMask( mask, binMask );
image->copyTo( res, binMask );
}
vector<Point>::const_iterator it;
for( it = bgdPxls.begin(); it != bgdPxls.end(); ++it )
circle( res, *it, radius, BLUE, thickness );
for( it = fgdPxls.begin(); it != fgdPxls.end(); ++it )
circle( res, *it, radius, RED, thickness );
for( it = prBgdPxls.begin(); it != prBgdPxls.end(); ++it )
circle( res, *it, radius, LIGHTBLUE, thickness );
for( it = prFgdPxls.begin(); it != prFgdPxls.end(); ++it )
circle( res, *it, radius, PINK, thickness );
if( rectState == IN_PROCESS || rectState == SET )
rectangle( res, Point( rect.x, rect.y ), Point(rect.x + rect.width, rect.y + rect.height ), GREEN, 2);
imshow( *winName, res );
}
void GCApplication::setRectInMask()
{
assert( !mask.empty() );
mask.setTo( GC_BGD );
rect.x = max(0, rect.x);
rect.y = max(0, rect.y);
rect.width = min(rect.width, image->cols-rect.x);
rect.height = min(rect.height, image->rows-rect.y);
(mask(rect)).setTo( Scalar(GC_PR_FGD) );
}
void GCApplication::setLblsInMask( int flags, Point p, bool isPr )
{
vector<Point> *bpxls, *fpxls;
uchar bvalue, fvalue;
if( !isPr )
{
bpxls = &bgdPxls;
fpxls = &fgdPxls;
bvalue = GC_BGD;
fvalue = GC_FGD;
}
else
{
bpxls = &prBgdPxls;
fpxls = &prFgdPxls;
bvalue = GC_PR_BGD;
fvalue = GC_PR_FGD;
}
if( flags & BGD_KEY )
{
bpxls->push_back(p);
circle( mask, p, radius, bvalue, thickness );
}
if( flags & FGD_KEY )
{
fpxls->push_back(p);
circle( mask, p, radius, fvalue, thickness );
}
}
void GCApplication::mouseClick( int event, int x, int y, int flags, void* )
{
// TODO add bad args check
switch( event )
{
case CV_EVENT_LBUTTONDOWN: // set rect or GC_BGD(GC_FGD) labels
{
bool isb = (flags & BGD_KEY) != 0,
isf = (flags & FGD_KEY) != 0;
if( rectState == NOT_SET && !isb && !isf )
{
rectState = IN_PROCESS;
rect = Rect( x, y, 1, 1 );
}
if ( (isb || isf) && rectState == SET )
lblsState = IN_PROCESS;
}
break;
case CV_EVENT_RBUTTONDOWN: // set GC_PR_BGD(GC_PR_FGD) labels
{
bool isb = (flags & BGD_KEY) != 0,
isf = (flags & FGD_KEY) != 0;
if ( (isb || isf) && rectState == SET )
prLblsState = IN_PROCESS;
}
break;
case CV_EVENT_LBUTTONUP:
if( rectState == IN_PROCESS )
{
rect = Rect( Point(rect.x, rect.y), Point(x,y) );
rectState = SET;
setRectInMask();
assert( bgdPxls.empty() && fgdPxls.empty() && prBgdPxls.empty() && prFgdPxls.empty() );
showImage();
}
if( lblsState == IN_PROCESS )
{
setLblsInMask(flags, Point(x,y), false);
lblsState = SET;
showImage();
}
break;
case CV_EVENT_RBUTTONUP:
if( prLblsState == IN_PROCESS )
{
setLblsInMask(flags, Point(x,y), true);
prLblsState = SET;
showImage();
}
break;
case CV_EVENT_MOUSEMOVE:
if( rectState == IN_PROCESS )
{
rect = Rect( Point(rect.x, rect.y), Point(x,y) );
assert( bgdPxls.empty() && fgdPxls.empty() && prBgdPxls.empty() && prFgdPxls.empty() );
showImage();
}
else if( lblsState == IN_PROCESS )
{
setLblsInMask(flags, Point(x,y), false);
showImage();
}
else if( prLblsState == IN_PROCESS )
{
setLblsInMask(flags, Point(x,y), true);
showImage();
}
break;
}
}
int GCApplication::nextIter()
{
if( isInitialized )
grabCut( *image, mask, rect, bgdModel, fgdModel, 1 );
else
{
if( rectState != SET )
return iterCount;
if( lblsState == SET || prLblsState == SET )
grabCut( *image, mask, rect, bgdModel, fgdModel, 1, GC_INIT_WITH_MASK );
else
grabCut( *image, mask, rect, bgdModel, fgdModel, 1, GC_INIT_WITH_RECT );
isInitialized = true;
}
iterCount++;
bgdPxls.clear(); fgdPxls.clear();
prBgdPxls.clear(); prFgdPxls.clear();
return iterCount;
}
GCApplication gcapp;
void on_mouse( int event, int x, int y, int flags, void* param )
{
gcapp.mouseClick( event, x, y, flags, param );
}
int main( int argc, char** argv )
{
if( argc==1 )
return 1;
string filename = argv[1];
if( filename.empty() )
return 1;
Mat image = imread( filename, 1 );
if( image.empty() )
return 1;
cout << "First, select the rectangular area\n" <<
"Hot keys: \n"
"\tESC - quit the program\n"
"\tr - restore the original image\n"
"\tn - next iteration\n"
"\n"
"\tleft mouse button - set rectangle\n"
"\n"
"\tCTRL+left mouse button - set GC_BGD pixels\n"
"\tSHIFT+left mouse button - set CG_FGD pixels\n"
"\n"
"\tCTRL+right mouse button - set GC_PR_BGD pixels\n"
"\tSHIFT+right mouse button - set CG_PR_FGD pixels\n";
const string winName = "image";
cvNamedWindow( winName.c_str(), CV_WINDOW_AUTOSIZE );
cvSetMouseCallback( winName.c_str(), on_mouse, 0 );
gcapp.setImageAndWinName( image, winName );
gcapp.showImage();
for(;;)
{
int c = cvWaitKey(0);
switch( (char) c )
{
case '\x1b':
cout << "Exiting ..." << endl;
goto exit_main;
case 'r':
cout << endl;
gcapp.reset();
gcapp.showImage();
break;
case 'n':
int iterCount = gcapp.getIterCount();
cout << "<" << iterCount << "... ";
int newIterCount = gcapp.nextIter();
if( newIterCount > iterCount )
{
gcapp.showImage();
cout << iterCount << ">" << endl;
}
else
cout << "rect must be determined>" << endl;
break;
}
}
exit_main:
cvDestroyWindow( winName.c_str() );
return 0;
}

65
samples/cpp/kmeans.cpp Normal file
View File

@ -0,0 +1,65 @@
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
using namespace cv;
int main( int argc, char** argv )
{
const int MAX_CLUSTERS = 5;
Scalar colorTab[] =
{
Scalar(0, 0, 255),
Scalar(0,255,0),
Scalar(255,100,100),
Scalar(255,0,255),
Scalar(0,255,255)
};
Mat img(500, 500, CV_8UC3);
RNG rng(12345);
for(;;)
{
int k, clusterCount = rng.uniform(2, MAX_CLUSTERS+1);
int i, sampleCount = rng.uniform(1, 1001);
Mat points(sampleCount, 1, CV_32FC2), labels;
clusterCount = MIN(clusterCount, sampleCount);
Mat centers(clusterCount, 1, points.type());
/* generate random sample from multigaussian distribution */
for( k = 0; k < clusterCount; k++ )
{
Point center;
center.x = rng.uniform(0, img.cols);
center.y = rng.uniform(0, img.rows);
Mat pointChunk = points.rowRange(k*sampleCount/clusterCount,
k == clusterCount - 1 ? sampleCount :
(k+1)*sampleCount/clusterCount);
rng.fill(pointChunk, CV_RAND_NORMAL, Scalar(center.x, center.y), Scalar(img.cols*0.05, img.rows*0.05));
}
randShuffle(points, 1, &rng);
kmeans(points, clusterCount, labels,
TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0),
3, KMEANS_PP_CENTERS, &centers);
img = Scalar::all(0);
for( i = 0; i < sampleCount; i++ )
{
int clusterIdx = labels.at<int>(i);
Point ipt = points.at<Point2f>(i);
circle( img, ipt, 2, colorTab[clusterIdx], CV_FILLED, CV_AA );
}
imshow("clusters", img);
char key = (char)waitKey();
if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC'
break;
}
return 0;
}

60
samples/cpp/laplace.cpp Normal file
View File

@ -0,0 +1,60 @@
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <ctype.h>
#include <iostream>
using namespace cv;
using namespace std;
int sigma = 3;
int smoothType = CV_GAUSSIAN;
int main( int argc, char** argv )
{
VideoCapture cap;
if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
cap.open(argc == 2 ? argv[1][0] - '0' : 0);
else if( argc == 2 )
cap.open(argv[1]);
if( !cap.isOpened() )
{
cout << "Could not initialize capturing...\n";
return -1;
}
namedWindow( "Laplacian", 0 );
createTrackbar( "Sigma", "Laplacian", &sigma, 15, 0 );
Mat smoothed, laplace, result;
for(;;)
{
Mat frame;
cap >> frame;
if( frame.empty() )
break;
int ksize = (sigma*5)|1;
if(smoothType == CV_GAUSSIAN)
GaussianBlur(frame, smoothed, Size(ksize, ksize), sigma, sigma);
else if(smoothType == CV_BLUR)
blur(frame, smoothed, Size(ksize, ksize));
else
medianBlur(frame, smoothed, ksize);
Laplacian(smoothed, laplace, CV_16S, 5);
convertScaleAbs(laplace, result, (sigma+1)*0.25);
imshow("Laplacian", result);
int c = waitKey(30);
if( c == ' ' )
smoothType = smoothType == CV_GAUSSIAN ? CV_BLUR : smoothType == CV_BLUR ? CV_MEDIAN : CV_GAUSSIAN;
if( c == 'q' || c == 'Q' || (c & 255) == 27 )
break;
}
return 0;
}

BIN
samples/cpp/left01.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
samples/cpp/left02.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
samples/cpp/left03.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
samples/cpp/left04.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
samples/cpp/left05.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
samples/cpp/left06.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
samples/cpp/left07.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
samples/cpp/left08.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
samples/cpp/left09.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
samples/cpp/left11.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
samples/cpp/left12.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
samples/cpp/left13.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
samples/cpp/left14.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,530 @@
#include "opencv2/core/core_c.h"
#include "opencv2/ml/ml.hpp"
/*
The sample demonstrates how to train Random Trees classifier
(or Boosting classifier, or MLP - see main()) using the provided dataset.
We use the sample database letter-recognition.data
from UCI Repository, here is the link:
Newman, D.J. & Hettich, S. & Blake, C.L. & Merz, C.J. (1998).
UCI Repository of machine learning databases
[http://www.ics.uci.edu/~mlearn/MLRepository.html].
Irvine, CA: University of California, Department of Information and Computer Science.
The dataset consists of 20000 feature vectors along with the
responses - capital latin letters A..Z.
The first 16000 (10000 for boosting)) samples are used for training
and the remaining 4000 (10000 for boosting) - to test the classifier.
*/
// This function reads data and responses from the file <filename>
static int
read_num_class_data( const char* filename, int var_count,
CvMat** data, CvMat** responses )
{
const int M = 1024;
FILE* f = fopen( filename, "rt" );
CvMemStorage* storage;
CvSeq* seq;
char buf[M+2];
float* el_ptr;
CvSeqReader reader;
int i, j;
if( !f )
return 0;
el_ptr = new float[var_count+1];
storage = cvCreateMemStorage();
seq = cvCreateSeq( 0, sizeof(*seq), (var_count+1)*sizeof(float), storage );
for(;;)
{
char* ptr;
if( !fgets( buf, M, f ) || !strchr( buf, ',' ) )
break;
el_ptr[0] = buf[0];
ptr = buf+2;
for( i = 1; i <= var_count; i++ )
{
int n = 0;
sscanf( ptr, "%f%n", el_ptr + i, &n );
ptr += n + 1;
}
if( i <= var_count )
break;
cvSeqPush( seq, el_ptr );
}
fclose(f);
*data = cvCreateMat( seq->total, var_count, CV_32F );
*responses = cvCreateMat( seq->total, 1, CV_32F );
cvStartReadSeq( seq, &reader );
for( i = 0; i < seq->total; i++ )
{
const float* sdata = (float*)reader.ptr + 1;
float* ddata = data[0]->data.fl + var_count*i;
float* dr = responses[0]->data.fl + i;
for( j = 0; j < var_count; j++ )
ddata[j] = sdata[j];
*dr = sdata[-1];
CV_NEXT_SEQ_ELEM( seq->elem_size, reader );
}
cvReleaseMemStorage( &storage );
delete el_ptr;
return 1;
}
static
int build_rtrees_classifier( char* data_filename,
char* filename_to_save, char* filename_to_load )
{
CvMat* data = 0;
CvMat* responses = 0;
CvMat* var_type = 0;
CvMat* sample_idx = 0;
int ok = read_num_class_data( data_filename, 16, &data, &responses );
int nsamples_all = 0, ntrain_samples = 0;
int i = 0;
double train_hr = 0, test_hr = 0;
CvRTrees forest;
CvMat* var_importance = 0;
if( !ok )
{
printf( "Could not read the database %s\n", data_filename );
return -1;
}
printf( "The database %s is loaded.\n", data_filename );
nsamples_all = data->rows;
ntrain_samples = (int)(nsamples_all*0.8);
// Create or load Random Trees classifier
if( filename_to_load )
{
// load classifier from the specified file
forest.load( filename_to_load );
ntrain_samples = 0;
if( forest.get_tree_count() == 0 )
{
printf( "Could not read the classifier %s\n", filename_to_load );
return -1;
}
printf( "The classifier %s is loaded.\n", data_filename );
}
else
{
// create classifier by using <data> and <responses>
printf( "Training the classifier ...\n");
// 1. create type mask
var_type = cvCreateMat( data->cols + 1, 1, CV_8U );
cvSet( var_type, cvScalarAll(CV_VAR_ORDERED) );
cvSetReal1D( var_type, data->cols, CV_VAR_CATEGORICAL );
// 2. create sample_idx
sample_idx = cvCreateMat( 1, nsamples_all, CV_8UC1 );
{
CvMat mat;
cvGetCols( sample_idx, &mat, 0, ntrain_samples );
cvSet( &mat, cvRealScalar(1) );
cvGetCols( sample_idx, &mat, ntrain_samples, nsamples_all );
cvSetZero( &mat );
}
// 3. train classifier
forest.train( data, CV_ROW_SAMPLE, responses, 0, sample_idx, var_type, 0,
CvRTParams(10,10,0,false,15,0,true,4,100,0.01f,CV_TERMCRIT_ITER));
printf( "\n");
}
// compute prediction error on train and test data
for( i = 0; i < nsamples_all; i++ )
{
double r;
CvMat sample;
cvGetRow( data, &sample, i );
r = forest.predict( &sample );
r = fabs((double)r - responses->data.fl[i]) <= FLT_EPSILON ? 1 : 0;
if( i < ntrain_samples )
train_hr += r;
else
test_hr += r;
}
test_hr /= (double)(nsamples_all-ntrain_samples);
train_hr /= (double)ntrain_samples;
printf( "Recognition rate: train = %.1f%%, test = %.1f%%\n",
train_hr*100., test_hr*100. );
printf( "Number of trees: %d\n", forest.get_tree_count() );
// Print variable importance
var_importance = (CvMat*)forest.get_var_importance();
if( var_importance )
{
double rt_imp_sum = cvSum( var_importance ).val[0];
printf("var#\timportance (in %%):\n");
for( i = 0; i < var_importance->cols; i++ )
printf( "%-2d\t%-4.1f\n", i,
100.f*var_importance->data.fl[i]/rt_imp_sum);
}
//Print some proximitites
printf( "Proximities between some samples corresponding to the letter 'T':\n" );
{
CvMat sample1, sample2;
const int pairs[][2] = {{0,103}, {0,106}, {106,103}, {-1,-1}};
for( i = 0; pairs[i][0] >= 0; i++ )
{
cvGetRow( data, &sample1, pairs[i][0] );
cvGetRow( data, &sample2, pairs[i][1] );
printf( "proximity(%d,%d) = %.1f%%\n", pairs[i][0], pairs[i][1],
forest.get_proximity( &sample1, &sample2 )*100. );
}
}
// Save Random Trees classifier to file if needed
if( filename_to_save )
forest.save( filename_to_save );
cvReleaseMat( &sample_idx );
cvReleaseMat( &var_type );
cvReleaseMat( &data );
cvReleaseMat( &responses );
return 0;
}
static
int build_boost_classifier( char* data_filename,
char* filename_to_save, char* filename_to_load )
{
const int class_count = 26;
CvMat* data = 0;
CvMat* responses = 0;
CvMat* var_type = 0;
CvMat* temp_sample = 0;
CvMat* weak_responses = 0;
int ok = read_num_class_data( data_filename, 16, &data, &responses );
int nsamples_all = 0, ntrain_samples = 0;
int var_count;
int i, j, k;
double train_hr = 0, test_hr = 0;
CvBoost boost;
if( !ok )
{
printf( "Could not read the database %s\n", data_filename );
return -1;
}
printf( "The database %s is loaded.\n", data_filename );
nsamples_all = data->rows;
ntrain_samples = (int)(nsamples_all*0.5);
var_count = data->cols;
// Create or load Boosted Tree classifier
if( filename_to_load )
{
// load classifier from the specified file
boost.load( filename_to_load );
ntrain_samples = 0;
if( !boost.get_weak_predictors() )
{
printf( "Could not read the classifier %s\n", filename_to_load );
return -1;
}
printf( "The classifier %s is loaded.\n", data_filename );
}
else
{
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// As currently boosted tree classifier in MLL can only be trained
// for 2-class problems, we transform the training database by
// "unrolling" each training sample as many times as the number of
// classes (26) that we have.
//
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
CvMat* new_data = cvCreateMat( ntrain_samples*class_count, var_count + 1, CV_32F );
CvMat* new_responses = cvCreateMat( ntrain_samples*class_count, 1, CV_32S );
// 1. unroll the database type mask
printf( "Unrolling the database...\n");
for( i = 0; i < ntrain_samples; i++ )
{
float* data_row = (float*)(data->data.ptr + data->step*i);
for( j = 0; j < class_count; j++ )
{
float* new_data_row = (float*)(new_data->data.ptr +
new_data->step*(i*class_count+j));
for( k = 0; k < var_count; k++ )
new_data_row[k] = data_row[k];
new_data_row[var_count] = (float)j;
new_responses->data.i[i*class_count + j] = responses->data.fl[i] == j+'A';
}
}
// 2. create type mask
var_type = cvCreateMat( var_count + 2, 1, CV_8U );
cvSet( var_type, cvScalarAll(CV_VAR_ORDERED) );
// the last indicator variable, as well
// as the new (binary) response are categorical
cvSetReal1D( var_type, var_count, CV_VAR_CATEGORICAL );
cvSetReal1D( var_type, var_count+1, CV_VAR_CATEGORICAL );
// 3. train classifier
printf( "Training the classifier (may take a few minutes)...\n");
boost.train( new_data, CV_ROW_SAMPLE, new_responses, 0, 0, var_type, 0,
CvBoostParams(CvBoost::REAL, 100, 0.95, 5, false, 0 ));
cvReleaseMat( &new_data );
cvReleaseMat( &new_responses );
printf("\n");
}
temp_sample = cvCreateMat( 1, var_count + 1, CV_32F );
weak_responses = cvCreateMat( 1, boost.get_weak_predictors()->total, CV_32F );
// compute prediction error on train and test data
for( i = 0; i < nsamples_all; i++ )
{
int best_class = 0;
double max_sum = -DBL_MAX;
double r;
CvMat sample;
cvGetRow( data, &sample, i );
for( k = 0; k < var_count; k++ )
temp_sample->data.fl[k] = sample.data.fl[k];
for( j = 0; j < class_count; j++ )
{
temp_sample->data.fl[var_count] = (float)j;
boost.predict( temp_sample, 0, weak_responses );
double sum = cvSum( weak_responses ).val[0];
if( max_sum < sum )
{
max_sum = sum;
best_class = j + 'A';
}
}
r = fabs(best_class - responses->data.fl[i]) < FLT_EPSILON ? 1 : 0;
if( i < ntrain_samples )
train_hr += r;
else
test_hr += r;
}
test_hr /= (double)(nsamples_all-ntrain_samples);
train_hr /= (double)ntrain_samples;
printf( "Recognition rate: train = %.1f%%, test = %.1f%%\n",
train_hr*100., test_hr*100. );
printf( "Number of trees: %d\n", boost.get_weak_predictors()->total );
// Save classifier to file if needed
if( filename_to_save )
boost.save( filename_to_save );
cvReleaseMat( &temp_sample );
cvReleaseMat( &weak_responses );
cvReleaseMat( &var_type );
cvReleaseMat( &data );
cvReleaseMat( &responses );
return 0;
}
static
int build_mlp_classifier( char* data_filename,
char* filename_to_save, char* filename_to_load )
{
const int class_count = 26;
CvMat* data = 0;
CvMat train_data;
CvMat* responses = 0;
CvMat* mlp_response = 0;
int ok = read_num_class_data( data_filename, 16, &data, &responses );
int nsamples_all = 0, ntrain_samples = 0;
int i, j;
double train_hr = 0, test_hr = 0;
CvANN_MLP mlp;
if( !ok )
{
printf( "Could not read the database %s\n", data_filename );
return -1;
}
printf( "The database %s is loaded.\n", data_filename );
nsamples_all = data->rows;
ntrain_samples = (int)(nsamples_all*0.8);
// Create or load MLP classifier
if( filename_to_load )
{
// load classifier from the specified file
mlp.load( filename_to_load );
ntrain_samples = 0;
if( !mlp.get_layer_count() )
{
printf( "Could not read the classifier %s\n", filename_to_load );
return -1;
}
printf( "The classifier %s is loaded.\n", data_filename );
}
else
{
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// MLP does not support categorical variables by explicitly.
// So, instead of the output class label, we will use
// a binary vector of <class_count> components for training and,
// therefore, MLP will give us a vector of "probabilities" at the
// prediction stage
//
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
CvMat* new_responses = cvCreateMat( ntrain_samples, class_count, CV_32F );
// 1. unroll the responses
printf( "Unrolling the responses...\n");
for( i = 0; i < ntrain_samples; i++ )
{
int cls_label = cvRound(responses->data.fl[i]) - 'A';
float* bit_vec = (float*)(new_responses->data.ptr + i*new_responses->step);
for( j = 0; j < class_count; j++ )
bit_vec[j] = 0.f;
bit_vec[cls_label] = 1.f;
}
cvGetRows( data, &train_data, 0, ntrain_samples );
// 2. train classifier
int layer_sz[] = { data->cols, 100, 100, class_count };
CvMat layer_sizes =
cvMat( 1, (int)(sizeof(layer_sz)/sizeof(layer_sz[0])), CV_32S, layer_sz );
mlp.create( &layer_sizes );
printf( "Training the classifier (may take a few minutes)...\n");
mlp.train( &train_data, new_responses, 0, 0,
CvANN_MLP_TrainParams(cvTermCriteria(CV_TERMCRIT_ITER,300,0.01),
#if 1
CvANN_MLP_TrainParams::BACKPROP,0.001));
#else
CvANN_MLP_TrainParams::RPROP,0.05));
#endif
cvReleaseMat( &new_responses );
printf("\n");
}
mlp_response = cvCreateMat( 1, class_count, CV_32F );
// compute prediction error on train and test data
for( i = 0; i < nsamples_all; i++ )
{
int best_class;
CvMat sample;
cvGetRow( data, &sample, i );
CvPoint max_loc = {0,0};
mlp.predict( &sample, mlp_response );
cvMinMaxLoc( mlp_response, 0, 0, 0, &max_loc, 0 );
best_class = max_loc.x + 'A';
int r = fabs((double)best_class - responses->data.fl[i]) < FLT_EPSILON ? 1 : 0;
if( i < ntrain_samples )
train_hr += r;
else
test_hr += r;
}
test_hr /= (double)(nsamples_all-ntrain_samples);
train_hr /= (double)ntrain_samples;
printf( "Recognition rate: train = %.1f%%, test = %.1f%%\n",
train_hr*100., test_hr*100. );
// Save classifier to file if needed
if( filename_to_save )
mlp.save( filename_to_save );
cvReleaseMat( &mlp_response );
cvReleaseMat( &data );
cvReleaseMat( &responses );
return 0;
}
int main( int argc, char *argv[] )
{
char* filename_to_save = 0;
char* filename_to_load = 0;
char default_data_filename[] = "./letter-recognition.data";
char* data_filename = default_data_filename;
int method = 0;
int i;
for( i = 1; i < argc; i++ )
{
if( strcmp(argv[i],"-data") == 0 ) // flag "-data letter_recognition.xml"
{
i++;
data_filename = argv[i];
}
else if( strcmp(argv[i],"-save") == 0 ) // flag "-save filename.xml"
{
i++;
filename_to_save = argv[i];
}
else if( strcmp(argv[i],"-load") == 0) // flag "-load filename.xml"
{
i++;
filename_to_load = argv[i];
}
else if( strcmp(argv[i],"-boost") == 0)
{
method = 1;
}
else if( strcmp(argv[i],"-mlp") == 0 )
{
method = 2;
}
else
break;
}
if( i < argc ||
(method == 0 ?
build_rtrees_classifier( data_filename, filename_to_save, filename_to_load ) :
method == 1 ?
build_boost_classifier( data_filename, filename_to_save, filename_to_load ) :
method == 2 ?
build_mlp_classifier( data_filename, filename_to_save, filename_to_load ) :
-1) < 0)
{
printf("This is letter recognition sample.\n"
"The usage: letter_recog [-data <path to letter-recognition.data>] \\\n"
" [-save <output XML file for the classifier>] \\\n"
" [-load <XML file with the pre-trained classifier>] \\\n"
" [-boost|-mlp] # to use boost/mlp classifier instead of default Random Trees\n" );
}
return 0;
}

47
samples/cpp/minarea.cpp Normal file
View File

@ -0,0 +1,47 @@
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
int main( int argc, char** argv )
{
Mat img(500, 500, CV_8UC3);
RNG& rng = theRNG();
for(;;)
{
int i, count = rng.uniform(1, 101);
vector<Point> points;
for( i = 0; i < count; i++ )
{
Point pt;
pt.x = rng.uniform(img.cols/4, img.cols*3/4);
pt.y = rng.uniform(img.rows/4, img.rows*3/4);
points.push_back(pt);
}
RotatedRect box = minAreaRect(Mat(points));
Point2f center, vtx[4];
float radius = 0;
minEnclosingCircle(Mat(points), center, radius);
box.points(vtx);
img = Scalar::all(0);
for( i = 0; i < count; i++ )
circle( img, points[i], 3, Scalar(0, 0, 255), CV_FILLED, CV_AA );
for( i = 0; i < 4; i++ )
line(img, vtx[i], vtx[(i+1)%4], Scalar(0, 255, 0), 1, CV_AA);
circle(img, center, cvRound(radius), Scalar(0, 255, 255), 1, CV_AA);
imshow( "rect & circle", img );
char key = (char)cvWaitKey();
if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC'
break;
}
return 0;
}

BIN
samples/cpp/pic1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
samples/cpp/pic2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 KiB

BIN
samples/cpp/pic3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
samples/cpp/pic4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
samples/cpp/pic5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
samples/cpp/pic6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
samples/cpp/right01.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
samples/cpp/right02.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
samples/cpp/right03.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
samples/cpp/right04.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
samples/cpp/right05.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
samples/cpp/right06.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
samples/cpp/right07.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
samples/cpp/right08.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
samples/cpp/right09.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
samples/cpp/right11.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
samples/cpp/right12.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
samples/cpp/right13.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
samples/cpp/right14.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

154
samples/cpp/squares.cpp Normal file
View File

@ -0,0 +1,154 @@
// The "Square Detector" program.
// It loads several images subsequentally and tries to find squares in
// each image
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <math.h>
#include <string.h>
using namespace cv;
using namespace std;
int thresh = 50, N = 11;
const char* wndname = "Square Detection Demo";
// helper function:
// finds a cosine of angle between vectors
// from pt0->pt1 and from pt0->pt2
double angle( Point pt1, Point pt2, Point pt0 )
{
double dx1 = pt1.x - pt0.x;
double dy1 = pt1.y - pt0.y;
double dx2 = pt2.x - pt0.x;
double dy2 = pt2.y - pt0.y;
return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
}
// returns sequence of squares detected on the image.
// the sequence is stored in the specified memory storage
void findSquares( const Mat& image, vector<vector<Point> >& squares )
{
squares.clear();
Mat pyr, timg, gray0(image.size(), CV_8U), gray;
// down-scale and upscale the image to filter out the noise
pyrDown(image, pyr, Size(image.cols/2, image.rows/2));
pyrUp(pyr, timg, image.size());
vector<vector<Point> > contours;
// find squares in every color plane of the image
for( int c = 0; c < 3; c++ )
{
int ch[] = {c, 0};
mixChannels(&timg, 1, &gray0, 1, ch, 1);
// try several threshold levels
for( int l = 0; l < N; l++ )
{
// hack: use Canny instead of zero threshold level.
// Canny helps to catch squares with gradient shading
if( l == 0 )
{
// apply Canny. Take the upper threshold from slider
// and set the lower to 0 (which forces edges merging)
Canny(gray0, gray, 0, thresh, 5);
// dilate canny output to remove potential
// holes between edge segments
dilate(gray, gray, Mat(), Point(-1,-1));
}
else
{
// apply threshold if l!=0:
// tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0
gray = gray0 >= (l+1)*255/N;
}
// find contours and store them all as a list
findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
vector<Point> approx;
// test each contour
for( size_t i = 0; i < contours.size(); i++ )
{
// approximate contour with accuracy proportional
// to the contour perimeter
approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);
// square contours should have 4 vertices after approximation
// relatively large area (to filter out noisy contours)
// and be convex.
// Note: absolute value of an area is used because
// area may be positive or negative - in accordance with the
// contour orientation
if( approx.size() == 4 &&
fabs(contourArea(Mat(approx))) > 1000 &&
isContourConvex(Mat(approx)) )
{
double maxCosine = 0;
for( int j = 2; j < 5; j++ )
{
// find the maximum cosine of the angle between joint edges
double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
maxCosine = MAX(maxCosine, cosine);
}
// if cosines of all angles are small
// (all angles are ~90 degree) then write quandrange
// vertices to resultant sequence
if( maxCosine < 0.3 )
squares.push_back(approx);
}
}
}
}
}
// the function draws all the squares in the image
void drawSquares( Mat& image, const vector<vector<Point> >& squares )
{
for( size_t i = 0; i < squares.size(); i++ )
{
const Point* p = &squares[i][0];
int n = (int)squares[i].size();
polylines(image, &p, &n, 1, true, Scalar(0,255,0), 3, CV_AA);
}
imshow(wndname, image);
}
int main(int argc, char** argv)
{
static const char* names[] = { "pic1.png", "pic2.png", "pic3.png",
"pic4.png", "pic5.png", "pic6.png", 0 };
namedWindow( wndname, 1 );
vector<vector<Point> > squares;
for( int i = 0; names[i] != 0; i++ )
{
Mat image = imread(names[i], 1);
if( image.empty() )
{
cout << "Couldn't load " << names[i] << endl;
continue;
}
findSquares(image, squares);
drawSquares(image, squares);
int c = waitKey();
if( (char)c == 27 )
break;
}
return 0;
}

View File

@ -0,0 +1,388 @@
/* This is sample from the OpenCV book. The copyright notice is below */
/* *************** License:**************************
Oct. 3, 2008
Right to use this code in any way you want without warrenty, support or any guarentee of it working.
BOOK: It would be nice if you cited it:
Learning OpenCV: Computer Vision with the OpenCV Library
by Gary Bradski and Adrian Kaehler
Published by O'Reilly Media, October 3, 2008
AVAILABLE AT:
http://www.amazon.com/Learning-OpenCV-Computer-Vision-Library/dp/0596516134
Or: http://oreilly.com/catalog/9780596516130/
ISBN-10: 0596516134 or: ISBN-13: 978-0596516130
OTHER OPENCV SITES:
* The source code is on sourceforge at:
http://sourceforge.net/projects/opencvlibrary/
* The OpenCV wiki page (As of Oct 1, 2008 this is down for changing over servers, but should come back):
http://opencvlibrary.sourceforge.net/
* An active user group is at:
http://tech.groups.yahoo.com/group/OpenCV/
* The minutes of weekly OpenCV development meetings are at:
http://pr.willowgarage.com/wiki/OpenCV
************************************************** */
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include <vector>
#include <string>
#include <algorithm>
#include <stdio.h>
#include <ctype.h>
using namespace std;
//
// Given a list of chessboard images, the number of corners (nx, ny)
// on the chessboards, and a flag: useCalibrated for calibrated (0) or
// uncalibrated (1: use cvStereoCalibrate(), 2: compute fundamental
// matrix separately) stereo. Calibrate the cameras and display the
// rectified results along with the computed disparity images.
//
static void
StereoCalib(const char* path, const char* imageList, int useUncalibrated)
{
CvRect roi1, roi2;
int nx = 0, ny = 0;
int displayCorners = 1;
int showUndistorted = 1;
bool isVerticalStereo = false;//OpenCV can handle left-right
//or up-down camera arrangements
const int maxScale = 1;
const float squareSize = 1.f; //Set this to your actual square size
FILE* f = fopen(imageList, "rt");
int i, j, lr, nframes = 0, n, N = 0;
vector<string> imageNames[2];
vector<CvPoint3D32f> objectPoints;
vector<CvPoint2D32f> points[2];
vector<CvPoint2D32f> temp_points[2];
vector<int> npoints;
// vector<uchar> active[2];
int is_found[2] = {0, 0};
vector<CvPoint2D32f> temp;
CvSize imageSize = {0,0};
// ARRAY AND VECTOR STORAGE:
double M1[3][3], M2[3][3], D1[5], D2[5];
double R[3][3], T[3], E[3][3], F[3][3];
double Q[4][4];
CvMat _M1 = cvMat(3, 3, CV_64F, M1 );
CvMat _M2 = cvMat(3, 3, CV_64F, M2 );
CvMat _D1 = cvMat(1, 5, CV_64F, D1 );
CvMat _D2 = cvMat(1, 5, CV_64F, D2 );
CvMat matR = cvMat(3, 3, CV_64F, R );
CvMat matT = cvMat(3, 1, CV_64F, T );
CvMat matE = cvMat(3, 3, CV_64F, E );
CvMat matF = cvMat(3, 3, CV_64F, F );
CvMat matQ = cvMat(4, 4, CV_64FC1, Q);
char buf[1024];
if( displayCorners )
cvNamedWindow( "corners", 1 );
// READ IN THE LIST OF CHESSBOARDS:
if( !f )
{
fprintf(stderr, "can not open file %s\n", imageList );
return;
}
if( !fgets(buf, sizeof(buf)-3, f) || sscanf(buf, "%d%d", &nx, &ny) != 2 )
return;
n = nx*ny;
temp.resize(n);
temp_points[0].resize(n);
temp_points[1].resize(n);
for(i=0;;i++)
{
int count = 0, result=0;
lr = i % 2;
vector<CvPoint2D32f>& pts = temp_points[lr];//points[lr];
if( !fgets( buf, sizeof(buf)-3, f ))
break;
size_t len = strlen(buf);
while( len > 0 && isspace(buf[len-1]))
buf[--len] = '\0';
if( buf[0] == '#')
continue;
char fullpath[1024];
sprintf(fullpath, "%s/%s", path, buf);
IplImage* img = cvLoadImage( fullpath, 0 );
if( !img )
{
printf("Cannot read file %s\n", fullpath);
return;
}
imageSize = cvGetSize(img);
imageNames[lr].push_back(buf);
//FIND CHESSBOARDS AND CORNERS THEREIN:
for( int s = 1; s <= maxScale; s++ )
{
IplImage* timg = img;
if( s > 1 )
{
timg = cvCreateImage(cvSize(img->width*s,img->height*s),
img->depth, img->nChannels );
cvResize( img, timg, CV_INTER_CUBIC );
}
result = cvFindChessboardCorners( timg, cvSize(nx, ny),
&temp[0], &count,
CV_CALIB_CB_ADAPTIVE_THRESH |
CV_CALIB_CB_NORMALIZE_IMAGE);
if( timg != img )
cvReleaseImage( &timg );
if( result || s == maxScale )
for( j = 0; j < count; j++ )
{
temp[j].x /= s;
temp[j].y /= s;
}
if( result )
break;
}
if( displayCorners )
{
printf("%s\n", buf);
IplImage* cimg = cvCreateImage( imageSize, 8, 3 );
cvCvtColor( img, cimg, CV_GRAY2BGR );
cvDrawChessboardCorners( cimg, cvSize(nx, ny), &temp[0],
count, result );
IplImage* cimg1 = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3);
cvResize(cimg, cimg1);
cvShowImage( "corners", cimg1 );
cvReleaseImage( &cimg );
cvReleaseImage( &cimg1 );
int c = cvWaitKey(1000);
if( c == 27 || c == 'q' || c == 'Q' ) //Allow ESC to quit
exit(-1);
}
else
putchar('.');
//N = pts.size();
//pts.resize(N + n, cvPoint2D32f(0,0));
//active[lr].push_back((uchar)result);
is_found[lr] = result > 0 ? 1 : 0;
//assert( result != 0 );
if( result )
{
//Calibration will suffer without subpixel interpolation
cvFindCornerSubPix( img, &temp[0], count,
cvSize(11, 11), cvSize(-1,-1),
cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,
30, 0.01) );
copy( temp.begin(), temp.end(), pts.begin() );
}
cvReleaseImage( &img );
if(lr)
{
if(is_found[0] == 1 && is_found[1] == 1)
{
assert(temp_points[0].size() == temp_points[1].size());
int current_size = points[0].size();
points[0].resize(current_size + temp_points[0].size(), cvPoint2D32f(0.0, 0.0));
points[1].resize(current_size + temp_points[1].size(), cvPoint2D32f(0.0, 0.0));
copy(temp_points[0].begin(), temp_points[0].end(), points[0].begin() + current_size);
copy(temp_points[1].begin(), temp_points[1].end(), points[1].begin() + current_size);
nframes++;
printf("Pair successfully detected...\n");
}
is_found[0] = 0;
is_found[1] = 0;
}
}
fclose(f);
printf("\n");
// HARVEST CHESSBOARD 3D OBJECT POINT LIST:
objectPoints.resize(nframes*n);
for( i = 0; i < ny; i++ )
for( j = 0; j < nx; j++ )
objectPoints[i*nx + j] =
cvPoint3D32f(i*squareSize, j*squareSize, 0);
for( i = 1; i < nframes; i++ )
copy( objectPoints.begin(), objectPoints.begin() + n,
objectPoints.begin() + i*n );
npoints.resize(nframes,n);
N = nframes*n;
CvMat _objectPoints = cvMat(1, N, CV_32FC3, &objectPoints[0] );
CvMat _imagePoints1 = cvMat(1, N, CV_32FC2, &points[0][0] );
CvMat _imagePoints2 = cvMat(1, N, CV_32FC2, &points[1][0] );
CvMat _npoints = cvMat(1, npoints.size(), CV_32S, &npoints[0] );
cvSetIdentity(&_M1);
cvSetIdentity(&_M2);
cvZero(&_D1);
cvZero(&_D2);
// CALIBRATE THE STEREO CAMERAS
printf("Running stereo calibration ...");
fflush(stdout);
cvStereoCalibrate( &_objectPoints, &_imagePoints1,
&_imagePoints2, &_npoints,
&_M1, &_D1, &_M2, &_D2,
imageSize, &matR, &matT, &matE, &matF,
cvTermCriteria(CV_TERMCRIT_ITER+
CV_TERMCRIT_EPS, 100, 1e-5),
CV_CALIB_FIX_ASPECT_RATIO +
CV_CALIB_ZERO_TANGENT_DIST +
CV_CALIB_SAME_FOCAL_LENGTH +
CV_CALIB_FIX_K3);
printf(" done\n");
// CALIBRATION QUALITY CHECK
// because the output fundamental matrix implicitly
// includes all the output information,
// we can check the quality of calibration using the
// epipolar geometry constraint: m2^t*F*m1=0
vector<CvPoint3D32f> lines[2];
points[0].resize(N);
points[1].resize(N);
_imagePoints1 = cvMat(1, N, CV_32FC2, &points[0][0] );
_imagePoints2 = cvMat(1, N, CV_32FC2, &points[1][0] );
lines[0].resize(N);
lines[1].resize(N);
CvMat _L1 = cvMat(1, N, CV_32FC3, &lines[0][0]);
CvMat _L2 = cvMat(1, N, CV_32FC3, &lines[1][0]);
//Always work in undistorted space
cvUndistortPoints( &_imagePoints1, &_imagePoints1,
&_M1, &_D1, 0, &_M1 );
cvUndistortPoints( &_imagePoints2, &_imagePoints2,
&_M2, &_D2, 0, &_M2 );
cvComputeCorrespondEpilines( &_imagePoints1, 1, &matF, &_L1 );
cvComputeCorrespondEpilines( &_imagePoints2, 2, &matF, &_L2 );
double avgErr = 0;
for( i = 0; i < N; i++ )
{
double err = fabs(points[0][i].x*lines[1][i].x +
points[0][i].y*lines[1][i].y + lines[1][i].z)
+ fabs(points[1][i].x*lines[0][i].x +
points[1][i].y*lines[0][i].y + lines[0][i].z);
avgErr += err;
}
printf( "avg err = %g\n", avgErr/(nframes*n) );
// save intrinsic parameters
CvFileStorage* fstorage = cvOpenFileStorage("intrinsics.yml", NULL, CV_STORAGE_WRITE);
cvWrite(fstorage, "M1", &_M1);
cvWrite(fstorage, "D1", &_D1);
cvWrite(fstorage, "M2", &_M2);
cvWrite(fstorage, "D2", &_D2);
cvReleaseFileStorage(&fstorage);
//COMPUTE AND DISPLAY RECTIFICATION
if( showUndistorted )
{
CvMat* mx1 = cvCreateMat( imageSize.height,
imageSize.width, CV_32F );
CvMat* my1 = cvCreateMat( imageSize.height,
imageSize.width, CV_32F );
CvMat* mx2 = cvCreateMat( imageSize.height,
imageSize.width, CV_32F );
CvMat* my2 = cvCreateMat( imageSize.height,
imageSize.width, CV_32F );
CvMat* img1r = cvCreateMat( imageSize.height,
imageSize.width, CV_8U );
CvMat* img2r = cvCreateMat( imageSize.height,
imageSize.width, CV_8U );
CvMat* disp = cvCreateMat( imageSize.height,
imageSize.width, CV_16S );
double R1[3][3], R2[3][3], P1[3][4], P2[3][4];
CvMat _R1 = cvMat(3, 3, CV_64F, R1);
CvMat _R2 = cvMat(3, 3, CV_64F, R2);
// IF BY CALIBRATED (BOUGUET'S METHOD)
if( useUncalibrated == 0 )
{
CvMat _P1 = cvMat(3, 4, CV_64F, P1);
CvMat _P2 = cvMat(3, 4, CV_64F, P2);
cvStereoRectify( &_M1, &_M2, &_D1, &_D2, imageSize,
&matR, &matT,
&_R1, &_R2, &_P1, &_P2, &matQ,
CV_CALIB_ZERO_DISPARITY,
1, imageSize, &roi1, &roi2);
CvFileStorage* file = cvOpenFileStorage("extrinsics.yml", NULL, CV_STORAGE_WRITE);
cvWrite(file, "R", &matR);
cvWrite(file, "T", &matT);
cvWrite(file, "R1", &_R1);
cvWrite(file, "R2", &_R2);
cvWrite(file, "P1", &_P1);
cvWrite(file, "P2", &_P2);
cvWrite(file, "Q", &matQ);
cvReleaseFileStorage(&file);
isVerticalStereo = fabs(P2[1][3]) > fabs(P2[0][3]);
if(!isVerticalStereo)
roi2.x += imageSize.width;
else
roi2.y += imageSize.height;
//Precompute maps for cvRemap()
cvInitUndistortRectifyMap(&_M1,&_D1,&_R1,&_P1,mx1,my1);
cvInitUndistortRectifyMap(&_M2,&_D2,&_R2,&_P2,mx2,my2);
}
//OR ELSE HARTLEY'S METHOD
else if( useUncalibrated == 1 || useUncalibrated == 2 )
// use intrinsic parameters of each camera, but
// compute the rectification transformation directly
// from the fundamental matrix
{
double H1[3][3], H2[3][3], iM[3][3];
CvMat _H1 = cvMat(3, 3, CV_64F, H1);
CvMat _H2 = cvMat(3, 3, CV_64F, H2);
CvMat _iM = cvMat(3, 3, CV_64F, iM);
//Just to show you could have independently used F
if( useUncalibrated == 2 )
cvFindFundamentalMat( &_imagePoints1,
&_imagePoints2, &matF);
cvStereoRectifyUncalibrated( &_imagePoints1,
&_imagePoints2, &matF,
imageSize,
&_H1, &_H2, 3);
cvInvert(&_M1, &_iM);
cvMatMul(&_H1, &_M1, &_R1);
cvMatMul(&_iM, &_R1, &_R1);
cvInvert(&_M2, &_iM);
cvMatMul(&_H2, &_M2, &_R2);
cvMatMul(&_iM, &_R2, &_R2);
//Precompute map for cvRemap()
cvInitUndistortRectifyMap(&_M1,&_D1,&_R1,&_M1,mx1,my1);
cvInitUndistortRectifyMap(&_M2,&_D1,&_R2,&_M2,mx2,my2);
}
else
assert(0);
cvReleaseMat( &mx1 );
cvReleaseMat( &my1 );
cvReleaseMat( &mx2 );
cvReleaseMat( &my2 );
cvReleaseMat( &img1r );
cvReleaseMat( &img2r );
cvReleaseMat( &disp );
}
}
int main(int argc, char** argv)
{
if(argc > 1 && !strcmp(argv[1], "--help"))
{
printf("Usage:\n ./stereo_calib <path to images> <file wtih image list>\n");
return 0;
}
StereoCalib(argc > 1 ? argv[1] : ".", argc > 2 ? argv[2] : "stereo_calib.txt", 0);
return 0;
}

View File

@ -0,0 +1,27 @@
9 6
left01.jpg
right01.jpg
left02.jpg
right02.jpg
left03.jpg
right03.jpg
left04.jpg
right04.jpg
left05.jpg
right05.jpg
left06.jpg
right06.jpg
left07.jpg
right07.jpg
left08.jpg
right08.jpg
left09.jpg
right09.jpg
left11.jpg
right11.jpg
left12.jpg
right12.jpg
left13.jpg
right13.jpg
left14.jpg
right14.jpg

View File

@ -0,0 +1,265 @@
/*
* stereo_match.cpp
* calibration
*
* Created by Victor Eruhimov on 1/18/10.
* Copyright 2010 Argus Corp. All rights reserved.
*
*/
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdio.h>
using namespace cv;
void saveXYZ(const char* filename, const Mat& mat)
{
const double max_z = 1.0e4;
FILE* fp = fopen(filename, "wt");
for(int y = 0; y < mat.rows; y++)
{
for(int x = 0; x < mat.cols; x++)
{
Vec3f point = mat.at<Vec3f>(y, x);
if(fabs(point[2] - max_z) < FLT_EPSILON || fabs(point[2]) > max_z) continue;
fprintf(fp, "%f %f %f\n", point[0], point[1], point[2]);
}
}
fclose(fp);
}
void print_help()
{
printf("Usage: stereo_match <left_image> <right_image> [--algorithm=bm|sgbm|hh] [--blocksize=<block_size>]\n"
"[--max-disparity=<max_disparity>] [-i <intrinsic_filename>] [-e <extrinsic_filename>]\n"
"[--no-display] [-o <disparity_image>] [-p <point_cloud_file>]\n");
}
int main(int argc, char** argv)
{
const char* algorithm_opt = "--algorithm=";
const char* maxdisp_opt = "--max-disparity=";
const char* blocksize_opt = "--blocksize=";
const char* nodisplay_opt = "--no-display=";
if(argc < 3)
{
print_help();
return 0;
}
const char* img1_filename = 0;
const char* img2_filename = 0;
const char* intrinsic_filename = 0;
const char* extrinsic_filename = 0;
const char* disparity_filename = 0;
const char* point_cloud_filename = 0;
enum { STEREO_BM=0, STEREO_SGBM=1, STEREO_HH=2 };
int alg = STEREO_SGBM;
int SADWindowSize = 0, numberOfDisparities = 0;
bool no_display = false;
StereoBM bm;
StereoSGBM sgbm;
for( int i = 1; i < argc; i++ )
{
if( argv[i][0] != '-' )
{
if( !img1_filename )
img1_filename = argv[i];
else
img2_filename = argv[i];
}
else if( strncmp(argv[i], algorithm_opt, strlen(algorithm_opt)) == 0 )
{
char* _alg = argv[i] + strlen(algorithm_opt);
alg = strcmp(_alg, "bm") == 0 ? STEREO_BM :
strcmp(_alg, "sgbm") == 0 ? STEREO_SGBM :
strcmp(_alg, "hh") == 0 ? STEREO_HH : -1;
if( alg < 0 )
{
printf("Command-line parameter error: Unknown stereo algorithm\n\n");
print_help();
return -1;
}
}
else if( strncmp(argv[i], maxdisp_opt, strlen(maxdisp_opt)) == 0 )
{
if( sscanf( argv[i] + strlen(maxdisp_opt), "%d", &numberOfDisparities ) != 1 ||
numberOfDisparities < 1 || numberOfDisparities % 16 != 0 )
{
printf("Command-line parameter error: The max disparity (--maxdisparity=<...>) must be a positive integer divisible by 16\n");
print_help();
return -1;
}
}
else if( strncmp(argv[i], blocksize_opt, strlen(blocksize_opt)) == 0 )
{
if( sscanf( argv[i] + strlen(blocksize_opt), "%d", &SADWindowSize ) != 1 ||
SADWindowSize < 1 || SADWindowSize % 2 != 1 )
{
printf("Command-line parameter error: The block size (--blocksize=<...>) must be a positive odd number\n");
return -1;
}
}
else if( strcmp(argv[i], nodisplay_opt) == 0 )
no_display = true;
else if( strcmp(argv[i], "-i" ) == 0 )
intrinsic_filename = argv[++i];
else if( strcmp(argv[i], "-e" ) == 0 )
extrinsic_filename = argv[++i];
else if( strcmp(argv[i], "-o" ) == 0 )
disparity_filename = argv[++i];
else if( strcmp(argv[i], "-p" ) == 0 )
point_cloud_filename = argv[++i];
else
{
printf("Command-line parameter error: unknown option %s\n", argv[i]);
return -1;
}
}
if( !img1_filename || !img2_filename )
{
printf("Command-line parameter error: both left and right images must be specified\n");
return -1;
}
if( (intrinsic_filename != 0) ^ (extrinsic_filename != 0) )
{
printf("Command-line parameter error: either both intrinsic and extrinsic parameters must be specified, or none of them (when the stereo pair is already rectified)\n");
return -1;
}
if( extrinsic_filename == 0 && point_cloud_filename )
{
printf("Command-line parameter error: extrinsic and intrinsic parameters must be specified to compute the point cloud\n");
return -1;
}
int color_mode = alg == STEREO_BM ? 0 : -1;
Mat img1 = imread(img1_filename, color_mode);
Mat img2 = imread(img2_filename, color_mode);
Size img_size = img1.size();
Rect roi1, roi2;
Mat Q;
if( intrinsic_filename )
{
// reading intrinsic parameters
FileStorage fs(intrinsic_filename, CV_STORAGE_READ);
if(!fs.isOpened())
{
printf("Failed to open file %s\n", intrinsic_filename);
return -1;
}
Mat M1, D1, M2, D2;
fs["M1"] >> M1;
fs["D1"] >> D1;
fs["M2"] >> M2;
fs["D2"] >> D2;
fs.open(extrinsic_filename, CV_STORAGE_READ);
if(!fs.isOpened())
{
printf("Failed to open file %s\n", extrinsic_filename);
return -1;
}
Mat R, T, R1, P1, R2, P2;
fs["R"] >> R;
fs["T"] >> T;
stereoRectify( M1, D1, M2, D2, img_size, R, T, R1, R2, P1, P2, Q, -1, img_size, &roi1, &roi2 );
Mat map11, map12, map21, map22;
initUndistortRectifyMap(M1, D1, R1, P1, img_size, CV_16SC2, map11, map12);
initUndistortRectifyMap(M2, D2, R2, P2, img_size, CV_16SC2, map21, map22);
Mat img1r, img2r;
remap(img1, img1r, map11, map12, INTER_LINEAR);
remap(img2, img2r, map21, map22, INTER_LINEAR);
img1 = img1r;
img2 = img2r;
}
numberOfDisparities = numberOfDisparities > 0 ? numberOfDisparities : img_size.width/8;
bm.state->roi1 = roi1;
bm.state->roi2 = roi2;
bm.state->preFilterCap = 31;
bm.state->SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 9;
bm.state->minDisparity = 0;
bm.state->numberOfDisparities = numberOfDisparities;
bm.state->textureThreshold = 10;
bm.state->uniquenessRatio = 15;
bm.state->speckleWindowSize = 100;
bm.state->speckleRange = 32;
bm.state->disp12MaxDiff = 1;
sgbm.preFilterCap = 63;
sgbm.SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 3;
int cn = img1.channels();
sgbm.P1 = 8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
sgbm.P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
sgbm.minDisparity = 0;
sgbm.numberOfDisparities = numberOfDisparities;
sgbm.uniquenessRatio = 10;
sgbm.speckleWindowSize = bm.state->speckleWindowSize;
sgbm.speckleRange = bm.state->speckleRange;
sgbm.disp12MaxDiff = 1;
sgbm.fullDP = alg == STEREO_HH;
Mat disp, disp8;
//Mat img1p, img2p, dispp;
//copyMakeBorder(img1, img1p, 0, 0, numberOfDisparities, 0, IPL_BORDER_REPLICATE);
//copyMakeBorder(img2, img2p, 0, 0, numberOfDisparities, 0, IPL_BORDER_REPLICATE);
int64 t = getTickCount();
if( alg == STEREO_BM )
bm(img1, img2, disp);
else
sgbm(img1, img2, disp);
t = getTickCount() - t;
printf("Time elapsed: %fms\n", t*1000/getTickFrequency());
//disp = dispp.colRange(numberOfDisparities, img1p.cols);
disp.convertTo(disp8, CV_8U, 255/(numberOfDisparities*16.));
if( !no_display )
{
namedWindow("left", 1);
imshow("left", img1);
namedWindow("right", 1);
imshow("right", img2);
namedWindow("disparity", 0);
imshow("disparity", disp8);
printf("press any key to continue...");
fflush(stdout);
waitKey();
printf("\n");
}
if(disparity_filename)
imwrite(disparity_filename, disp8);
if(point_cloud_filename)
{
printf("storing the point cloud...");
fflush(stdout);
Mat xyz;
reprojectImageTo3D(disp, xyz, Q, true);
saveXYZ(point_cloud_filename, xyz);
printf("\n");
}
return 0;
}

BIN
samples/cpp/stuff.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

127
samples/cpp/watershed.cpp Normal file
View File

@ -0,0 +1,127 @@
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
Mat markerMask, img;
Point prevPt(-1, -1);
void onMouse( int event, int x, int y, int flags, void* )
{
if( x < 0 || x >= img.cols || y < 0 || y >= img.rows )
return;
if( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON) )
prevPt = Point(-1,-1);
else if( event == CV_EVENT_LBUTTONDOWN )
prevPt = Point(x,y);
else if( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON) )
{
Point pt(x, y);
if( prevPt.x < 0 )
prevPt = pt;
line( markerMask, prevPt, pt, Scalar::all(255), 5, 8, 0 );
line( img, prevPt, pt, Scalar::all(255), 5, 8, 0 );
prevPt = pt;
imshow("image", img);
}
}
int main( int argc, char** argv )
{
char* filename = argc >= 2 ? argv[1] : (char*)"fruits.jpg";
Mat img0 = imread(filename, 1), imgGray;
if( img0.empty() )
{
cout << "Usage: watershed <image_name>\n";
return 0;
}
cout << "Hot keys: \n"
"\tESC - quit the program\n"
"\tr - restore the original image\n"
"\tw or SPACE - run watershed algorithm\n"
"\t\t(before running it, roughly mark the areas on the image)\n"
"\t (before that, roughly outline several markers on the image)\n";
namedWindow( "image", 1 );
img0.copyTo(img);
cvtColor(img, markerMask, CV_BGR2GRAY);
cvtColor(markerMask, imgGray, CV_GRAY2BGR);
markerMask = Scalar::all(0);
imshow( "image", img );
setMouseCallback( "image", onMouse, 0 );
for(;;)
{
int c = waitKey(0);
if( (char)c == 27 )
break;
if( (char)c == 'r' )
{
markerMask = Scalar::all(0);
img0.copyTo(img);
imshow( "image", img );
}
if( (char)c == 'w' || (char)c == ' ' )
{
int i, j, compCount = 0;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(markerMask, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
Mat markers(markerMask.size(), CV_32S);
markers = Scalar::all(0);
int idx = 0;
for( ; idx >= 0; idx = hierarchy[idx][0], compCount++ )
drawContours(markers, contours, idx, Scalar::all(compCount+1), -1, 8, hierarchy, INT_MAX);
if( compCount == 0 )
continue;
vector<Vec3b> colorTab;
for( i = 0; i < compCount; i++ )
{
int b = theRNG().uniform(180, 230);
int g = theRNG().uniform(180, 230);
int r = theRNG().uniform(180, 230);
colorTab.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
}
double t = (double)getTickCount();
watershed( img0, markers );
t = (double)getTickCount() - t;
printf( "execution time = %gms\n", t*1000./getTickFrequency() );
Mat wshed(markers.size(), CV_8UC3);
// paint the watershed image
for( i = 0; i < markers.rows; i++ )
for( j = 0; j < markers.cols; j++ )
{
int idx = markers.at<int>(i,j);
if( idx == -1 )
wshed.at<Vec3b>(i,j) = Vec3b(255,255,255);
else if( idx <= 0 || idx > compCount )
wshed.at<Vec3b>(i,j) = Vec3b(0,0,0);
else
wshed.at<Vec3b>(i,j) = colorTab[idx - 1];
}
wshed = wshed*0.5 + imgGray*0.5;
imshow( "watershed transform", wshed );
}
}
return 0;
}