opencv使用鼠标任意形状的抠图

鼠标截取图像c++风格 本人新手一枚,最近在做视频处理方面毕设,运用鼠标截取图像对相机进行标定。确切的说是得到图像中有效像素的位置信息,为了防止非感兴趣像素的影响,所以想到先用鼠标截取图像中的一部分,进而得到相应坐标。        在前辈dayo的博客中曾看到这方面的代码,是C风格的,但是由于博客中代码并不完整,直接粘来用不了,所以自行改为c++风格代码,完整代码如下,以供参考: #include "cv.h" 阅读详情

主要的方法思路是:首先利用鼠标在图上画任意形状,利用掩码将任意形状抠出来

主要难点是怎么填充,因为鼠标在画线的时候,滑动越快,点是不连续的,利用floodFill和drawContours都是没有办法进行填充的,从另一个方面想,一个面是由很多个点组成的,虽然鼠标滑动保存下来的就是一系列点,可以利用这一系列点构成一个面,利用面的性质进行填充就比较简单了。

一、首先使用鼠标点击事件,鼠标点击事件的函数为:

void on_mouse(int event, int x, int y, int flags, void* ustc)

常见的鼠标事件有:

event事件有: 

    CV_EVENT_MOUSEMOVE      =0,   //鼠标移动
    CV_EVENT_LBUTTONDOWN    =1,   //按下左键
    CV_EVENT_RBUTTONDOWN    =2,   //按下右键
    CV_EVENT_MBUTTONDOWN    =3,   //按下中键
    CV_EVENT_LBUTTONUP      =4,   //放开左键
    CV_EVENT_RBUTTONUP      =5,   //放开右键
    CV_EVENT_MBUTTONUP      =6,   //放开中键
    CV_EVENT_LBUTTONDBLCLK  =7,   //左键双击
    CV_EVENT_RBUTTONDBLCLK  =8,   //右键双击
    CV_EVENT_MBUTTONDBLCLK  =9,   //中键双击
    CV_EVENT_MOUSEWHEEL     =10,  //滚轮滚动
    CV_EVENT_MOUSEHWHEEL    =11   //横向滚轮滚动

flag事件有:

   CV_EVENT_FLAG_LBUTTON   =1,   //左键拖拽
    CV_EVENT_FLAG_RBUTTON   =2,   //右键拖拽
    CV_EVENT_FLAG_MBUTTON   =4,   //中键拖拽
    CV_EVENT_FLAG_CTRLKEY   =8,   //按住CTRL拖拽
    CV_EVENT_FLAG_SHIFTKEY  =16,  //按住Shift拖拽
    CV_EVENT_FLAG_ALTKEY    =32   //按住ALT拖拽

首先鼠标在图像上的操作有三个步骤:

1、按下左键,建立一个起点

if (event == CV_EVENT_LBUTTONDOWN)
	{
		//画起点
	}

2、按下左键的同时,进行左键拖拽画线

else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))
	{
	   //在拖动过程中画线
	}

3、放下左键,起点与当前点进行连接

else if (event == CV_EVENT_LBUTTONUP)
	{
       //在结束之后进行起点和终点的连接
    }

二、对一系列点组成的封闭图形进行填充

采用多边形填充函数fillpoly 取一系列队的首地址,进行多边形的填充,vctPoint保存鼠标滑过的一系列的点

        const cv::Point * ppt[1] = { &vctPoint[0] };//取数组的首地址
		int len = vctPoint.size();
		int npt[] = { len };
		org.copyTo(maskImage);
		maskImage.setTo(cv::Scalar(0,0, 0, 0));
		cv::fillPoly(maskImage, ppt, npt, 1, cv::Scalar(0,255, 255, 255));

完整的代码如下:

#include <iostream>  
#include <vector>
#include <opencv.hpp>
#include <opencv2\opencv.hpp>
#include <opencv2/highgui/highgui.hpp>    
#include <opencv2/core/core.hpp>

