/*
OPenCV框选感兴趣区域ROI,按ESC退出时画框并输出坐标
*/
#include "stdafx.h"
#include "opencv2/highgui/highgui.hpp"
#include < iostream >
#include "cv.h"
#include "highgui.h"
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
cv::Mat img;
bool select_flag = false;//鼠标左键按下开始框选的标志
cv::Rect m_select; //框选的区域
cv::Point origin; //左键按下捕捉到的点
int ROI_count;
void onMouseRectPicking(int event, int x, int y, int, void*)
{
if (select_flag)
{
//等鼠标弹起才计算矩形框,可改为在鼠标按下开始到弹起这段时间实时计算所选矩形框
m_select.x = MIN(origin.x, x);
m_select.y = MIN(origin.y, y);
//算矩形宽度和高度
m_select.width = abs(x - origin.x);
m_select.height = abs(y - origin.y);
//保证所选矩形框在显示区域之内
m_select &= cv::Rect(0, 0, img.cols, img.rows);
}
//鼠标按下
if (event == CV_EVENT_LBUTTONDOWN)
{
select_flag = true;
//保存下来单击捕捉到的点
origin = cv::Point(x, y);
//一定要初始化宽和高为(0,0),因为在opencv中Rect矩形框类内的点是包含左上角那个点但不含右下角那个点。
m_select = cv::Rect(x, y, 0, 0);
}
//鼠标抬起
else if (event == CV_EVENT_LBUTTONUP)
{
select_flag = false;
ROI_count++;
}
}
int main(int argc, char* argv[])
{
bool stop = false;
cv::namedWindow("capframe", CV_WINDOW_AUTOSIZE);
cv::setMouseCallback("capframe", onMouseRectPicking, 0);
char pic_name[40];
ROI_count = 0;
//用于存储框选的图像和rect
Rect rect;
Mat ROI;
while (!stop)
{
img = imread("CarIcon.bmp");
cv::rectangle(img, m_select, cv::Scalar(255, 0, 0), 2, 8, 0); // 画矩形框
cv::imshow("capframe", img);
if ((m_select.x != 0) && (m_select.y != 0) && (m_select.width != 0) && (m_select.height != 0))
{
sprintf_s(pic_name, "ROI_%d.bmp", ROI_count);
ROI_count++;
ROI = img(m_select);
rect = m_select;
}
//直到ESC按下才退出框选操作
char key = cv::waitKey(30);
if (key == 27)
stop = true;
}
//显示框选的图像
imshow("ROI_WIN", ROI);
imwrite(pic_name, ROI);
//输出框选的图像在原图中左上角点的坐标以及框选图像的宽高
cout << "X=" << rect.x << ",Y=" << rect.y << endl;
cout << "宽:" << rect.width << ",高:" << rect.height << endl;
waitKey(0);
return 0;
}