您的位置:首页 > 游戏 > 手游 > OpenCV通过鼠标提前ROI(C++实现)

OpenCV通过鼠标提前ROI(C++实现)

2024/12/23 16:41:40 来源:https://blog.csdn.net/qq_44924694/article/details/142150651  浏览:    关键词:OpenCV通过鼠标提前ROI(C++实现)

文章目录

    • 鼠标绘制矩形提取ROI
    • 任意形状绘制提前ROI

废话不多说,直接上代码

鼠标绘制矩形提取ROI

#include <iostream>  
#include <opencv2\opencv.hpp>
#include <opencv2/highgui/highgui.hpp>    
#include <opencv2/core/core.hpp>using namespace cv;
using namespace std;// 全局变量图像源
cv::Mat srcImage;
cv::Mat roiImage;
// 起始点
cv::Point startPoint;
// 终止点
cv::Point endPoint;
// 完成所选区域标志位
bool downFlag = false;
bool upFlag = false;void MouseEvent(int event, int x, int y, int flags, void* data)
{// 鼠标左键按下 获取起始点if (event == EVENT_LBUTTONDOWN){downFlag = true;startPoint.x = x;startPoint.y = y;}// 鼠标拖到松开 获取终止点if (event == EVENT_LBUTTONUP){upFlag = true;endPoint.x = x;endPoint.y = y;}// 显示鼠标选择的图像区域if (downFlag == true && upFlag == false){Point tempPoint;tempPoint.x = x;tempPoint.y = y;// 用于显示图像生成cv::Mat tempImage = srcImage.clone();cv::rectangle(tempImage, startPoint, tempPoint, Scalar(0, 0, 255), 2, 3, 0);cv::imshow("cut", tempImage);}   // 选择区域生成if (downFlag == true && upFlag == true){// 所选矩形区域 cv::Rect roiRect;// 获取选择区域的ROIroiRect.width = abs(startPoint.x - endPoint.x);roiRect.height = abs(startPoint.y - endPoint.y);roiRect.x = min(startPoint.x, endPoint.x);roiRect.y = min(startPoint.y, endPoint.y);cout << "rect: " << roiRect << endl;if (roiRect.width > 0 && roiRect.height > 0){cv::Mat roiMat(srcImage, roiRect);imshow("ROI", roiMat);imwrite("roi.tif", roiMat);}downFlag = false;upFlag = false;}
}int main()
{Mat src = cv::imread("tt.jpg");if (src.empty())return -1;namedWindow("cut", WINDOW_AUTOSIZE);// 回调事件响应::srcImage = src.clone();cv::namedWindow("cut");cv::imshow("cut", srcImage);cv::setMouseCallback("cut", MouseEvent, 0);cv::waitKey(0);cv::destroyAllWindows();return 0;
}

在这里插入图片描述
在这里插入图片描述

任意形状绘制提前ROI

#include <iostream>  
#include <vector>
#include <opencv2\opencv.hpp>
#include <opencv2/highgui/highgui.hpp>    
#include <opencv2/core/core.hpp>
#define CV_AA 16using namespace cv;cv::Mat src, tempMat;
cv::Mat dst, maskImage;
std::vector<cv::Point> vctPoint;
cv::Point ptStart = (-1, -1); //初始化起点
cv::Point cur_pt = (-1, -1);  //初始化临时节点void on_mouse(int event, int x, int y, int flags, void *ustc)//event鼠标事件代号,x,y鼠标坐标,flags拖拽和键盘操作的代号    
{if (event == EVENT_LBUTTONDOWN){std::cout << "x:" << x << " y:" << y << std::endl;ptStart = cv::Point(x, y);vctPoint.push_back(ptStart);cv::circle(src, ptStart, 1, cv::Scalar(255, 0, 255), FILLED, CV_AA, 0);cv::imshow("图片", src);}else if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON)){std::cout << "x:" << x << " y:" << y << std::endl;cur_pt = cv::Point(x, y);cv::line(src, vctPoint.back(), cur_pt, cv::Scalar(0, 255, 0, 0), 1, 8, 0);cv::imshow("图片", src);vctPoint.push_back(cur_pt);}else if (event == EVENT_LBUTTONUP){std::cout << "x:" << x << " y:" << y << std::endl;cur_pt = cv::Point(x, y);cv::line(src, ptStart, cur_pt, cv::Scalar(0, 255, 0, 0), 1, 8, 0);cv::imshow("图片", src);vctPoint.push_back(cur_pt);//把点构成任意多边形进行填充const cv::Point * ppt[1] = { &vctPoint[0] };//取数组的首地址int len = vctPoint.size();int npt[] = { len };std::cout << len << std::endl;src.copyTo(maskImage);maskImage.setTo(cv::Scalar(0, 0, 0, 0));cv::fillPoly(maskImage, ppt, npt, 1, cv::Scalar(0, 255, 255, 255));src.copyTo(dst, maskImage);cv::imshow("抠图", dst);// 清空上次绘制的点vctPoint.clear();vctPoint.resize(0);vctPoint.shrink_to_fit();std::cout << "Vector is " << (vctPoint.empty() ? "empty." : "not empty.") << std::endl;std::cout << "Capacity is " << vctPoint.capacity() << std::endl;dst.setTo(0);src = tempMat.clone();cv::waitKey(0);}
}int main()
{src = cv::imread("src.jpg");tempMat = src.clone();//鼠标点击cv::namedWindow("图片");//定义一个img窗口    cv::setMouseCallback("图片", on_mouse, 0);//调用回调函数    cv::imshow("图片", src);cv::waitKey(0);return 0;
}

在这里插入图片描述
在这里插入图片描述
如果觉得以上代码对你有帮助,那就一键三连吧。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com