static std::vector<std::vector<cv::Point>> vctvctPoint;
cv::Mat org = cv::imread("images/kaola.jpg");
cv::Mat dst, maskImage;
static std::vector<cv::Point> vctPoint;
static cv::Point ptStart = (-1, -1); //初始化起点
static cv::Point cur_pt = (-1, -1);  //初始化临时节点
char temp[16];


void on_mouse(int event, int x, int y, int flags, void *ustc)//event鼠标事件代号,x,y鼠标坐标,flags拖拽和键盘操作的代号    
{
	if (event == CV_EVENT_LBUTTONDOWN)
	{
		std::cout << "x:" << x << " y:" << y << std::endl;
		ptStart = cv::Point(x, y);
		vctPoint.push_back(ptStart);
        cv::circle(org, ptStart, 1, cv::Scalar(255, 0, 255), CV_FILLED, CV_AA, 0);
		cv::imshow("图片", org);
		//cv::putText(tmp, temp, ptStart, cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0, 0), 1, 8);
	}
	else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))
	{
		std::cout << "x:" << x << " y:" << y << std::endl;
		cur_pt = cv::Point(x, y);
		cv::line(org, vctPoint.back(), cur_pt, cv::Scalar(0, 255, 0, 0), 1, 8, 0);
		cv::circle(org, cur_pt, 1, cv::Scalar(255, 0, 255), CV_FILLED, CV_AA, 0);
		cv::imshow("图片", org);
		vctPoint.push_back(cur_pt);
		//cv::putText(tmp, temp, cur_pt, cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0, 0));
	}
	else if (event == CV_EVENT_LBUTTONUP)
	{	
		std::cout << "x:" << x << " y:" << y << std::endl;
		cur_pt = cv::Point(x, y);
		cv::line(org, ptStart, cur_pt, cv::Scalar(0, 255, 0, 0), 1, 8, 0);
		cv::circle(org, cur_pt, 1, cv::Scalar(255, 0, 255), CV_FILLED, CV_AA, 0);
		cv::imshow("图片", org);
		vctPoint.push_back(cur_pt);
		vctvctPoint.push_back(vctPoint);   
		//把点构成任意多边形进行填充
		const cv::Point * ppt[1] = { &vctPoint[0] };//取数组的首地址
		int len = vctPoint.size();
		int npt[] = { len };
	//	cv::polylines(org, ppt, npt, 1, 1, cv::Scalar(0,0, 0, 0), 1, 8, 0);	    
		org.copyTo(maskImage);
		maskImage.setTo(cv::Scalar(0,0, 0, 0));
		cv::fillPoly(maskImage, ppt, npt, 1, cv::Scalar(0,255, 255, 255));	
		org.copyTo(dst ,maskImage);
		cv::imshow("抠图",dst);
		cv::waitKey(0);
	}
}
int main()
{
	//鼠标点击
	cv::namedWindow("图片");//定义一个img窗口    
	cv::setMouseCallback("图片", on_mouse, 0);//调用回调函数    
	cv::imshow("图片", org);
	cv::waitKey(0);
	return 0;
}

效果如下所示:

 

OpenCV2.4.13 中 选取roi区域,任意形状(矩形,不规则多边形,圆形,椭圆,手动指定形状) 在利用OpenCV对图像进行处理时,通常会遇到一个情况,就是只需要对部分感兴趣区域进行处理。 因此,如何选取感兴趣区域(其实就是“抠图”)。 下面给出一个例子: Mat img = imread(IMG_PATH); Mat cat = imread(CAT_PATH); if (img.empty()|| cat.empty()) cerr << "can 阅读详情

相关推荐

C# WinForm项目实战:用OpenCVSharp 3实现任意形状ROI抠图(附完整源码)

本文详细介绍了如何在C# WinForm项目中使用OpenCVSharp 3实现任意形状ROI抠图,包括矩形、圆形和椭圆三种形状的动态区域提取。通过完整的源码示例和实战教程,帮助开发者解决图像坐标转换、实时预览等工程难题,适用于工业检测、医疗影像等多个领域。

