opencv學習筆記

來源:互聯網
上載者:User

1、視窗管理

//建立和定位新視窗
cvNamedWindow("win1", CV_WINDOW_AUTOSIZE); 
cvMoveWindow("win1", 100, 100); // offset from the UL corner of the screen

//載入映像
IplImage* img=0; 
img=cvLoadImage(fileName, CV_LOAD_IMAGE_COLOR);
if(!img) 
printf("Could not load image file: %s\n",fileName);

//顯示映像
cvShowImage("win1",img);

//關閉視窗
cvDestroyWindow("win1");

//改變視窗大小
cvResizeWindow("win1",100,100); // new width/heigh in pixels

2、輸入處理處理滑鼠事件

//先定義滑鼠處理常式
//x,y相對於左上方的像素座標
void mouseHandler(int event, int x, int y, int flags, void* param)
 {
    switch(event)
{
      case CV_EVENT_LBUTTONDOWN:
        if(flags & CV_EVENT_FLAG_CTRLKEY) 
          printf("Left button down with CTRL pressed\n");
        break; 
 
      case CV_EVENT_LBUTTONUP:
        printf("Left button up\n");
        break;
    }
 }
 //再註冊該事件處理常式
 mouseParam=5;
 cvSetMouseCallback("win1",mouseHandler,&mouseParam);  //第三個參數可以設定為NULL
 
 
 處理鍵盤事件

 
 //按一定間隔檢測鍵盤輸入
 int key;
 key=cvWaitKey(10); // wait 10ms for input
 
 //中止程式等待鍵盤輸入
 int key;
 key=cvWaitKey(0); // wait indefinitely for input
 
 //鍵盤輸入迴圈處理常式
 while(1)
 {
    key=cvWaitKey(10);
    if(key==27) break; 
 
    switch(key)
{
      case 'h':
        ...
        break;
      case 'i':
        ...
        break;
    }
 }
 
 處理滑動條事件

 
 //定義一個滑動條處理常式
 void trackbarHandler(int pos)
 {
    printf("Trackbar position: %d\n",pos);
 }
 
 //註冊該事件處理常式
 int trackbarVal=25;
 int maxVal=100;
 cvCreateTrackbar("bar1", "win1", &trackbarVal ,maxVal , trackbarHandler);
 
 //擷取當前的滑動條位置
 int pos = cvGetTrackbarPos("bar1","win1");
 
 //設定滑動條位置
 cvSetTrackbarPos("bar1", "win1", 25);
 
 3、影像處理

 
 映像的記憶體配置與釋放

 
 //分配記憶體給一幅新映像
 //size:cvSize(width,height);depth: 像素深度;channels: 像素通道數. Can be 1, 2, 3 or 4.
 IplImage* cvCreateImage(CvSize size, int depth, int channels);
 
// Allocate a 1-channel byte image
IplImage* img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); 
 
// Allocate a 3-channel float image
IplImage* img2=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);

//釋放映像
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); 
cvReleaseImage(&img);

//複製映像
IplImage* img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); 
IplImage* img2;
img2=cvCloneImage(img1);  // 注意通過cvCloneImage得到的映像
 // 也要用 cvReleaseImage 釋放,否則容易產生記憶體流失
 
//設定/擷取感興趣地區ROI
void  cvSetImageROI(IplImage* image, CvRect rect);
void  cvResetImageROI(IplImage* image);
CvRect cvGetImageROI(const IplImage* image);

// 設定/擷取感興趣通道COI
void cvSetImageCOI(IplImage* image, int coi); // 0=all
int cvGetImageCOI(const IplImage* image);

映像讀寫

//從檔案中讀入映像
//OpenCV預設將讀入的映像強制轉換為一幅三通道彩色映像
IplImage* img=0; 
img=cvLoadImage(fileName);
if(!img) 
printf("Could not load image file: %s\n",fileName);  

