[OpenCV]在顯示窗口中截圖 簡介
介紹使用OpenCV實現(xiàn)簡單的截圖功能。首先闡述實現(xiàn)此功能的基本步驟,然后給出實現(xiàn)代碼,最后貼出實驗結(jié)果以及遇到的問題。
基本步驟
我們需要知道OpenCV使用字符串來唯一標記顯示圖像的窗口,也就是說與窗口相關的工作都與一個字符串有關。
我們在已經(jīng)顯示的圖像上截取一個子圖,并且顯示這個子圖。
具體操作步驟如下:
將鼠標移動到顯示圖像的窗口上 按下鼠標左鍵 保持鼠標左鍵按下狀態(tài),并且移動鼠標 抬起鼠標左鍵
程序的基本步驟如下:
讀入要截圖的圖像 窗口顯示要截取的圖像 設置顯示窗口的回調(diào)函數(shù) 循環(huán)顯示圖像,等待鍵盤按下退出鍵
本功能的回調(diào)函數(shù)需要處理鼠標的三個事件:
左鍵按下(對應OpenCV中事件CV_EVENT_LBUTTONDOWN) 鼠標移動(對應OpenCV中事件CV_EVENT_MOUSEMOVE) 左鍵抬起(對應OpenCV中事件CV_EVENT_LBUTTONUP)
為了展示截屏過程的效果,在鼠標移動過程中,加入一個繪制矩形框功能。為了避免在沒按下鼠標左鍵的條件下繪制矩形框,需要引入一個控制變量,來標記鼠標左鍵是否已經(jīng)按下。
程序代碼
代碼如下:
#include?"opencv2/imgproc/imgproc.hpp" #include?"opencv2/highgui/highgui.hpp" #include?"opencv2/opencv.hpp" #include#includeusing?namespace?cv; using?namespace?std; //?global?variable static?Mat?g_img_src; static?Mat?g_img_dst; static?Mat?g_img_sub; static?bool?g_is_rect_inited?=?false; static?Point?g_rect_tl; static?string?g_window_name?=?"image"; static?void?onMouse(?int?event,?int?x,?int?y,?int,?void*?) {??? ????if(CV_EVENT_LBUTTONDOWN?==?event){ ????????g_is_rect_inited?=?true; ????????g_rect_tl?=?Point(x,?y);???? ????} ????else?if?(CV_EVENT_MOUSEMOVE?==?event?&&?g_is_rect_inited){?????? ????????g_img_src.copyTo(g_img_dst); ????????rectangle(g_img_dst,?g_rect_tl,?Point(x,y),?Scalar_::all(200),?3,?8); ????????imshow(g_window_name,?g_img_dst);??? ????} ????else?if?(CV_EVENT_LBUTTONUP?==?event?&&?g_rect_tl?!=?Point(x,y)){??? ????????g_img_src(Rect(g_rect_tl,?Point(x,y))).copyTo(g_img_sub); ????????imshow("sub?image",?g_img_sub); ????????g_is_rect_inited?=?false; ????} } int?main(int?argc,?char**?argv){ ????string?filename?=?argc?>=?2???argv[1]?:?"fruits.jpg"; ????g_img_src?=?imread(filename,?CV_LOAD_IMAGE_GRAYSCALE); ????if?(g_img_src.empty()){ ????????cerr?<<?"[ERROR]?:?please?check?your?image?file?name."?<<?endl; ????????return?EXIT_FAILURE; ????} ????namedWindow(g_window_name,?CV_WINDOW_KEEPRATIO); ????setMouseCallback(g_window_name,?onMouse,?0); ????while(true){ ????????imshow(g_window_name,?g_img_src); ????????int?c?=?waitKey(0); ????????if(?(c?&?255)?==?27?){?//?Esc ????????????destroyAllWindows(); ????????????cout?<<?"Exiting?...n"; ????????????break; ????????} ????} ????return?EXIT_SUCCESS; }
實驗結(jié)果
實驗結(jié)果如下圖所示:
總結(jié)
本文中實現(xiàn)的程序有些情況下單擊鼠標左鍵,不能夠捕獲鼠標左鍵的抬起時間,單擊被認為是左鍵按下的事件,所以單擊之后,白框就一直跟著鼠標走。這一點有待改進。