以下是用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;
}

在这里插入图片描述

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