weixin_26934905的博客 207

opencv使用—使用鼠标任意形状的抠图(获取任意形状mask)

opencv使用—使用鼠标任意形状的抠图 项目中使用到opencv提取多边形,并做成mask opencv4.1.0 #include <iostream> #include "opencv2/core/core.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #in...

weixin_45545542的博客 1384

Qt实现的图片抠图工具

QString fileName = QFileDialog::getOpenFileName(this, "打开图片", "",QString fileName = QFileDialog::getSaveFileName(this, "保存结果", "",QMessageBox::about(this, "关于", "Qt 图片抠图工具\n支持自动抠图、手动抠图和多种形状抠图");QColor color = QColorDialog::getColor(Qt::red, this, "选择颜色");

寒寒豆豆软件公司的博客 350

12.Opencv大作业——实现鼠标绘制基本图形

保持热爱,奔赴山海。 3679

Python+OpenCV+Qt实现交互式图像抠图实战项目

随着计算机视觉技术的快速发展,图像分割与目标提取在人工智能、医学影像分析、智能安防等领域扮演着越来越重要的角色。交互式抠图通过结合用户输入(如鼠标标注)与算法处理(如颜色分割、轮廓提取),显著提升了复杂背景下目标提取的精度与灵活性。Python凭借简洁语法和强大的科学计算生态,成为该领域主流开发语言;而OpenCV不仅提供高效的图像处理函数库,还内置完善的交互机制(如鼠标事件响应、实时图像渲染),为构建直观、可操作的抠图系统提供了坚实支撑。

weixin_32389853的博客 530

Opencv使用鼠标任意形状的抠图

本文实例为大家分享了Opencv使用鼠标任意形状抠图的具体代码,供大家参考,具体内容如下 主要的方法思路是:首先利用鼠标在图上画任意形状,利用掩码将任意形状抠出来 主要难点是怎么填充,因为鼠标在画线的时候,滑动越快,点是不连续的,利用floodFill和drawContours都是没有办法进行填充的,从另一个方面想,一个面是由很多个点组成的,虽然鼠标滑动保存下来的就是一系列点,可以利用这一系列点构成一个面,利用面的性质进行填充就比较简单了。 一、首先使用鼠标点击事件,鼠标点击事件的函数为: void on_mouse(int event, int x, int y, int flags, vo

学习Opencv+Python之获取鼠标绘制图形

学习Opencv+Python之获取鼠标绘制图形 1、鼠标相应的相关操作 在Opencv中,将鼠标键位的点击操作称为“事件(event)”,常见的这些事件有: EVENT_MOUSEMOVE 0 滑动 EVENT_LBUTTONDOWN 1 左键点击 EVENT_RBUTTONDOWN 2 右键点击 EVENT_MBUTTONDOWN 3 中键点击 EVENT_LBUTTONUP 4 左键放开 EVENT_RBUTTONUP 5 右键放开 EVENT_M

weixin_42744921的博客 1358

SpringBoot+Maven打包实战:把项目变成SDK供其他团队调用

本文详细介绍了如何将SpringBoot项目改造并打包成可被其他项目依赖的SDK。通过调整Maven配置,剥离SpringBoot父依赖与启动类,并定制打包插件,最终生成标准的JAR依赖库,实现从“可执行应用”到“组件化SDK”的优雅转变,便于团队间功能复用。

assembly8low的博客 827

Opencv-Python鼠标响应事件之绘制圆/矩形/线/椭圆

鼠标事件分为三大类:1.点击(Click) 2.放开(Down) 3.滑动(move) Event: #define CV_EVENT_MOUSEMOVE 0 滑动 #define CV_EVENT_LBUTTONDOWN 1 左键点击 #define CV_EVENT_RBUTTONDOWN 2 右键点击 #define CV_EVENT_MBUTTONDOWN 3 中键点击 #define CV_EVEN

Scarlett的博客 2529

数字摄影与摄像中的图像信号处理器(ISP):流程与经典算法详解

图像信号处理器(Image Signal Processor, ISP)是现代数字成像系统(如智能手机、数码相机、网络摄像头等)中的核心组件,扮演着将图像传感器(如CMOS或CCD)捕获的原始光电信号转换为高质量、可供观看或进一步处理的数字图像的关键角色。在数字摄影和摄像的整个链路中,光线首先通过镜头(Lens)聚焦到图像传感器上,传感器将光信号转换为模拟电信号,随后经过模数转换(A/D转换)变为原始的数字图像信号。

qq_44682523的博客 3725

[Dify 实战] 如何在内网环境部署 Dify 应用:彻底离线的企业级方案解析

企业内网环境如何离线部署Dify?本文提供详细教程:Dify作为开源AI平台,支持完全离线部署,无需外网访问。文中介绍两种部署方式:推荐使用Docker一键部署,也可选择源码安装定制化方案。重点讲解内网模型配置(支持Ollama/GPT-OSS等)、知识库存储(MinIO/PostgreSQL)及内网代理设置,并给出常见问题排查方法。该方案适用于金融、政府等对数据安全要求高的场景,确保敏感数据不泄露,实现完全本地化的AI应用闭环。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 453

c语言程序图像抠图,Opencv使用鼠标任意形状的抠图

本文实例为大家分享了Opencv使用鼠标任意形状抠图的具体代码,供大家参考,具体内容如下主要的方法思路是:首先利用鼠标在图上画任意形状,利用掩码将任意形状抠出来主要难点是怎么填充,因为鼠标在画线的时候,滑动越快,点是不连续的,利用floodFill和drawContours都是没有办法进行填充的,从另一个方面想,一个面是由很多个点组成的,虽然鼠标滑动保存下来的就是一系列点,可以利用这一系列点构成一...

weixin_39681058的博客 840

基于Simulink进行步进电机的重复控制仿真建模

重复控制概述目的:通过引入一个周期延迟环节来补偿系统的周期性误差,从而提高系统对周期性参考信号或扰动的跟踪性能。方法内部模型原理:在控制器中嵌入一个与周期性信号相关的模型(例如周期延迟环节),以实现对周期性误差的零稳态误差控制。滤波器设计:为了避免高频噪声放大,通常会在重复控制器中加入低通滤波器。优势对周期性信号具有良好的跟踪性能。不需要精确的数学模型即可实现高性能控制。挑战:需要合理设计重复控制器的参数以避免系统不稳定。

amy_mhd的博客 268

opencv 笔记(一) 抠图

#include <iostream> #include <vector> #include <opencv2\opencv.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/core/core.hpp> #define CV_AA 16 using namespace cv; static std::vector<std::vector<c...

juluwangriyue的博客 950

基于Gurobi的综合能源系统运行优化:鲁棒两阶段优化方法

本文提出了一种基于Gurobi的综合能源系统鲁棒两阶段优化方法,针对包含换电站、光伏发电和电池储能的系统运行问题。研究采用多面体不确定性集合描述光伏出力随机性,构建了考虑电池衰减成本和弃光惩罚的两阶段优化模型:第一阶段制定日前调度计划,第二阶段处理实时运行中的不确定性。通过列与约束生成算法求解模型,并使用Python和Gurobi实现。仿真验证了该方法能有效平衡系统经济性与鲁棒性,为含高比例可再生能源的综合能源系统运行提供了实用解决方案。

huanghm88的专栏 242

二、TCP/IP协议之网络层(IP地址的格式、分类、报文格式)

数据报每经过一个路由器,路由器都要重新计算一下首部检验和,若首部未发生变化,则此结果必为 0,于是就保留这个数据报。对于网络号相的设备,无论实际所处的物理位置如何,它们都是处在同一个网络中。在首部的固定部分的后面是一些可选字段,其长度是可变的。IPv4 软件在存储器中维持一个计数器,每产生一个数据报,计数器就加 1,并将此值赋给标识字段。表示数据报在网络中的寿命,英文缩写是 TTL(Time To Live),功能是“跳数限制”。地址的网络号码字段用来标识一个网络,网络号码字段的前几位用来区分。

锦慈的技术博客 185

OpenCV图像处理使用笔记(一)——使用鼠标选取任何形状的ROI

1.在图像处理中,会用鼠标选择一个感兴趣的区域进行相关的操作,我这里演示如何用鼠标选择任何形状的ROI,就你Ps的抠图一样,使用鼠标左键选择一个任何形状的区域,生成新的图像。2.我演示的代码环境是,IDE是VS2015,使用的是OpenCV3.30这个版本。

知来者逆的博客 2630

R语言生存分析之限制性立方样条分析:样条回归、和多项式回归有什么不同?是否存在非线性关系、限制性立方样条cox回归模型

R语言生存分析之限制性立方样条分析:样条回归、和多项式回归有什么不同?是否存在非线性关系、限制性立方样条cox回归模型

statistics+insight+vista+power 634

opencv4 通过鼠标绘制掩模进行抠图

#include<iostream> #include<opencv2/opencv.hpp> #include<opencv2/imgproc/imgproc.hpp> #include<opencv2/highgui.hpp> using namespace std; using namespace cv; Mat img1; Mat mask; Mat res; Point center; Point end_1; void onMouse(int,

weixin_44171380的博客 404

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

学习OpenCV2——抠图及setmousecallback说明

本文介绍了在OpenCV中如何截取矩形和任意形状的图形,还介绍了鼠标回调函数setmousecallback的用法。

Markala的博客 5220

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

opencv3.0 截取任意形状封闭图形

截取任意图形是抠图的一个基本操作,在opencv 下也可以实现了。 漫水填充加模板实现截图。FloodFill函数原型    int floodFill(InputOutputArray image, InputOutputArray mask, Point seedPoint, Scalar newVal, Rect* rect=0, Scalar loDiff

shuwu 7983

C++ opencv 截取任意形状封闭图形

C++ opencv 截取任意形状封闭图形

qq_51054915的博客 2013

提取图片中任意形状的区域

提取图片中任意形状的区域      http://www.cnblogs.com/saintbird/archive/2008/10/27/1305003.html正在做一个基于内容的图像检索项目,客户要求可以让用户提取图片上的任意形状的子图作为输入。为了实现这个功能,花了不少精力,中间绕了不少圈子。现在问题总算解决了,把主要的思路记录一下,希望能帮到有同样需求的朋友。

ding_net的专栏 1106

提取图片中任意形状的区域(我的简单修改及代码)

http://hi.baidu.com/beansteven/item/c007875e89d43fced3e10cdd     我根据这位达人的信息http://hi.baidu.com/yibobin/blog/item/a55e162a7b18273ad52af164.html 将其程序简单的修改,得出如下实现代码: #include #include #pragma 

xgwdy06的专栏 1614

Opencv 如何获取roi区域

然后通过图像的基本绘制方法(circle/rectangle/ellipse/polylines/fillpoly/drawContours)绘制基本图形,并将绘制的图形进行填充(注意一定要填充为非0值,这与掩膜的原理有关系,只有mask掩膜的值非0的区域才会进行操作,以setto为例,第二个参数就是mask,mask中非0的位置才会将第一个参数的值付给对应位置的像素)。上述两种获取roi的方式是通过重载()运算符实现的,根据上面的描述可以看到通过上面两种方法仅可以实现矩形roi区域的获取。

漫步者 1722
上一篇: win10笔记本虚拟机上装centos7系统
下一篇: 在win10系统安装python,配置opencv
Traveling_DING
博客等级 码龄12年 65粉丝 29原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值