OpenCV中掩膜(mask)图像的创建和使用

news2024/11/23 1:44:19
  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

功能描述

掩模图像(Mask Image)是一种特殊类型的形象数据,在图像处理和计算机视觉中扮演着重要角色。它通常是一个二维数组,与原始图像具有相同的尺寸,其上的每个像素值用来指示对应于原始图像中像素的处理方式。掩模图像主要使用两种基本值:非零值(通常是白色,255)和零值(通常是黑色,0)。这些值分别代表“感兴趣区域”(ROI, Region of Interest)和不感兴趣的区域。

掩模的主要用途包括:

区域选择:在图像处理操作中,仅对掩模中标记为非零的区域应用滤镜、颜色调整或其他效果,而忽略零值区域。
形状提取:结合位运算,从复杂图像中精确提取特定形状或对象。
图像分割:帮助分离前景和背景,尤其是在对象识别和跟踪任务中。
Alpha通道:在图形设计中,掩模可以作为alpha通道来控制透明度,实现图像合成。
数据屏蔽:在数据分析中,用于排除不需要分析的数据部分。
形态学操作:结合膨胀、腐蚀等操作,用于特征增强或去除噪声。

fillPoly() 函数

fillPoly() 的功能是填充由一个或多个多边形所限定的区域。
cv::fillPoly函数用于填充由多个多边形轮廓所限定的区域。该函数能够填充复杂的区域,例如含有空洞的区域、自身相交的轮廓(它们的部分),等等。

原型1


void cv::fillPoly	
(	
	InputOutputArray 	img,
	InputArrayOfArrays 	pts,
	const Scalar & 	color,
	int 	lineType = LINE_8,
	int 	shift = 0,
	Point 	offset = Point() 
)		

参数1

  • 参数 img 图像.
  • 参数 pts 多边形数组,其中每个多边形由顶点数组表示。
  • 参数 color 多边形颜色.
  • 参数 lineType 多边形边线的颜色. 见 LineTypes
  • 参数 shift 顶点坐标中的小数位数.
  • 参数 offset 可选参数,轮廓上所有点的偏移量.

原型2


void cv::fillPoly	
(	
InputOutputArray 	img,
const Point ** 	pts,
const int * 	npts,
int 	ncontours,
const Scalar & 	color,
int 	lineType = LINE_8,
int 	shift = 0,
Point 	offset = Point() 
)		

参数2

  • 参数 img 图像.
  • 参数 pts 多边形数组,其中每个多边形由顶点数组表示。
  • 参数 npts 多边形数组的个数。
  • 参数 ncontours 轮廓的数量
  • 参数 color 多边形颜色.
  • 参数 lineType 多边形边线的颜色. 见 LineTypes
  • 参数 shift 顶点坐标中的小数位数.
  • 参数 offset 可选参数,轮廓上所有点的偏移量.

bitwise_and()函数

函数cv::bitwise_and用于计算两个数组或一个数组与一个标量之间的逐元素按位逻辑与运算。具体规则如下:

  1. 当src1和src2尺寸相同时:
    对于数组中的每个元素I,若mask(I)不等于0,则执行按位与运算:
    dst ( I ) = src1 ( I ) ∧ src2 ( I ) if   mask ( I ) ≠ 0 \texttt{dst} (I) = \texttt{src1} (I) \wedge \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0 dst(I)=src1(I)src2(I)if mask(I)=0
    这意味着只有当mask在该位置上为非零值时,才会在dst中存储src1和src2对应位置的按位与结果。
  2. 一个数组和一个标量运算,当src2由Scalar构造或其元素数量与src1.channels()相同:
    同样地,若mask(I)非零,则dst中的元素通过src1的元素与标量src2的按位与得到:
    dst ( I ) = src1 ( I ) ∧ src2 if   mask ( I ) ≠ 0 \texttt{dst} (I) = \texttt{src1} (I) \wedge \texttt{src2} \quad \texttt{if mask} (I) \ne0 dst(I)=src1(I)src2if mask(I)=0
    这里,标量src2会被转换成与src1相同类型的数组,然后进行逐元素运算。
  3. 一个标量和一个数组运算,当src1由Scalar构造或其元素数量与src2.channels()相同:
    类似地,若mask(I)非零,则按位与的结果由src1和src2(I)决定:
    dst ( I ) = src1 ∧ src2 ( I ) if   mask ( I ) ≠ 0 \texttt{dst} (I) = \texttt{src1} \wedge \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0 dst(I)=src1src2(I)if mask(I)=0
    这里,src1作为标量参与运算,先被转换为与src2相同类型的数组形式。