img=cvLoadImage(fileName,flag);
// flag: >0 將讀入的映像強制轉換為一幅三通道彩色映像
//       =0 將讀入的映像強制轉換為一幅單通道灰階映像
//       <0 讀入的映像通道數與所讀入的檔案相同.

//儲存映像
if(!cvSaveImage(outFileName,img)) 
printf("Could not save: %s\n", outFileName);

訪問映像像素

間接訪問,效率低
//對於單通道位元組型映像
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
CvScalar s;
s=cvGet2D(img,i,j); // get the (j,i) pixel value, 注意cvGet2D與cvSet2D中座標參數的順序與其它opencv函數座標參數順序恰好相反.本函數中i代表y軸,即height;j代表x軸,即weight.
printf("intensity=%f\n",s.val[0]);
s.val[0]=111;
cvSet2D(img,i,j,s); // set the (j,i) pixel value

//對於多通道位元組型/浮點型映像
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
CvScalar s;
s=cvGet2D(img,i,j); // get the (j,i) pixel value
printf("B=%f, G=%f, R=%f\n",s.val[0],s.val[1],s.val[2]);
s.val[0]=111;
s.val[1]=111;
s.val[2]=111;
cvSet2D(img,i,j,s); // set the (j,i) pixel value

直接存取,效率高
//對於單通道位元組型映像
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
((uchar *)(img->imageData + i*img->widthStep))[j]=111;

//對於多通道位元組型映像
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B
((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G
((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R

//對於多通道浮點型映像
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R

基於指標的直接存取

//對於單通道位元組型映像
IplImage* img  = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
int height     = img->height;
int width      = img->width;
int step       = img->widthStep;
uchar* data    = (uchar *)img->imageData;
data[i*step+j] = 111;

//對於多通道位元組型映像
IplImage* img  = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
int height     = img->height;
int width      = img->width;
int step       = img->widthStep;
int channels   = img->nChannels;
uchar* data    = (uchar *)img->imageData;
data[i*step+j*channels+k] = 111;

映像轉換

//位元組型映像的灰階-彩色轉換:
cvConvertImage(src, dst, flags=0);
src = float/byte grayscale/color image
dst = byte grayscale/color image
flags = CV_CVTIMG_FLIP     (垂直翻轉映像)
        CV_CVTIMG_SWAP_RB  (置換 R 和 B 通道)

//彩色映像->灰階映像:
// Using the OpenCV conversion: 
cvCvtColor(cimg,gimg,CV_BGR2GRAY); // cimg -> gimg 
 
// Using a direct conversion: 
for(i=0;i<cimg->height;i++) for(j=0;j<cimg->width;j++) 
  gimgA[i][j]= (uchar)(cimgA[i][j].b*0.114 + 
                       cimgA[i][j].g*0.587 + 
                       cimgA[i][j].r*0.299);
  
//不同彩色空間之間的轉換:
cvCvtColor(src,dst,code); // src -> dst
 code    = CV_<X>2<Y>
 <X>/<Y> = RGB, BGR, GRAY, HSV, YCrCb, XYZ, Lab, Luv, HLS 
 
 繪圖指令
 //繪製矩形:
// 在點 (100,100) 和 (200,200) 之間繪製一矩形,邊線用紅色、寬度為 1
cvRectangle(img, cvPoint(100,100), cvPoint(200,200), cvScalar(0,0,255), 1);

//繪製圓形:
// 圓心為(100,100)、半徑為20. 圓周綠色、寬度為1
cvCircle(img, cvPoint(100,100), 20, cvScalar(0,255,0), 1);

//繪製線段:
// 在 (100,100) 和 (200,200) 之間、線寬為 1 的綠色線段
cvLine(img, cvPoint(100,100), cvPoint(200,200), cvScalar(0,255,0), 1);

//繪製一組線段:
CvPoint  curve1[]={10,10,  10,100,  100,100,  100,10};
CvPoint  curve2[]={30,30,  30,130,  130,130,  130,30,  150,10};
CvPoint* curveArr[2]={curve1, curve2};
int      nCurvePts[2]={4,5};
int      nCurves=2;
int      isCurveClosed=1;
int      lineWidth=1; 
 
cvPolyLine(img,curveArr,nCurvePts,nCurves,isCurveClosed,cvScalar(0,255,255),lineWidth);
 
void cvPolyLine( CvArr* img, CvPoint** pts, int* npts, int contours, int is_closed,
                          CvScalar color, int thickness=1, int line_type=8, int shift=0 );
//img       映像。 
//pts       折線的頂點指標數組。 
//npts     折線的定點個數數組。也可以認為是pts指標數組的大小 
//contours   折線的線段數量。 
//is_closed  指出多邊形是否封閉。如果封閉,函數將起始點和結束點連線。 
//color         折線的顏色。 
//thickness  線條的粗細程度。 
//line_type  線段的類型。參見cvLine。 
//shift          頂點的小數點位元

//繪製一組填充顏色的多邊形:
cvFillPoly(img,curveArr,nCurvePts,nCurves,cvScalar(0,255,255));
 
//cvFillPoly用於一個單獨被多邊形輪廓所限定的地區內進行填充。函數可以填充複雜的地區,例如,有漏洞的地區和有交叉點的地區等等。
void cvFillPoly( CvArr* img, CvPoint** pts, int* npts, int contours,CvScalar color, int line_type=8, int shift=0 );
//img           映像。 
//pts           指向多邊形的數組指標。 
//npts         多邊形的頂點個數的數組。 
//contours   組成填充地區的線段的數量。 
//color         多邊形的顏色。 
//line_type  組成多邊形的線條的類型。 
//shift          頂點座標的小數點位元。

//文本標註:
CvFont font;
double hScale=1.0;
double vScale=1.0;
int    lineWidth=1;
cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, hScale,vScale,0,lineWidth); 
 
cvPutText (img,"My comment",cvPoint(200,400), &font, cvScalar(255,255,0));

4、視頻處理

//初始化一個相機擷取器:
CvCapture* capture = cvCaptureFromCAM(0); // capture from video device #0

//初始化一個視頻檔案捕捉器:
CvCapture* capture = cvCaptureFromAVI("infile.avi");

//捕捉一幀畫面:
IplImage* img = 0; 
if(!cvGrabFrame(capture)) // capture a frame 
{             
  printf("Could not grab a frame\n\7");
  exit(0);
}
img=cvRetrieveFrame(capture);           // retrieve the captured frame

//釋放視頻流捕捉器:
cvReleaseCapture(&capture);

//擷取視頻流裝置資訊:
cvQueryFrame(capture); // 在讀取視頻流資訊前,要先執行此操作
int frameH    = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
int frameW    = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
int fps       = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
int numFrames = (int) cvGetCaptureProperty(capture,  CV_CAP_PROP_FRAME_COUNT);

//擷取幀圖資訊:
float posMsec   =       cvGetCaptureProperty(capture, CV_CAP_PROP_POS_MSEC);
int posFrames   = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES);
float posRatio  =       cvGetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO);

//設定從視頻檔案抓取的第一幀畫面的位置:
// start capturing from a relative position of 0.9 of a video file
cvSetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO, (double)0.9);

//初始化視頻編寫器:
CvVideoWriter *writer = 0;
int isColor = 1;
int fps     = 25;  // or 30
int frameW  = 640; // 744 for firewire cameras
int frameH  = 480; // 480 for firewire cameras
writer=cvCreateVideoWriter("out.avi",CV_FOURCC('P','I','M','1'),
                           fps,cvSize(frameW,frameH),isColor);
  
//保持視頻檔案:
IplImage* img = 0; 
int nFrames = 50;
for(i=0;i<nFrames;i++){
  cvGrabFrame(capture);          // capture a frame
  img=cvRetrieveFrame(capture);  // retrieve the captured frame
  // img = cvQueryFrame(capture);
  cvWriteFrame(writer,img);      // add the frame to the file
}

//釋放視頻編寫器:
cvReleaseVideoWriter(&writer);    

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.