OpenCV学习起步姚言惑众.docx
《OpenCV学习起步姚言惑众.docx》由会员分享,可在线阅读,更多相关《OpenCV学习起步姚言惑众.docx(11页珍藏版)》请在冰豆网上搜索。
OpenCV学习起步姚言惑众
OpenCV学习起步_“姚”言惑众
使用库的技术问题
怎么访问图像像素
(坐标是从0开始的,并且是相对图像原点的位置。
图像原点或者是左上角(img->origin=IPL_ORIGIN_TL)或者是左下角(img->origin=IPL_ORIGIN_BL))
假设有8-bit1-通道的图像I(IplImage*img):
I(x,y)~((uchar*)(img->imageData+img->widthStep*y))[x]
假设有8-bit3-通道的图像I(IplImage*img):
I(x,y)blue~((uchar*)(img->imageData+img->widthStep*y))[x*3]
I(x,y)green~((uchar*)(img->imageData+img->widthStep*y))[x*3+1]
I(x,y)red~((uchar*)(img->imageData+img->widthStep*y))[x*3+2]
例如,给点(100,100)的亮度增加30,那么可以这样做:
CvPointpt={100,100};
((uchar*)(img->imageData+img->widthStep*pt.y))[pt.x*3]+=30;
((uchar*)(img->imageData+img->widthStep*pt.y))[pt.x*3+1]+=30;
((uchar*)(img->imageData+img->widthStep*pt.y))[pt.x*3+2]+=30;
或者更高效地:
CvPointpt={100,100};
uchar*temp_ptr=&((uchar*)(img->imageData+img->widthStep*pt.y))[pt.x*3];
temp_ptr[0]+=30;
temp_ptr[1]+=30;
temp_ptr[2]+=30;
假设有32-bit浮点数,1-通道图像I(IplImage*img):
I(x,y)~((float*)(img->imageData+img->widthStep*y))[x]
现在,一般的情况下,假设有N-通道,类型为T的图像:
I(x,y)c~((T*)(img->imageData+img->widthStep*y))[x*N+c]
你可以使用宏CV_IMAGE_ELEM(image_header,elemtype,y,x_Nc)
I(x,y)c~CV_IMAGE_ELEM(img,T,y,x*N+c)
也有针对各种图像(包括4通道图像)和矩阵的函数(cvGet2D,cvSet2D),但是它们非常慢。
如何访问矩阵元素?
方法是类似的(下面的例子都是针对0起点的列和行)
设有32-bit浮点数的实数矩阵M(CvMat*mat):
M(i,j)~((float*)(mat->data.ptr+mat->step*i))[j]
设有64-bit浮点数的复数矩阵M(CvMat*mat):
ReM(i,j)~((double*)(mat->data.ptr+mat->step*i))[j*2]
ImM(i,j)~((double*)(mat->data.ptr+mat->step*i))[j*2+1]
对单通道矩阵,有宏CV_MAT_ELEM(matrix,elemtype,row,col),例如对32-bit浮点数的实数矩阵:
M(i,j)~CV_MAT_ELEM(mat,float,i,j),
例如,这儿是一个3x3单位矩阵的初始化:
CV_MAT_ELEM(mat,float,0,0)=1.f;
CV_MAT_ELEM(mat,float,0,1)=0.f;
CV_MAT_ELEM(mat,float,0,2)=0.f;
CV_MAT_ELEM(mat,float,1,0)=0.f;
CV_MAT_ELEM(mat,float,1,1)=1.f;
CV_MAT_ELEM(mat,float,1,2)=0.f;
CV_MAT_ELEM(mat,float,2,0)=0.f;
CV_MAT_ELEM(mat,float,2,1)=0.f;
CV_MAT_ELEM(mat,float,2,2)=1.f;
如何在OpenCV中处理我自己的数据
设你有300x20032-bit浮点数image/array,也就是对一个有60000个元素的数组。
intcols=300,rows=200;
float*myarr=newfloat[rows*cols];
//第一步,初始化CvMat头
CvMatmat=cvMat(rows,cols,
CV_32FC1,//32位浮点单通道类型
myarr//用户数据指针(数据没有被复制)
);
//第二步,使用cv函数,例如计算l2(Frobenius)模
doublenorm=cvNorm(&mat,0,CV_L2);
...
deletemyarr;
其它情况在参考手册中有描述。
见cvCreateMatHeader,cvInitMatHeader,cvCreateImageHeader,cvSetData等
如何读入和显示图像
/*usage:
prog*/
#include"cv.h"
#include"highgui.h"
intmain(intargc,char**argv)
{
IplImage*img;
if(argc==2&&(img=cvLoadImage(argv[1],1))!
=0)
{
cvNamedWindow("Imageview",1);
cvShowImage("Imageview",img);
cvWaitKey(0);//非常重要,内部包含事件处理循环
cvDestroyWindow("Imageview");
cvReleaseImage(&img);
return0;
}
return-1;
}
如何检测和处理轮廓线
参考squaresdemo
/*
在程序里找寻矩形
*/
#ifdef_CH_
#pragmapackage
#endif
#ifndef_EiC
#include"cv.h"
#include"highgui.h"
#include
#include
#include
#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{
//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;itotal;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来定标摄像机
可以使用\OpenCV\samples\c目录下的calibration.cpp这个程序,程序的输入支持USB摄像机,avi文件或者图片
1。
使用说明
a.输入为图片时:
//examplecommandline(forcopy-n-paste):
//calibration-w6-h8-s2-n10-ocamera.yml-op-oe[]
/*Thelistofviewsmaylookasfollowing(discardthestartingandending------separators):
-------------------
view000.png
view001.png
#view002.png
view003.png
view010.png
one_extra_view.jpg
-------------------
thatis,thefilewillcontain6lines,view002.pngwillnotbeusedforcalibration,
otheroneswillbe(those,inwhichthechessboardpatternwillbefound)
b.输入为摄像机或者avi文件时
"Whenthelivevideofromcameraisusedasinput,thefollowinghot-keysmaybeused:
\n"
",'q'-quittheprogram\n"
"'g'-startcapturingimages\n"
"'u'-sw