您的位置:首页 > 运维架构

opencv 检测直线、圆、矩形

2009-12-01 09:26 543 查看
检测直线:cvHoughLines,cvHoughLines2

检测圆:cvHoughCircles

检测矩形:opencv中没有对应的函数,下面有段代码可以检测矩形,是通过先找直线,然后找到直线平行与垂直的四根线。

检测直线代码:

/*Thisisastandaloneprogram.Passanimagenameasafirstparameteroftheprogram.

SwitchbetweenstandardandprobabilisticHoughtransformbychanging"#if1"to"#if0"andback*/

#include<cv.h>

#include<highgui.h>

#include<math.h>

intmain(intargc,char**argv)

{

constchar*filename=argc>=2?argv[1]:"pic1.png";

IplImage*src=cvLoadImage(filename,0);

IplImage*dst;

IplImage*color_dst;

CvMemStorage*storage=cvCreateMemStorage(0);

CvSeq*lines=0;

inti;

if(!src)

return-1;

dst=cvCreateImage(cvGetSize(src),8,1);

color_dst=cvCreateImage(cvGetSize(src),8,3);

cvCanny(src,dst,50,200,3);

cvCvtColor(dst,color_dst,CV_GRAY2BGR);

#if0

lines=cvHoughLines2(dst,storage,CV_HOUGH_STANDARD,1,CV_PI/180,100,0,0);

for(i=0;i<MIN(lines->total,100);i++)

{

float*line=(float*)cvGetSeqElem(lines,i);

floatrho=line[0];

floattheta=line[1];

CvPointpt1,pt2;

doublea=cos(theta),b=sin(theta);

doublex0=a*rho,y0=b*rho;

pt1.x=cvRound(x0+1000*(-b));

pt1.y=cvRound(y0+1000*(a));

pt2.x=cvRound(x0-1000*(-b));

pt2.y=cvRound(y0-1000*(a));

cvLine(color_dst,pt1,pt2,CV_RGB(255,0,0),3,CV_AA,0);

}

#else

lines=cvHoughLines2(dst,storage,CV_HOUGH_PROBABILISTIC,1,CV_PI/180,50,50,10);

for(i=0;i<lines->total;i++)

{

CvPoint*line=(CvPoint*)cvGetSeqElem(lines,i);

cvLine(color_dst,line[0],line[1],CV_RGB(255,0,0),3,CV_AA,0);

}

#endif

cvNamedWindow("Source",1);

cvShowImage("Source",src);

cvNamedWindow("Hough",1);

cvShowImage("Hough",color_dst);

cvWaitKey(0);

return0;

}

检测圆代码:

#include<cv.h>

#include<highgui.h>

#include<math.h>

intmain(intargc,char**argv)

{

IplImage*img;

if(argc==2&&(img=cvLoadImage(argv[1],1))!=0)

{

IplImage*gray=cvCreateImage(cvGetSize(img),8,1);

CvMemStorage*storage=cvCreateMemStorage(0);

cvCvtColor(img,gray,CV_BGR2GRAY);

cvSmooth(gray,gray,CV_GAUSSIAN,9,9);//smoothit,otherwisealotoffalsecirclesmaybedetected

CvSeq*circles=cvHoughCircles(gray,storage,CV_HOUGH_GRADIENT,2,gray->height/4,200,100);

inti;

for(i=0;i<circles->total;i++)

{

float*p=(float*)cvGetSeqElem(circles,i);

cvCircle(img,cvPoint(cvRound(p[0]),cvRound(p[1])),3,CV_RGB(0,255,0),-1,8,0);

cvCircle(img,cvPoint(cvRound(p[0]),cvRound(p[1])),cvRound(p[2]),CV_RGB(255,0,0),3,8,0);

}

cvNamedWindow("circles",1);

cvShowImage("circles",img);

}

return0;

}

检测矩形代码:

/*

在程序里找寻矩形

*/

#ifdef_CH_

#pragmapackage<opencv>

#endif


#ifndef_EiC

#include"cv.h"

#include"highgui.h"

#include<stdio.h>

#include<math.h>

#include<string.h>

#endif


intthresh=50;

IplImage*img=0;

IplImage*img0=0;

CvMemStorage*storage=0;

CvPointpt[4];

constchar*wndname="SquareDetectionDemo";


//helperfunction:

//findsacosineofanglebetweenvectors

//frompt0->pt1andfrompt0->pt2

doubleangle(CvPoint*pt1,CvPoint*pt2,CvPoint*pt0)

{

doubledx1=pt1->x-pt0->x;

doubledy1=pt1->y-pt0->y;

doubledx2=pt2->x-pt0->x;

doubledy2=pt2->y-pt0->y;

return(dx1*dx2+dy1*dy2)/sqrt((dx1*dx1+dy1*dy1)*(dx2*dx2+dy2*dy2)+1e-10);

}


//returnssequenceofsquaresdetectedontheimage.

//thesequenceisstoredinthespecifiedmemorystorage

CvSeq*findSquares4(IplImage*img,CvMemStorage*storage)

