[OpenCV]在顯示窗口中截圖
[OpenCV]在顯示窗口中截圖 簡介
介紹使用OpenCV實(shí)現(xiàn)簡單的截圖功能。首先闡述實(shí)現(xiàn)此功能的基本步驟,然后給出實(shí)現(xiàn)代碼,最后貼出實(shí)驗(yàn)結(jié)果以及遇到的問題。
基本步驟
我們需要知道OpenCV使用字符串來唯一標(biāo)記顯示圖像的窗口,也就是說與窗口相關(guān)的工作都與一個(gè)字符串有關(guān)。
我們在已經(jīng)顯示的圖像上截取一個(gè)子圖,并且顯示這個(gè)子圖。
具體操作步驟如下:
將鼠標(biāo)移動(dòng)到顯示圖像的窗口上 按下鼠標(biāo)左鍵 保持鼠標(biāo)左鍵按下狀態(tài),并且移動(dòng)鼠標(biāo) 抬起鼠標(biāo)左鍵
程序的基本步驟如下:
讀入要截圖的圖像 窗口顯示要截取的圖像 設(shè)置顯示窗口的回調(diào)函數(shù) 循環(huán)顯示圖像,等待鍵盤按下退出鍵
本功能的回調(diào)函數(shù)需要處理鼠標(biāo)的三個(gè)事件:
左鍵按下(對應(yīng)OpenCV中事件CV_EVENT_LBUTTONDOWN) 鼠標(biāo)移動(dòng)(對應(yīng)OpenCV中事件CV_EVENT_MOUSEMOVE) 左鍵抬起(對應(yīng)OpenCV中事件CV_EVENT_LBUTTONUP)
為了展示截屏過程的效果,在鼠標(biāo)移動(dòng)過程中,加入一個(gè)繪制矩形框功能。為了避免在沒按下鼠標(biāo)左鍵的條件下繪制矩形框,需要引入一個(gè)控制變量,來標(biāo)記鼠標(biāo)左鍵是否已經(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;
}實(shí)驗(yàn)結(jié)果
實(shí)驗(yàn)結(jié)果如下圖所示:
總結(jié)
本文中實(shí)現(xiàn)的程序有些情況下單擊鼠標(biāo)左鍵,不能夠捕獲鼠標(biāo)左鍵的抬起時(shí)間,單擊被認(rèn)為是左鍵按下的事件,所以單擊之后,白框就一直跟著鼠標(biāo)走。這一點(diǎn)有待改進(jìn)。





