当前位置: 首页 > news >正文

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;
}

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

http://www.lryc.cn/news/435690.html

相关文章:

  • 6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)
  • 【智能终端】HBuilder X 与微信开发者工具集成与调试实战
  • 结构体的字节对齐方式(__attribute_pack(packed))#pragma pack())
  • 若依Ruoyi之智能售货机运营管理系统(新增运营运维工单管理)
  • ModuleNotFoundError: No module named ‘keras.layers.core‘怎么解决
  • C++(三)----内存管理
  • 使用 ShuffleNet 模型在 CIFAR-100 数据集上的图像分类
  • 怎么利用短信接口发送文字短信
  • 【C#生态园】提升C#开发效率:掌握这六款单元测试利器
  • 【QT】自制一个简单的小闹钟,能够实现语音播报功能
  • 基于深度学习的图像描述生成
  • Linux和C语言(Day11)
  • 使用Zlib库进行多文件或者多文件夹的压缩解压缩
  • CSGHub携手Nvidia NIM、阿里计算巢打造企业级私有化部署解决方案
  • opencv的球面投影
  • 5. 去中心化应用(dApp)
  • k8s服务发布Ingress
  • 区块链学习笔记1--比特币
  • 在 Vite 项目中自动为每个 Vue 文件导入 base.less
  • RUST 学习之全局变量
  • 代码随想录八股训练营第三十九天| C++
  • 服务网关工作原理,如何获取用户真实IP?
  • 单链表的实现(C语言)
  • sql语句的训练2024/9/9
  • 【QT】常用控件-下
  • 828华为云征文|华为云Flexus X实例docker部署Jitsi构建属于自己的音视频会议系统
  • 25虾皮笔试shopee笔试测评sea笔试测评题型
  • 启明云端乐鑫代理商,乐鑫ESP32无线芯片方案,物联网设备WiFi联动控制
  • 希尔排序/选择排序
  • 漫谈设计模式 [16]:中介者模式