CvPoint CTools::QuartzPostion(IplImage* src, IplImage* dst) { CvMemStorage * storage = cvCreateMemStorage(0); CvSeq * contour = 0; int mode = CV_RETR_EXTERNAL; double length; CvPoint2D32f center; float r; CvPoint pt; pt.y = 1000; pt.x = 0; CalibrateData m_CalDat; GetCalirateParam(&m_CalDat); IplImage* temp = cvCreateImage(cvGetSize(src), 8, 1); cvCanny(src, temp, 50, 100); cvFindContours(temp, storage, &contour, sizeof(CvContour), mode); for( CvSeq* c = contour; c != NULL; c = c->h_next) { c = cvApproxPoly( c, sizeof(CvContour), storage, CV_POLY_APPROX_DP, 5, 1 ); length = cvArcLength(c, CV_WHOLE_SEQ, -1); if ((length > m_CalDat.WaferPxLow) && (length < m_CalDat.WaferPxHigh)) { cvDrawContours(dst, c, CV_RGB(0,0,255), CV_RGB(255, 0, 0), -1, 2, 8); cvMinEnclosingCircle(c, ¢er, &r); if ((center.y > 336) && (center.y < pt.y)) { pt = cvPointFrom32f(center); } //pt[num] = cvPointFrom32f(center); //cvCircle(pContoursImg, pt[num], 3, CV_RGB(0,0,255), -1); //cvCircle(pContoursImg, pt[num], r, CV_RGB(0,0,255), 2); } } cvCircle(dst, pt, 10, CV_RGB(255,0, 0), -1); cvReleaseImage(&temp); cvClearMemStorage( storage ); cvReleaseMemStorage( &storage ); return pt; }
void mvContours::get_circle_parameters (IplImage* img, CvSeq* contour1, CvPoint ¢roid, float &radius) { assert (contour1->total > 3); CvPoint2D32f centroid32f; cvMinEnclosingCircle(contour1, ¢roid32f, &radius); int x = static_cast<int>(centroid32f.x); int y = static_cast<int>(centroid32f.y); if (radius > img->height/2) { radius = -1; return; } centroid.x = x - img->width*0.5; centroid.y = y - img->height*0.5; cvCircle (img, cvPoint(x,y), static_cast<int>(radius), CV_RGB(50,50,50), 2); }
void EnclosingCircle(IplImage* _image, IplImage *dem) { assert(_image != 0); IplImage* bin = cvCreateImage( cvGetSize(_image), IPL_DEPTH_8U, 1); // конвертируем в градации серого cvConvertImage(_image, bin, CV_BGR2GRAY); // находим границы cvCanny(bin, bin, 100, 200); //cvNamedWindow( "bin", 1 ); //cvShowImage("bin", bin); // хранилище памяти для контуров CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* contours = 0; // находим контуры int contoursCont = cvFindContours( bin, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0)); assert(contours != 0); CvPoint2D32f center; float radius = 0; // обходим все контуры for( CvSeq* current = contours; current != NULL; current = current->h_next ) { // находим параметры окружности cvMinEnclosingCircle(current, ¢er, &radius); // рисуем cvCircle(dem, cvPointFrom32f(center), radius, CV_RGB(255, 0, 0), 1, 1); } // освобождаем ресурсы cvReleaseMemStorage(&storage); cvReleaseImage(&bin); }
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; }
float mvContours::match_circle (IplImage* img, MvCircleVector* circle_vector, COLOR_TRIPLE color, int method) { assert (img != NULL); assert (img->nChannels == 1); int n_contours = find_contour_and_check_errors(img); if (n_contours < 1 || m_contours == NULL) return -1; bin_calc.start(); CvSeq* c_contour = m_contours; int n_circles = 0; // debug //mvWindow window("contours"); // examine each contour, put the passing ones into the circle_vector for (int C = 0; C < n_contours; C++, c_contour = c_contour->h_next) { // debug /*cvZero (img); draw_contours (c_contour, img); //window.showImage (img); cvWaitKey(0);*/ // check that there are at least 6 points if (c_contour->total < 6) { continue; } // check the contour's area to make sure it isnt too small double area = cvContourArea(c_contour); if (area < img->width*img->height/600) { DEBUG_PRINT ("Circle Fail: Contour too small!\n"); continue; } // do some kind of matching to ensure the contour is a circle CvMoments moments; cvContourMoments (c_contour, &moments); cv::Moments cvmoments(moments); double nu11 = cvmoments.nu11; double nu20 = cvmoments.nu02; double nu02 = cvmoments.nu20; double nu21 = cvmoments.nu21; double nu12 = cvmoments.nu12; double nu03 = cvmoments.nu03; double nu30 = cvmoments.nu30; double r03 = fabs(nu30 / nu03); r03 = (r03 > 1) ? r03 : 1.0/r03; double r12 = fabs(nu12 / nu21); r12 = (r12 > 1) ? r12 : 1.0/r12; double r02 = fabs(nu02 / nu20); r02 = (r02 > 1) ? r02 : 1.0/r02; double r11 = fabs( MEAN2(nu02,nu20) / nu11); double R = MEAN2(nu20,nu02) / std::max((MEAN2(nu21,nu12)), (MEAN2(nu30,nu03))); bool pass = true; pass = (r03 <= 25.0) && (r12 <= 12.0) && (r02 <= 12.0) && (r11 > 2.5) && (R > 25); if (!pass) { //DEBUG_PRINT ("Circle Moms: nu11=%lf, nu20=%lf, nu02=%lf, nu21=%lf, nu12=%lf, nu30=%lf, nu03=%lf\n", nu11, nu20, nu02, nu21, nu12, nu30, nu03); DEBUG_PRINT ("Circle Fail: \tn30/n03=%3.1lf, n21/n12=%3.1lf, nu20/nu02=%3.1lf, r11=%3.1f, R=%3.1f!\n", r03, r12, r02, r11, R); continue; } // get area and perimeter of the contour //double perimeter = cvArcLength (c_contour, CV_WHOLE_SEQ, 1); // get min enclosing circle and radius CvPoint2D32f centroid32f; float radius; cvMinEnclosingCircle(c_contour, ¢roid32f, &radius); if (radius > img->width/2 || radius < 0) { continue; } // do checks on area and perimeter double area_ratio = area / (CV_PI*radius*radius); //double perimeter_ratio = perimeter / (2*CV_PI*radius); if (area_ratio < 0.7) { DEBUG_PRINT ("Circle Fail: Area: %6.2lf\n", area_ratio); continue; } MvCircle circle; circle.center.x = static_cast<int>(centroid32f.x); circle.center.y = static_cast<int>(centroid32f.y); circle.radius = radius; circle.m1 = color.m1; circle.m2 = color.m2; circle.m3 = color.m3; assign_color_to_shape (color, &circle); circle.validity = area_ratio; circle_vector->push_back(circle); //cvCircle (img, cvPoint(x,y), static_cast<int>(radius), CV_RGB(50,50,50), 2); n_circles++; } bin_calc.stop(); return n_circles; }
void hand() { bool useavepalm = true; if(palm->total <= 2) { useavepalm = false; CvFont Font1=cvFont(3,3); cvPutText(frame,"Error Palm Position!!",cvPoint(10,50),&Font1,CV_RGB(255,0,0)); //savepic = true; CvPoint *temp,*additional,*palmtemp; CvMemStorage* palm2storage = cvCreateMemStorage(0); CvSeq* palm2 = cvCreateSeq(CV_SEQ_ELTYPE_POINT,sizeof(CvSeq),sizeof(CvPoint),palm2storage); for(int i=0;i<palm->total;i++) { palmtemp = (CvPoint*)cvGetSeqElem(palm,i); for(int j=1;j<contours->total;j++) { temp = (CvPoint*)cvGetSeqElem(contours,j); if(temp->y == palmtemp->y && temp->x == palmtemp->x) { additional = (CvPoint*)cvGetSeqElem(contours,(int)(j+((contours->total)/2))%(contours->total)); if(additional->y <= palmtemp->y) cvCircle(frame,*additional,10,CV_RGB(0,0,255),-1,8,0); cvSeqPush(palm2,additional); } } } for(int i=0;i<palm2->total;i++) { temp = (CvPoint*)cvGetSeqElem(palm2,i); cvSeqPush(palm,temp); } for(int i=1;i<contours->total;i++) { temp = (CvPoint*)cvGetSeqElem(contours,1); if(temp->y <= additional->y) additional = temp; } cvCircle(frame,*additional,10,CV_RGB(0,0,255),-1,8,0); cvSeqPush(palm,additional); } ////////////////////////////////////////////////////////////////////////////// cvMinEnclosingCircle(palm,&mincirclecenter,&radius); mincirclecenter2.x = cvRound(mincirclecenter.x); mincirclecenter2.y = cvRound(mincirclecenter.y); if(useavepalm){ CvPoint avePalmCenter,distemp; int lengthtemp,radius2; avePalmCenter.x = 0; avePalmCenter.y = 0; for(int i=0;i<palm->total;i++) { CvPoint *temp = (CvPoint*)cvGetSeqElem(palm,i); avePalmCenter.x += temp->x; avePalmCenter.y += temp->y; } avePalmCenter.x = (int)(avePalmCenter.x/palm->total); avePalmCenter.y = (int)(avePalmCenter.y/palm->total); radius2 = 0; for(int i=0;i<palm->total;i++) { CvPoint *temp = (CvPoint*)cvGetSeqElem(palm,i); distemp.x = temp->x - avePalmCenter.x; distemp.y = temp->y - avePalmCenter.y; lengthtemp = sqrtf(( distemp.x* distemp.x)+(distemp.y*distemp.y)); radius2 += lengthtemp; } radius2 = (int)(radius2/palm->total); radius = ((0.5)*radius + (0.5)*radius2); mincirclecenter2.x = ((0.5)*mincirclecenter2.x + (0.5)*avePalmCenter.x); mincirclecenter2.y = ((0.5)*mincirclecenter2.y + (0.5)*avePalmCenter.y); } ////////////////////////////////////////////////////////////////////////////////////// palmposition[palmpositioncount].x = cvRound(mincirclecenter2.x); palmposition[palmpositioncount].y = cvRound(mincirclecenter2.y); palmpositioncount = (palmpositioncount+1)%3; if(palmpositionfull) { float xtemp=0,ytemp=0; for(int i=0;i<3;i++) { xtemp += palmposition[i].x; ytemp += palmposition[i].y; } mincirclecenter2.x = cvRound(xtemp/3); mincirclecenter2.y = cvRound(ytemp/3); } if(palmpositioncount == 2 && palmpositionfull == false) { palmpositionfull = true; } cvCircle(frame,mincirclecenter2,10,CV_RGB(0,255,255),4,8,0); //cvCircle(virtualhand,mincirclecenter2,10,CV_RGB(0,255,255),4,8,0); ////////////////////////////////////////////////////////////////////////////////////// palmsize[palmsizecount] = cvRound(radius); palmsizecount = (palmsizecount+1)%3; if(palmcountfull) { float tempcount=0; for(int i=0;i<3;i++) { tempcount += palmsize[i]; } radius = tempcount/3; } if(palmsizecount == 2 && palmcountfull == false) { palmcountfull = true; } cvCircle(frame,mincirclecenter2,cvRound(radius),CV_RGB(255,0,0),2,8,0); cvCircle(frame,mincirclecenter2,cvRound(radius*1.2),CV_RGB(200,100,200),1,8,0); //cvCircle(virtualhand,mincirclecenter2,cvRound(radius),CV_RGB(255,0,0),2,8,0); //cvCircle(virtualhand,mincirclecenter2,cvRound(radius*1.3),CV_RGB(200,100,200),1,8,0); ////////////////////////////////////////////////////////////////////////////////////// int fingercount = 0; float fingerlength; CvPoint tiplength,*point; for(int i=0;i<fingerseq->total;i++) { point = (CvPoint*)cvGetSeqElem(fingerseq,i); tiplength.x = point->x - mincirclecenter2.x; tiplength.y = point->y - mincirclecenter2.y; fingerlength = sqrtf(( tiplength.x* tiplength.x)+(tiplength.y*tiplength.y)); if((int)fingerlength > cvRound(radius*1.2)) { fingercount += 1; cvCircle(frame,*point,6,CV_RGB(0,255,0),-1,8,0); } } cvClearSeq(fingerseq); cvClearSeq(palm); }