opencv鼠标截图的简单实现
以下是用opencv实现的一个简单的窗口截图程序:#include <iostream>#include <opencv2/opencv.hpp>using namespace cv;using namespace std;/*截图方式说明:1.鼠标左键按下则为截图起始点方法一:鼠标左键一直按下,直到鼠标移动到目标点再松开,即可完成一次截图;方法二:鼠...
·
以下是用opencv实现的一个简单的窗口截图程序:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
/*
截图方式说明:
1.鼠标左键按下则为截图起始点
方法一:鼠标左键一直按下,直到鼠标移动到目标点再松开,即可完成一次截图;
方法二:鼠标左键单击后,鼠标移动到目标点再次鼠标左键单击,即可完成一次截图;
若是在截图过程中,单击鼠标右键可取消本次截图状态
2.截图不会立即进行保存,截完图后可以单击鼠标右键进行取消保存上一次的截图;
存储方式一:若是截图完成后,再次进入截图状态,则会自动存储上一轮截图;
存储方式二:若是跳到下一张原始图片,则上一张原始图片中未保存的上一轮截图会自动存储;
*/
#define MIN_ROI_AREA 300 //有效截图的最小面积限制
//定义全局变量
static Point g_pt; //存储鼠标第一次按下的坐标,即截图的左上角坐标;
static Mat g_img_src; //存储当前的原始图像;
static Mat g_img_dst; //存储截图过程实时的图像;
static Mat g_img_roi; //存储截图完成时的局部图;
static bool g_flag = false; //是否已处于截图状态的标示
static bool g_issave = false; //是否已经有未存储的缓存roi的标示
static string g_window_name = "image";//窗口名
//加载原始图像
bool load_image(Mat &image)
{
//遍历数据集中的原始图像,imread(),略;
}
//保存截取的roi图像
void save_roi(Mat image)
{
//定义输出路径,imwrite()输出,略;
}
// 鼠标的回调函数
static void onMouse(int event, int x, int y, int , void*)
{
//触发鼠标左键按下事件
if(CV_EVENT_LBUTTONDOWN == event)
{
//若当前不是截图状态,则进入截图状态,当前点为起始点并存储;
if(g_flag == false)
{
//进入截图状态;
g_flag = true;
//存储截图起始点
g_pt = Point(x,y);
//若未保存上一轮roi的保存,则进行存储;
if(g_issave == true)
{
save_roi(g_img_roi);
g_issave = false;
}
}
//若当前处于截图状态,则结束截图状态,并获取roi
if(g_flag == true && abs(x-g_pt.x)*abs(y-g_pt.y) >MIN_ROI_AREA)
{
//结束截图状态
g_flag = false;
// 利用截图区域生成g_img_roi
g_img_src(Rect(g_pt,Point(x,y))).copyTo(g_img_roi);
imshow("roi",g_img_roi);
g_issave = true;
}
}//if(CV_EVENT_LBUTTONDOWN == event)
//触发鼠标移动事件,并处于截图状态时
else if(CV_EVENT_MOUSEMOVE == event && g_flag)
{
//重新初始化g_img_dst,确保g_img_dst上始终只有一个框
g_img_src.copyTo(g_img_dst);
rectangle(g_img_dst,g_pt,Point(x,y),Scalar(255,0,0),3,8);
imshow(g_window_name, g_img_dst);
}
//触发鼠标左键松开事件
else if(CV_EVENT_LBUTTONUP == event &&
abs(x-g_pt.x)*abs(y-g_pt.y) >MIN_ROI_AREA )
{
//结束截图状态
g_flag = false;
//获取roi
g_img_src(Rect(g_pt,Point(x,y))).copyTo(g_img_roi);
imshow("roi",g_img_roi);
g_issave = true;
}
//触发鼠标右键按下事件
else if(CV_EVENT_RBUTTONDOWN == event )
{
//在截图状态,则取消截图状态
if(g_flag == true)
{
g_flag = false;
//更新图像
imshow(g_window_name, g_img_src);
}
//不在截图状态,则无效上一轮的截图缓存;
if(g_flag == false)
{
g_issave = false;
//更新图像
imshow(g_window_name, g_img_src);
//关闭局部窗口
destroyWindow("roi");
}
}
}
int main()
{
namedWindow(g_window_name,CV_WINDOW_AUTOSIZE);
setMouseCallback(g_window_name, onMouse,0);
Mat img;
while(load_image(img))
{
if(img.empty())
{
cout << "empty image" << endl;
return 0;
}
//存储原始图像
g_img_src = img.clone();
while(true)
{
imshow(g_window_name,g_img_src);
int c = waitKey(0);
if((c&255) == 27)
{
//按下ESC,则跳到下一张
g_flag = false;
//若本轮有未存储的截图则自动存储
//保存上一轮图
if(g_issave == true)
{
save_roi(g_img_roi);
g_issave = false;
}
}//if((c&255) == 27)
}//while(true)
}//while(load_image(img))
return 0;
}
更多推荐
所有评论(0)