@ -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 |
|
||||||
|
|
@ -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 |
|
||||||
|
|
@ -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; |
|
||||||
} |
|
@ -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; |
|
||||||
} |
|
@ -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 |
|
@ -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 |
|
@ -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 |
|
@ -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. ] |
@ -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 |
|
@ -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 |
|
@ -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, ¢er, &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, ¢er, &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 |
|
||||||
|
|
@ -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 |
|
@ -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; |
||||||
|
} |
@ -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; |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
|
@ -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; |
||||||
|
} |
@ -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 |
@ -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; |
||||||
|
} |
@ -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; |
||||||
|
} |
After Width: | Height: | Size: 80 KiB |
@ -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, ¢ers); |
||||||
|
|
||||||
|
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; |
||||||
|
} |
@ -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; |
||||||
|
} |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 27 KiB |
@ -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; |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
|
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 254 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 108 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 25 KiB |
@ -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; |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
|
@ -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 |
@ -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; |
||||||
|
} |
After Width: | Height: | Size: 29 KiB |
@ -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; |
||||||
|
} |