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;
}
检测矩形代码:
检测圆: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
相关文章推荐
- opencv 检测直线、圆、矩形
- ios--OpenCV--检测直线、圆、矩形
- opencv 检测直线、圆、矩形
- opencv 检测直线、圆、矩形
- opencv --检测直线、圆、矩形
- 【OpenCV】opencv 检测直线、圆、矩形
- OpenCV--- 检测直线、圆、矩形
- opencv检测直线,圆,矩形
- opencv 检测直线、线段、圆、矩形
- opencv 检测直线、线段、圆、矩形
- opencv 检测直线、线段、圆、矩形
- 利用opencv检测出矩形1
- 我的OpenCV学习笔记(19):检测轮廓,直线,圆以及直线拟合
- OpenCV自学笔记27. Hough变换:检测直线和圆
- Java+opencv3.2.0实现hough直线检测
- OpenCV 第六章 Hough 直线检测、圆检测
- Opencv--cvHoughLines2霍夫函数检测直线
- 矩形框绘制_运动检测_OpenCV
- Opencv图像识别从零到精通(22)-----hough变换检测直线与圆
- opencv 霍夫变换检测直线