对于浮点数数组,它们的按位运算基于机器特定的位表示(通常是遵循IEEE754标准)。而对于多通道数组,每个通道独立进行上述操作。在后两种情况中,标量会首先被转换为与数组相匹配的类型,然后再进行运算。

原型

void cv::bitwise_and	
(	
	InputArray 	src1,
	InputArray 	src2,
	OutputArray 	dst,
	InputArray 	mask = noArray() 
)		

参数

  • 参数 src1 第一个输入数组或一个标量.
  • 参数 src2 第二个输入数组或一个标量.
  • 参数 dst 输出数组,与输入数组具有相同的尺寸和类型.
  • 参数 mask 可选的操作掩码,一个8位单通道数组,用于指定输出数组中需要更改的元素.

代码示例

以下代码,可以在Source窗口中用鼠标左键点击选择点,这些点就是轮廓的顶点,在你点击的时候,会把点用线连起来,形成轮廓,然后点击右键开始创建掩膜。单击中键重新开始画轮廓。

#include "opencv2/highgui.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
Mat src, img1, mask, final;
Point point;
vector< Point > pts;
int drag = 0;
int var  = 0;
int flag = 0;
void mouseHandler( int, int, int, int, void* );
void mouseHandler( int event, int x, int y, int, void* )
{
    if ( event == EVENT_LBUTTONDOWN && !drag )
    {
        if ( flag == 0 )
        {
            if ( var == 0 )
                img1 = src.clone();
            point = Point( x, y );
            circle( img1, point, 2, Scalar( 0, 0, 255 ), -1, 8, 0 );
            pts.push_back( point );
            var++;
            drag = 1;
            if ( var > 1 )
                line( img1, pts[ var - 2 ], point, Scalar( 0, 0, 255 ), 2, 8, 0 );
            imshow( "Source", img1 );
        }
    }
    if ( event == EVENT_LBUTTONUP && drag )
    {
        imshow( "Source", img1 );
        drag = 0;
    }
    if ( event == EVENT_RBUTTONDOWN )
    {
        flag = 1;
        img1 = src.clone();
        if ( var != 0 )
        {
            polylines( img1, pts, 1, Scalar( 0, 0, 0 ), 2, 8, 0 );
        }
        imshow( "Source", img1 );
    }
    if ( event == EVENT_RBUTTONUP )
    {
        flag  = var;
        final = Mat::zeros( src.size(), CV_8UC3 );
        mask  = Mat::zeros( src.size(), CV_8UC1 );
        fillPoly( mask, pts, Scalar( 255, 255, 255 ), 8, 0 );
        bitwise_and( src, src, final, mask );
        imshow( "Mask", mask );
        imshow( "Result", final );
        imshow( "Source", img1 );
    }
    if ( event == EVENT_MBUTTONDOWN )
    {
        pts.clear();
        var  = 0;
        drag = 0;
        flag = 0;
        imshow( "Source", src );
    }
}
int main( int argc, char** argv )
{
    cout << "\n\tleft mouse button - set a point to create mask shape\n"
            "\tright mouse button - create mask from points\n"
            "\tmiddle mouse button - reset\n";

    

    src = imread( "/media/dingxin/data/study/OpenCV/sources/images/fruit.jpg", cv::IMREAD_GRAYSCALE );
    if ( src.empty() )
    {
        printf( "Error opening image" );
        return 0;
    }

    Size sz2Sh( 300, 300 );
   
    Mat queryToShow;
    resize( src, src, sz2Sh, 0, 0, INTER_LINEAR_EXACT );

    namedWindow( "Source", WINDOW_AUTOSIZE );
    setMouseCallback( "Source", mouseHandler, NULL );
    imshow( "Source", src );
    waitKey( 0 );
    return 0;
}

运行结果

