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

  • 操作系统: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;
}

运行结果

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LabVIEW遇到无法控制国外设备时怎么办

当使用LabVIEW遇到无法控制国外产品的问题时&#xff0c;解决此类问题需要系统化的分析和处理方法。以下是详细的解决思路和具体办法&#xff0c;以及不同方法的分析和比较&#xff0c;包括寻求代理、国外技术支持、国内用过的人请教等内容。 1. 了解产品的通信接口和协议 思路…

修复:cannot execute binary file --- ppc64le 系统架构

前言&#xff1a; 修复node_exporter,引用pprof包&#xff0c;对源码编译后在 Linux 系统下执行程序运行时&#xff0c;发生了报错&#xff0c;报错信息&#xff1a;cannot execute binary file: Exec format error。 开始以为编译有问题&#xff0c;检查发现&#xff1b;该l…

从零入门激光SLAM(十三)——LeGo-LOAM源码超详细解析3

大家好呀&#xff0c;我是一个SLAM方向的在读博士&#xff0c;深知SLAM学习过程一路走来的坎坷&#xff0c;也十分感谢各位大佬的优质文章和源码。随着知识的越来越多&#xff0c;越来越细&#xff0c;我准备整理一个自己的激光SLAM学习笔记专栏&#xff0c;从0带大家快速上手激…

Python3极简教程(一小时学完)上

开始 Python 之旅 本教程基于 Python for you and me 教程翻译制作&#xff0c;其中参考了 Python tutorial 和 _The Python Standard Library_&#xff0c;并对原教程的内容进行了改进与补充。 相关链接地址如下&#xff1a; _Python tutorial_&#xff1a;Python 入门指南…

通过颜色传感器控制机械臂抓物体

目录 1 绪论 2整体设计方案 2.1 系统的介绍 2.2 抓取模块 2.2.1 机械臂的定义 2.2.2 机械臂的分类 2.2.3 机械臂的选用 2.3 颜色识别模块 2.3.1 颜色传感器识别原理 2.3.2 TCS3200简介 2.4 整体控制方案 3 颜色识别抓取系统的硬件设计 3.1 单片机选型及参数 3.2 系…

13.爬虫---PyMongo安装与使用

13.PyMongo安装与使用 1.安装 PyMongo2.使用PyMongo2.1连接数据库和集合2.2增加数据2.3修改数据2.4查询数据2.5删除数据 3.总结 MongoDB 安装可以看这篇文章MongoDB安装配置教程&#xff08;详细版&#xff09; 1.安装 PyMongo PyMongo 是Python中用于连接MongoDB数据库的库&a…

适用于 Windows 11 的 5 大数据恢复软件 [免费和付费]

为什么我们需要Windows 11数据恢复软件&#xff1f; 计算机用户经常遇到的一件事就是数据丢失&#xff0c;这种情况随时可能发生。错误地删除重要文件和文件夹可能会非常令人担忧&#xff0c;但幸运的是&#xff0c;有一种方法可以恢复 PC 上丢失的数据。本文将向您展示可用于…

AI引领创意潮流:高效生成图片,参考图助力,一键保存到指定文件夹

在这个数字与创意交融的时代&#xff0c;我们迎来了AI绘画的新纪元。借助先进的AI技术&#xff0c;我们不仅能够高效生成图片&#xff0c;还能在参考图的启发下&#xff0c;激发无限创意&#xff0c;让您的想象力在数字世界中自由翱翔。 首助编辑高手软件中的魔法智能绘图板块&…

路径规划算法--DFS

文章目录 一、DFS二、DFS伪代码三、DFS做全覆盖路径 一、DFS DFS&#xff08;Depth First Search&#xff09;为深度优先搜索&#xff0c;是一种用于遍历或搜索树或图的搜索算法。DFS是从当前点出发&#xff0c;沿着一个方向一直搜索&#xff0c;如果搜索完成且未搜索到目标点…