{

CvSeq*contours;

inti,c,l,N=11;

CvSizesz=cvSize(img->width&-2,img->height&-2);

IplImage*timg=cvCloneImage(img);//makeacopyofinputimage

IplImage*gray=cvCreateImage(sz,8,1);

IplImage*pyr=cvCreateImage(cvSize(sz.width/2,sz.height/2),8,3);

IplImage*tgray;

CvSeq*result;

doubles,t;

//createemptysequencethatwillcontainpoints-

//4pointspersquare(thesquare'svertices)

CvSeq*squares=cvCreateSeq(0,sizeof(CvSeq),sizeof(CvPoint),storage);


//selectthemaximumROIintheimage

//withthewidthandheightdivisibleby2

cvSetImageROI(timg,cvRect(0,0,sz.width,sz.height));


//down-scaleandupscaletheimagetofilteroutthenoise

cvPyrDown(timg,pyr,7);

cvPyrUp(pyr,timg,7);

tgray=cvCreateImage(sz,8,1);


//findsquaresineverycolorplaneoftheimage

for(c=0;c<3;c++)

{

//extractthec-thcolorplane

cvSetImageCOI(timg,c+1);

cvCopy(timg,tgray,0);


//tryseveralthresholdlevels

for(l=0;l<N;l++)

{

//hack:useCannyinsteadofzerothresholdlevel.

//Cannyhelpstocatchsquareswithgradientshading

if(l==0)

{

//applyCanny.Taketheupperthresholdfromslider

//andsetthelowerto0(whichforcesedgesmerging)

cvCanny(tgray,gray,0,thresh,5);

//dilatecannyoutputtoremovepotential

//holesbetweenedgesegments

cvDilate(gray,gray,0,1);

}

else

{

//applythresholdifl!=0:

//tgray(x,y)=gray(x,y)<(l+1)*255/N?255:0

cvThreshold(tgray,gray,(l+1)*255/N,255,CV_THRESH_BINARY);

}


//findcontoursandstorethemallasalist

cvFindContours(gray,storage,&contours,sizeof(CvContour),

CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));


//testeachcontour

while(contours)

{

//approximatecontourwithaccuracyproportional

//tothecontourperimeter

result=cvApproxPoly(contours,sizeof(CvContour),storage,

CV_POLY_APPROX_DP,cvContourPerimeter(contours)*0.02,0);

//squarecontoursshouldhave4verticesafterapproximation

//relativelylargearea(tofilteroutnoisycontours)

//andbeconvex.

//Note:absolutevalueofanareaisusedbecause

//areamaybepositiveornegative-inaccordancewiththe

//contourorientation

if(result->total==4&&

fabs(cvContourArea(result,CV_WHOLE_SEQ))>1000&&

cvCheckContourConvexity(result))

{

s=0;


for(i=0;i<5;i++)

{

//findminimumanglebetweenjoint

//edges(maximumofcosine)

if(i>=2)

{

t=fabs(angle(

(CvPoint*)cvGetSeqElem(result,i),

(CvPoint*)cvGetSeqElem(result,i-2),

(CvPoint*)cvGetSeqElem(result,i-1)));

s=s>t?s:t;

}

}


//ifcosinesofallanglesaresmall

//(allanglesare~90degree)thenwritequandrange

//verticestoresultantsequence

if(s<0.3)

for(i=0;i<4;i++)

cvSeqPush(squares,

(CvPoint*)cvGetSeqElem(result,i));

}


//takethenextcontour

contours=contours->h_next;

}

}

}


//releaseallthetemporaryimages

cvReleaseImage(&gray);

cvReleaseImage(&pyr);

cvReleaseImage(&tgray);

cvReleaseImage(&timg);


returnsquares;

}



//thefunctiondrawsallthesquaresintheimage

voiddrawSquares(IplImage*img,CvSeq*squares)

{

CvSeqReaderreader;

IplImage*cpy=cvCloneImage(img);

inti;


//initializereaderofthesequence

cvStartReadSeq(squares,&reader,0);


//read4sequenceelementsatatime(allverticesofasquare)

for(i=0;i<squares->total;i+=4)

{

CvPoint*rect=pt;

intcount=4;


//read4vertices

memcpy(pt,reader.ptr,squares->elem_size);

CV_NEXT_SEQ_ELEM(squares->elem_size,reader);

memcpy(pt+1,reader.ptr,squares->elem_size);

CV_NEXT_SEQ_ELEM(squares->elem_size,reader);

memcpy(pt+2,reader.ptr,squares->elem_size);

CV_NEXT_SEQ_ELEM(squares->elem_size,reader);

memcpy(pt+3,reader.ptr,squares->elem_size);

CV_NEXT_SEQ_ELEM(squares->elem_size,reader);


//drawthesquareasaclosedpolyline

cvPolyLine(cpy,&rect,&count,1,1,CV_RGB(0,255,0),3,CV_AA,0);

}


//showtheresultantimage

cvShowImage(wndname,cpy);

cvReleaseImage(&cpy);

}



voidon_trackbar(inta)

{

if(img)

drawSquares(img,findSquares4(img,storage));

}


char*names[]={"pic1.png","pic2.png","pic3.png",

"pic4.png","pic5.png","pic6.png",0};


intmain(intargc,char**argv)

{

inti,c;

//creatememorystoragethatwillcontainallthedynamicdata

storage=cvCreateMemStorage(0);


for(i=0;names[i]!=0;i++)

{

//loadi-thimage

img0=cvLoadImage(names[i],1);

if(!img0)

{

printf("Couldn'tload%s/n",names[i]);

continue;

}

img=cvCloneImage(img0);


//createwindowandatrackbar(slider)withparent"image"andsetcallback

//(thesliderregulatesupperthreshold,passedtoCannyedgedetector)

cvNamedWindow(wndname,1);

cvCreateTrackbar("cannythresh",wndname,&thresh,1000,on_trackbar);


//forcetheimageprocessing

on_trackbar(0);

//waitforkey.

//AlsothefunctioncvWaitKeytakescareofeventprocessing

c=cvWaitKey(0);

//releasebothimages

cvReleaseImage(&img);

cvReleaseImage(&img0);

//clearmemorystorage-resetfreespaceposition

cvClearMemStorage(storage);

if(c==27)

break;

}


cvDestroyWindow(wndname);


return0;

}


#ifdef_EiC

main(1,"squares.c");

#endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: