2011-03-30 61 views
7

我想使用OpenCV在網絡攝像機屏幕上繪製/繪製圖像。由於我是從凸輪讀取的,所以這些幀不斷變化,所以我試圖找出一種方法來保存或保存當前幀上的圖形,並將其用於下一幀。下面的代碼允許你在屏幕上繪圖,但是當它到達下一幀時,繪圖消失並重新開始。使用OpenCV在網絡攝像機上繪圖

有人可以幫助我...謝謝。

  CvCapture *input; 
      input = cvCaptureFromCAM(0); 

      cvSetMouseCallback("Demo",&on_mouse, 0); 

       for(;;) 
        { 
         frame = cvQueryFrame(input); 

         if(!image) 
         { 
          image = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 3); 
          screenBuffer = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 3); 
         } 

         cvCopy(frame, image, 0); 

         if(drawing) //drawing is a global variable 
         { 
          cvCircle(image, cvPoint(last_x,last_y), 10,CV_RGB(red,green,blue), -1, CV_AA, 0); 
          cvCopy(image, screenBuffer, 0); 
         } 

         cvShowImage("Demo", screenBuffer); 
       } 


     void on_mouse(int event, int x, int y, int flags, void* param) 
     { 
      last_x = x; 
      last_y = y; 

      if(event==CV_EVENT_LBUTTONDOWN) 
       { 
        drawing = 1; 
       } 
     } 
+0

與我的興趣有關。你能在這裏發表評論嗎?你在使用什麼文檔/教程?我想在OpenCV中獲得自己的開始。謝謝 – sdadffdfd 2011-03-30 19:23:28

+0

對於我們來說,重新審視問題並接受解決問題的答案非常重要。 – karlphillip 2011-03-31 14:30:46

回答

2

立即dispalying它

0

您通常會添加圖像(他們將最終達到飽和)的問題之前繪製成一個單獨的圖像,然後cvAdd()的視頻圖像,所以我想這就是爲什麼你重新開始。我看到你有彩色圖像......如果你使用像OpenGL這樣更強大的東西來繪製圖畫,你可以使用疊加圖來繪製圖畫。否則,檢查了這一點:

http://aishack.in/tutorials/transparent-image-overlays-in-opencv/

1

我不會進入所有的細節,爲什麼你的做法是不好的,但請記住,對於繪圖創建2個額外的幀是有點太多了。

重要的是,您意識到所有這些淫事正在用於捕獲新幀的相同線程上完成。這意味着什麼?這意味着您在循環內添加的額外代碼將減慢捕獲和顯示新幀的過程。換句話說,你正在通過降低應用程序的幀率來破壞自己。如果你不在乎,沒關係。如果你這樣做,我的提示是你將捕獲的幀堆疊到一個緩衝區中,並讓另一個線程讀取,處理並顯示它們。

好的,所以你REALLY想繪製顯示捕獲幀的窗口。那麼,明顯的事情你不能做(你自己也發現了這個)是因爲在每個循環中它被替換爲新數據的幀不能在捕獲的幀上進行繪製。所以你會怎麼做?您創建第二個框架來完成繪圖。我們稱之爲drawing_frame

drawing_frame唯一會出現的情況是,當鼠標移動到窗口上時,鼠標的LBUTTON被點擊(第二次點擊在ON/OFF之間切換)時將出現這些圓圈。

圓的繪製發生後,drawing_frame被覆蓋在頂部由照相機捕獲的框架上。這個過程在CPU上有點貴,而且由於我們在應用程序的主線程中這樣做,它也會降低幀率。

我強烈建議大家感興趣的添加/合併/覆蓋與OpenCV的透明幀看一看Transparent image overlays in OpenCV。我使用的是cvCaptureFromCAM(-1),因爲我在Linux上。你可能應該改變爲適合你的任何東西。根據你的帖子,它的cvCaptureFromCAM(0)

#include <stdio.h> 

#include <cv.h> 
#include <highgui.h> 

int drawing = 0; 
int last_x = 0; 
int last_y = 0; 


void on_mouse(int event, int x, int y, int flags, void* param) 
{ 
    last_x = x; 
    last_y = y; 

    if (event == CV_EVENT_LBUTTONDOWN) 
    { 
     // switches between On and Off 
     if (drawing) 
      drawing = 0; 
     else 
      drawing = 1; 
    } 
} 


int main() 
{ 
    CvCapture* capture = NULL; 
    if ((capture = cvCaptureFromCAM(-1)) == NULL) 
    { 
     fprintf(stderr, "ERROR: capture is NULL \n"); 
     return -1; 
    } 

    cvNamedWindow("mywindow", CV_WINDOW_AUTOSIZE); 

    cvQueryFrame(capture); // Sometimes needed to get correct data 

    cvSetMouseCallback("mywindow",&on_mouse, 0); 

    IplImage* frame = NULL; 
    IplImage* drawing_frame = NULL; 
    while (1) 
    { 
     if ((frame = cvQueryFrame(capture)) == NULL) 
     { 
      fprintf(stderr, "ERROR: cvQueryFrame failed\n"); 
      break; 
     } 

     if (frame == NULL) 
     { 
      fprintf(stderr, "WARNING: cvQueryFrame returned NULL, sleeping..\n"); 
      usleep(100000); 
      continue; 
     } 

     if (!drawing_frame) // This frame is created only once 
     { 
      drawing_frame = cvCreateImage(cvSize(frame->width, frame->height), frame->depth, frame->nChannels); 
      cvZero(drawing_frame); 
     } 

     if (drawing) 
     { 
      cvCircle(drawing_frame, cvPoint(last_x,last_y), 10,CV_RGB(0, 255, 0), -1, CV_AA, 0); 

      // For overlaying (copying transparent images) in OpenCV 
      // http://www.aishack.in/2010/07/transparent-image-overlays-in-opencv/ 
      for (int x = 0; x < frame->width; x++) 
      { 
       for (int y = 0; y < frame->height; y++) 
       { 
        CvScalar source = cvGet2D(frame, y, x); 
        CvScalar over = cvGet2D(drawing_frame, y, x); 

        CvScalar merged; 
        CvScalar S = { 1,1,1,1 }; 
        CvScalar D = { 1,1,1,1 }; 

        for(int i = 0; i < 4; i++) 
         merged.val[i] = (S.val[i] * source.val[i] + D.val[i] * over.val[i]); 

        cvSet2D(frame, y, x, merged); 
       } 
      } 
     } 

     cvShowImage("mywindow", frame); 

     int key = cvWaitKey(10); 
     if (key == 113) // q was pressed on the keyboard 
      break; 
    } 

    cvReleaseImage(&frame); 
    cvReleaseImage(&drawing_frame); 
    cvReleaseCapture(&capture); 
    cvDestroyWindow("mywindow"); 

    return 0; 
} 
+0

@Aziz請查看答案並接受解決問題的答案。 – karlphillip 2011-04-19 03:25:10

相關問題