2014-08-27 14 views
0

我想在網絡攝像機畫面中的Opencv中使用鼠標事件繪製一條線。我也想擦掉它,就像MS-Paint中的橡皮擦一樣。我該怎麼辦?我對此沒有太多的想法。但是我從頭腦中搜索到了這個可能完全錯誤的pseduo代碼,但我仍然會把它寫下來。我想知道如何在C++中實現它。 因此,我將有兩個三鼠標事件 - 事件1-鼠標左鍵按鈕 - 這將用於開始繪圖 事件2-鼠標移動 - 這將用於移動鼠標繪製 事件3: - 鼠標左鍵按下 - 這將用於停止繪圖。 事件4-鼠標雙擊 - 這個事件我可以用來清除繪圖。 (Mat image,Point(startx,starty),Point(endx,endy),(0,0,255),1));我也將有一個線條的繪製函數。如何在opencv中使用mouseclick在網絡攝像頭畫框中繪製線條?

現在,我不知道如何以代碼格式實現這一點。我嘗試了很多,但我得到了錯誤的結果。我有一個真誠的請求,請建議我以Mat格式而不是Iplimage格式的代碼。謝謝。

+0

你有什麼試過。 「錯誤的結果」是什麼意思?使用opencv的鼠標偵聽器來確定用戶點擊的位置。有很多例子。 – user3791372 2014-08-27 18:12:12

+0

@ user3791372: - 那些讓我煩惱的事情是我無法弄清楚如何找出Lbuttonup中的開始位置和Lbuttondown中的結束位置。大多數我使用iplimages在谷歌上檢查過的文章,因爲我遵循Mat格式,所以我很困惑。你能給我一些建議嗎? – Rebecca 2014-08-27 18:17:03

+0

一個兩元素數組,一個兩元素結構,一個簡單類等不要使它過於複雜 – user3791372 2014-08-27 18:19:24

回答

1

請在下面找到工作代碼,並使用Mat內嵌解釋說明;) 如有任何問題,請告知我。 PS:在主要功能中,我已將默認凸輪ID更改爲1代碼,您應該保持它適合您PC,大概爲0.祝您好運。

#include <iostream> 

#include <opencv\cv.h> 
#include <opencv2\core\core.hpp> 
#include <opencv2\highgui\highgui.hpp> 


class WebCamPaint 
{ 
public: 

    int cam_id; 
    std::string win_name; 
    cv::VideoCapture webCam; 

    cv::Size frame_size; 
    cv::Mat cam_frame, drawing_canvas; 

    cv::Point current_pointer, last_pointer; 
    cv::Scalar erase_color, paint_color; 
    int pointer_size; 

    //! Contructor to initialize basic members to defaults 
    WebCamPaint() 
    { 
     cam_id = 0; 
     pointer_size = 5; 

     win_name = std::string("CamView"); 
     current_pointer = last_pointer = cv::Point(0, 0); 

     erase_color = cv::Scalar(0, 0, 0); 
     paint_color = cv::Scalar(250, 10, 10); 
    } 

    //! init function is required to set some members in case default members needed to change. 
    bool init() 
    { 
     //! Opening cam with specified cam id 
     webCam.open(cam_id); 
     //! Check if problem opening video 
     if (!webCam.isOpened()) 
     { 
      return false; 
     } 

     //! Reading single frame and extracting properties 
     webCam >> cam_frame; 
     //! Check if problem reading video 
     if (cam_frame.empty()) 
     { 
      return false; 
     } 
     frame_size = cam_frame.size(); 
     drawing_canvas = cv::Mat(frame_size, CV_8UC3); 

     //! Creating Activity/Interface window 
     cv::namedWindow(win_name); 
     cv::imshow(win_name, cam_frame); 

     //! Resetting drawing canvas 
     drawing_canvas = erase_color; 

     //! initialization went successful ;) 
     return true; 
    } 

    //! This function deals wih all processing, drawing and displaying ie main UI to user 
    void startAcivity() 
    { 
     //! Keep doing until user presses "Esc" from Keyboard, wait for 20ms for user input 
     for (char user_input = cv::waitKey(20); user_input != 27; user_input = cv::waitKey(20)) 
     { 
      webCam >> cam_frame; //Read a frame from webcam 

      cam_frame |= drawing_canvas; //Merge with actual drawing canvas or drawing pad, try different operation to merge incase you want different effect or solid effect 
      cv::imshow(win_name, cam_frame); //Display the image to user 

      //! Change size of pointer using keyboard +/-, don't they sound fun ;) 
      if (user_input == '+' && pointer_size < 25) 
      { 
       pointer_size++; 
      } 
      else if (user_input == '-' && pointer_size > 1) 
      { 
       pointer_size--; 
      } 
     } 
    } 

    //! Our function that should be registered in main to opencv Mouse Event Callback 
    static void onMouseCallback(int event, int x, int y, int flags, void* userdata) 
    { 
     /* NOTE: As it will be registered as mouse callback function, so this function will be called if anything happens with mouse 
     *   event : mouse button event 
     *   x, y : position of mouse-pointer relative to the window 
     *   flags : current status of mouse button ie if left/right/middle button is down 
     *   userdata: pointer o any data that can be supplied at time of setting callback, 
     *      we are using here to tell this static function about the this/object pointer at which it should operate 
     */ 

     WebCamPaint *object = (WebCamPaint*)userdata; 

     object->last_pointer = object->current_pointer; 
     object->current_pointer = cv::Point(x, y); 

     //! Drawing a line on drawing canvas if left button is down 
     if (event == 1 || flags == 1) 
     { 
      cv::line(object->drawing_canvas, object->last_pointer, object->current_pointer, object->paint_color, object->pointer_size); 
     } 

     //! Drawing a line on drawing canvas if right button is down 
     if (event == 2 || flags == 2) 
     { 
      cv::line(object->drawing_canvas, object->last_pointer, object->current_pointer, object->erase_color, object->pointer_size); 
     } 
    } 

}; 


int main(int argc, char *argv[]) 
{ 
    WebCamPaint myCam; 
    myCam.cam_id = 1; 
    myCam.init(); 
    cv::setMouseCallback(myCam.win_name, WebCamPaint::onMouseCallback, &myCam); 
    myCam.startAcivity(); 

    return 0; 
} 
+0

: - 非常感謝。對此,我真的非常感激。你幫了我很多。再次感謝。 Bdw可以推薦我使用C++爲Opencv推薦任何書籍,這樣我可以學習一些複雜的程序。我基本上是一名自學者,因爲我是一名新生,所以我需要一本能夠清楚地解釋這些概念的書。再次感謝 – Rebecca 2014-08-29 20:43:45

+0

我很高興它有幫助。我假設你從這段代碼中瞭解並學習到了。關於進一步的研究,OpenCV是令人驚歎的圖書館和很好的資源。如果你只是谷歌,你會發現很多書,代碼等。我建議你從官方文檔開始:http://opencv.org/documentation.html。本頁面鏈接到所有的code-doc和ref,書籍,教程等等。你可以用oreilly書去,它即將推出新版本。如果它有幫助,你可以upvote /接受這個答案,它可以幫助其他讀者看到答案的評分。 – 2014-08-30 06:24:53

相關問題