原始图:
在这里插入图片描述

画轮廓过程:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
掩膜图:
在这里插入图片描述
应用结果图:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1865874.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uniapp H5端使用百度地图

1、登录百度地图开放平台 https://lbsyun.baidu.com/&#xff08;没有账号则先去创建一个百度账号&#xff09; 2、进入百度地图开放平台控制台&#xff08;导航栏“控制台”&#xff09;&#xff0c;点击“应用管理”-“我的应用” 3、选择“创建应用”&#xff0c;应用模块选…

还不会找1688对标竞品?那你别说自己是做运营的

如何找正确的对标竞品 找到竞品→模仿竞品→学习竞品 找到正确的对标竞品&#xff0c;是至关重要的一个环节&#xff0c;如果你想要把流量做起来&#xff0c;却没找到正确的对标竞品是完全不可能的。因为你没有对标&#xff0c;你就完全不知道同行做什么动作才有流量&#xf…

Opencv学习项目2——pytesseract

上一次我们使用pytesseract.image_to_boxes来检测字符&#xff0c;今天我们使用pytesseract.image_to_data来检测文本并显示 实战教程 和上一次一样&#xff0c;添加opencv-python和pytesseract库 首先我们先来了解一下pytesseract.image_to_data pytesseract.image_to_data(…

k8s手撕架构图+详解

“如果您在解决类似问题时也遇到了困难&#xff0c;希望我的经验分享对您有所帮助。如果您有任何疑问或者想分享您的经历&#xff0c;欢迎在评论区留言&#xff0c;我们可以一起探讨解决方案。祝您在编程路上顺利前行&#xff0c;不断突破技术的难关&#xff0c;感谢您的阅读&a…

MySQL 超出月份最大日期(工作总结)

前几天帮同事修改了一个bug&#xff0c;这个bug是怎么造成的呢。先来看需求&#xff0c;系统需要统计某个月份的数据。很简单的一个需求。 同事的写的MySQL语句 SELECTREPLACE(FORMAT(sum(count_value),2), ,, ) as value,<if test"type day">count_date as…

Vue-内容渲染,属性渲染指令

内容渲染 在Vue中渲染元素&#xff0c;用双花括号{{}}的语法进行插值&#xff0c;称之为插值表达式 双花括号会渲染hi里面的值 <body><div id"app">{{hi}}</div> <script>const vm{data(){return{hi:hello world}}}const appVue.createAp…

【containerd】Containerd高阶命令行工具nerdctl

前言 对于习惯了使用docker cli的用户来说&#xff0c;containerd的命令行工具ctr使用起来不是很顺手&#xff0c;此时别慌&#xff0c;还有另外一个命令行工具项目nerdctl可供我们选择。 nerdctl是一个与docker cli风格兼容的containerd的cli工具。 nerdctl已经作为子项目加入…

u盘插到另一台电脑上数据丢失怎么办?提供实用的解决方案

在现代数字化生活中&#xff0c;U盘作为一种便携式存储设备&#xff0c;承载着我们重要的数据和信息。然而&#xff0c;有时当我们将U盘插入另一台电脑时&#xff0c;可能会遇到数据丢失的棘手问题。这可能是由于多种原因造成的&#xff0c;那么&#xff0c;U盘插到另一台电脑上…

cs与msf权限传递,与mimikatz抓取win2012明文密码

CS与MSF的权限互相传递抓取windows2012的明文密码 CS与MSF的权限互相传递 1、启动cs服务端 2、客户端连接 3、配置监听&#xff0c;并设置监听端口为9999 4、生成脚本 5、开启服务&#xff0c;下载并运行木马 已获取权限 6、进入msf并设置监听 7、cs新建监听&#xff0c;与m…

20240626让飞凌的OK3588-C开发板在相机使用1080p60分辨率下预览

20240626让飞凌的OK3588-C开发板在相机使用1080p60分辨率下预览 2024/6/26 15:15 4.2.1 全编译测试 在源码路径内&#xff0c;提供了编译脚本 build.sh&#xff0c;运行该脚本对整个源码进行编译&#xff0c;需要在终端切换到解压 出来的源码路径&#xff0c;找到 build.sh 文件…