C++系列-String(三)

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” assign 这个接口的目的是用一个新的值代替之前的那个值 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<string> #include<list> #include&l…

HTTP协议中的各种请求头、请求类型的作用以及用途

目录 一、http协议介绍二、http协议的请求头三、http协议的请求类型四、http协议中的各种请求头、请求类型的作用以及用途 一、http协议介绍 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是一种用于分布式、协作式和超媒体信息系统的应…

计算机组成原理 | CPU子系统(3)MIPS32指令架构

MIPS32架构指令格式 MIPS32架构寻址方式 指令的编码与功能

突破内存限制:Jamba模型的高效文本处理能力

在当今信息爆炸的时代&#xff0c;处理和理解海量文本数据的需求日益增长。自然语言处理&#xff08;NLP&#xff09;领域的研究者们一直在探索如何构建更高效、更强大且更灵活的语言模型来应对这一挑战。然而&#xff0c;现有的大型语言模型&#xff0c;尤其是基于Transformer…

昇思25天学习打卡营第8天|保存与加载

一、简介&#xff1a; 上一章节主要介绍了如何调整超参数&#xff0c;并进行网络模型训练。在训练网络模型的过程中&#xff0c;实际上我们希望保存中间和最后的结果&#xff0c;用于微调&#xff08;fine-tune&#xff09;和后续的模型推理与部署&#xff0c;本章节我们将介绍…

关于Vite+Vue+Ts WebStorm路径别名的问题

一、准备一个项目 二、在 vite.config.js 中添加 resolve: {alias: {: /src}} 三、tsconfig.app.json中添加代码 //添加代码"baseUrl": ".","paths": {"/*": ["src/*"]}把src的一个文件修改路径为开头 四、安装插件 npm i …

【嵌入式Linux】i.MX6ULL GPIO 中断服务函数注册与编写

文章目录 1 外部中断初始化与中断服务函数1.2 外部中断初始化函数 exti_init1.2.1 GPIO引脚配置1.2.2 中断使能与注册1.2.3 GIC_EnableIRQ()函数的分析 1.3 中断服务函数 gpio1_io20_irqhandler1.3.1 消抖处理1.3.2 中断事件处理1.3.3 清除中断标志 2 BUG处理2.1 问题描述2.2 解…

打破数据分析壁垒:SPSS复习必备(九)

有序定性资料统计推断 1.分类 单向有序行列表 双向有序属性相同行列表 双向有序属性不同行列表 2.单向有序行列表 秩和检验 ① 两组单向有序分类资料 ②多组单向有序定性资料 步骤&#xff1a; 1.建立检验假设和确定检验水准 2.编秩 3.求秩和 4.确定检验统计量 5…

Sora:探索AI视频模型的无限可能

随着人工智能技术的飞速发展&#xff0c;AI在视频处理和生成领域的应用正变得越来越广泛。Sora&#xff0c;作为新一代AI视频模型&#xff0c;展示了前所未有的潜力和创新能力。本文将深入探讨Sora的功能、应用场景以及它所带来的革命性变化。 一、Sora的核心功能 1.1 视频生…

一年Java|16K|同程艺龙面经

面经哥只做互联网社招面试经历分享&#xff0c;关注我&#xff0c;每日推送精选面经&#xff0c;面试前&#xff0c;先找面经哥 背景 公司&#xff1a;同程艺龙成都BU,现场部门老大面 之前的同程艺龙电话一面过了&#xff0c;然后通知到同程艺龙成都办公地点现场进行部门老大…

宠物空气净化器热卖爆款,希喂、小米、352猫用空气净化器真实PK

相信大漫天多数养猫家庭都会有一个烦恼&#xff1a;猫咪们的猫实在是太多了&#xff0c;无法忍受家里面漫天飞舞的浮毛和难闻的猫猫便臭。作为养猫多年的过来人我尝试过很多种方法清理这些猫浮毛和异味&#xff0c;但都以失败告终。 直到后面看到一个宠物博主推荐的宠物空气净…