OpenCV学习起步姚言惑众.docx
- 文档编号:10407927
- 上传时间:2023-02-11
- 格式:DOCX
- 页数:11
- 大小:19.47KB
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;i { 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
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OpenCV 学习 起步 惑众