海纳斯 hinas 的hi3798mv100 华为悦盒 6108v9 安装wifi模块

hi3798mv100安装wifi模块 1.执行脚本 &#xff0c;执行完毕后重启服务器2. 继续执行脚本3.检查网卡驱动安装是否正确4.查看网卡安装状态5.连接wifi结尾 1.执行脚本 &#xff0c;执行完毕后重启服务器 bash <(curl -sSL https://gitee.com/xjxjin/scripts/raw/main/install_…

【LeetCode】三、队列相关:最近的请求次数

文章目录 1、队列结构2、leetcode933&#xff1a;最近的请求次数 1、队列结构 先进先出 时间复杂度&#xff1a; Java中&#xff0c;LinkedList集合可以当一个队列来用&#xff1a; 2、leetcode933&#xff1a;最近的请求次数 很逆天的题目描述&#xff0c;就是不同时间会有请…

关于WebSocket

WebSocket 与传统的 HTTP 协议对比 在实时通信领域&#xff0c;传统的 HTTP 协议存在以下一些问题&#xff1a; 频繁的请求和响应&#xff1a;每次通信都需要建立和关闭连接&#xff0c;带来额外的开销。高延迟&#xff1a;每次通信都需要经过多个网络层的传输&#xff0c;延…

【仿真】UR机器人手眼标定与实时视觉追踪(单目)

这段代码实现了一个机器人视觉引导系统,主要功能包括: 连接仿真环境,控制UR机器人。相机标定: 使用棋盘格图案进行相机内参标定通过移动机器人采集多组图像使用calibrateCamera函数计算相机内参 手眼标定: 采集机器人末端位姿和对应的棋盘格图像使用calibrateHandEye函数计算相…

外汇的基本面分析需要关注什么?

外汇基本面分析的核心在于关注可能影响单一货币供求及国家货币价值的经济、社会和地缘政治事件与趋势。但值得注意的是&#xff0c;这些事件和因素往往具有更广泛的影响力&#xff0c;不仅限于单一国家。它们可能是影响整个地区或国家集团的重要事件&#xff0c;甚至一些事件&a…

植物大战僵尸杂交版技巧大全(附下载攻略)

《植物大战僵尸杂交版》为策略游戏爱好者带来了全新的挑战和乐趣。如果你是新手玩家&#xff0c;可能会对游戏中的植物和僵尸感到困惑。以下是一些实用的技巧&#xff0c;帮助你快速掌握游戏并享受其中的乐趣。 技巧一&#xff1a;熟悉基本玩法 游戏的基本玩法与原版相似&…

大自然高清风景视频无水印素材在哪下载?下载视频素材网分享

在视频创作领域&#xff0c;一段高清的风景视频可以极大地提升你的作品质感。无论是作为背景、过渡片段还是主要内容&#xff0c;优质的风景视频素材都是必不可少的。然而&#xff0c;寻找既高清又无水印的风景视频素材并非易事。为了帮助大家轻松获取这类素材&#xff0c;我整…

七天速通javaSE:第四天 递归算法

文章目录 前言一、递归的介绍二、递归模型&#xff08;n!&#xff09;1 阶乘的定义&#xff1a;2. 阶乘的递归代码实现3. 递推与回归的内部逻辑三、练习 前言 本文将学习递归算法。在计算机科学中&#xff0c;递归算法是一种将问题不断分解 为同一类子问题来解决问题的方法。递…

网站推广如何做?这七个方法要知道

在出海独立站商家中&#xff0c;推广是必不可少的环节。在你完成网站的搭建&#xff0c;产品的上架&#xff0c;以及网站的运营和优化后&#xff0c;你就可以开始着手推广你的网站了。你的网站是承载你的品牌和产品的主要平台&#xff0c;因此&#xff0c;你需要根据你的品牌和…

Python+Vue+Springboot实现电脑端微信好友导入导出

主要实现思路是使用python的自动化库uiautomation进行客户端抓取联系人&#xff0c;vue做管理界面&#xff0c;springboot做后端服务。 截图如下 登录&#xff1a; 首页 好友导出 不足之处就是只有windows版本&#xff0c;mac上还不行 而且谷歌和edge浏览器的效果是最好的&a…