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

OpenCV C++ 中的掩码(Mask)操作

掩码(Mask)是图像处理中常用的技术,它允许我们只对图像的特定部分进行操作。在OpenCV C++中,掩码通常是一个与原始图像尺寸相同的二值图像(0和255),用于指定哪些像素需要处理。

基本掩码操作

1. 创建掩码

#include <opencv2/opencv.hpp>int main() {// 创建一个黑色图像(全0)cv::Mat mask = cv::Mat::zeros(cv::Size(500, 500), CV_8UC1);// 在掩码上画一个白色矩形(255)cv::rectangle(mask, cv::Rect(100, 100, 200, 200), cv::Scalar(255), cv::FILLED);cv::imshow("Mask", mask);cv::waitKey(0);return 0;
}

2. 使用掩码复制图像区域

cv::Mat src = cv::imread("image.jpg");
cv::Mat dst = cv::Mat::zeros(src.size(), src.type());// 只复制mask中非零像素对应的src区域到dst
src.copyTo(dst, mask);
#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;int main() {// 1. 读取源图像Mat src = imread("image.jpg");if (src.empty()) {cout << "无法加载图像!" << endl;return -1;}// 2. 创建目标图像(初始化为黑色)Mat dst = Mat::zeros(src.size(), src.type());// 3. 创建掩码(与源图像同尺寸的单通道图像)Mat mask = Mat::zeros(src.size(), CV_8UC1);// 4. 在掩码上绘制白色区域(255表示要复制的区域)// 示例1: 绘制一个圆形区域circle(mask, Point(src.cols/2, src.rows/2), 150, Scalar(255), -1);// 示例2: 或者绘制矩形区域// rectangle(mask, Rect(100, 100, 300, 200), Scalar(255), -1);// 5. 使用掩码复制图像区域src.copyTo(dst, mask);// 6. 显示结果imshow("原始图像", src);imshow("掩码", mask);imshow("结果图像", dst);waitKey(0);return 0;
}

3. 位运算与掩码

// 与操作
cv::bitwise_and(src1, src2, dst, mask);// 或操作
cv::bitwise_or(src1, src2, dst, mask);// 非操作
cv::bitwise_not(src, dst, mask);// 异或操作
cv::bitwise_xor(src1, src2, dst, mask);

4.复制圆形区域

#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;int main() {// 1. 读取源图像Mat src = imread("image.jpg");if (src.empty()) {cout << "无法加载图像!" << endl;return -1;}// 2. 创建目标图像(初始化为黑色)Mat dst = Mat::zeros(src.size(), src.type());// 3. 创建掩码(单通道,与源图像同尺寸)Mat mask = Mat::zeros(src.rows, src.cols, CV_8UC1);// 4. 在掩码上绘制圆形区域(255表示要复制的区域)circle(mask, Point(src.cols/2, src.rows/2), 150, Scalar(255), -1);// 5. 使用掩码复制图像区域src.copyTo(dst, mask);// 6. 显示结果imshow("原始图像", src);imshow("掩码图像", mask);imshow("结果图像", dst);waitKey(0);return 0;
}

常见应用场景

1. ROI(感兴趣区域)处理

cv::Mat image = cv::imread("image.jpg");
cv::Mat roiMask = cv::Mat::zeros(image.size(), CV_8UC1);// 设置ROI区域
cv::Rect roi(50, 50, 200, 200);
roiMask(roi).setTo(255);// 只处理ROI区域
cv::Mat blurred;
cv::GaussianBlur(image, blurred, cv::Size(5, 5), 0);
blurred.copyTo(image, roiMask);

2. 图像合成

cv::Mat foreground = cv::imread("foreground.png", cv::IMREAD_UNCHANGED);
cv::Mat background = cv::imread("background.jpg");// 从带alpha通道的图像创建掩码
cv::Mat fgMask;
cv::extractChannel(foreground, fgMask, 3); // 提取alpha通道// 合成图像
cv::Mat fgBGR;
cv::cvtColor(foreground, fgBGR, cv::COLOR_BGRA2BGR);
fgBGR.copyTo(background(cv::Rect(100, 100, fgBGR.cols, fgBGR.rows)), fgMask);

3. 基于颜色的掩码

cv::Mat image = cv::imread("image.jpg");
cv::Mat hsv;
cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV);// 创建颜色掩码(例如提取红色区域)
cv::Mat redMask;
cv::inRange(hsv, cv::Scalar(0, 70, 50), cv::Scalar(10, 255, 255), redMask);// 应用掩码
cv::Mat redOnly;
image.copyTo(redOnly, redMask);

4.提取特定颜色区域

#include <opencv2/opencv.hpp>int main() {Mat src = imread("fruits.jpg");Mat hsv, mask, result;// 转换为HSV颜色空间cvtColor(src, hsv, COLOR_BGR2HSV);// 创建颜色掩码(提取红色区域)inRange(hsv, Scalar(0, 70, 50), Scalar(10, 255, 255), mask);// 应用掩码src.copyTo(result, mask);imshow("Original", src);imshow("Mask", mask);imshow("Red Objects", result);waitKey(0);return 0;
}

高级技巧

1. 掩码的膨胀与腐蚀

cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));// 膨胀掩码
cv::dilate(mask, mask, kernel);// 腐蚀掩码
cv::erode(mask, mask, kernel);

2. 掩码边缘模糊

cv::Mat blurredMask;
cv::GaussianBlur(mask, blurredMask, cv::Size(5, 5), 0);// 归一化到0-1范围用于混合
blurredMask.convertTo(blurredMask, CV_32F, 1.0/255);

3.掩码边缘羽化

// 创建模糊边缘的掩码
Mat blurredMask;
GaussianBlur(mask, blurredMask, Size(21,21), 0);// 转换为浮点型用于混合
blurredMask.convertTo(blurredMask, CV_32F, 1.0/255);// 使用混合函数实现羽化效果
Mat result;
src.convertTo(src, CV_32F);
dst.convertTo(dst, CV_32F);
multiply(src, blurredMask, src);
multiply(dst, Scalar::all(1.0)-blurredMask, dst);
add(src, dst, result);
result.convertTo(result, CV_8U);

4. 多掩码组合

// 创建两个不同的掩码
Mat mask1 = Mat::zeros(src.size(), CV_8UC1);
Mat mask2 = Mat::zeros(src.size(), CV_8UC1);
circle(mask1, Point(200,200), 100, Scalar(255), -1);
rectangle(mask2, Rect(150,150,200,200), Scalar(255), -1);// 掩码组合操作
Mat combinedMask;
bitwise_or(mask1, mask2, combinedMask); // 逻辑或
// bitwise_and(mask1, mask2, combinedMask); // 逻辑与
// bitwise_xor(mask1, mask2, combinedMask); // 逻辑异或src.copyTo(dst, combinedMask);

http://www.dtcms.com/a/279675.html

相关文章:

  • 微服务初步入门
  • 设计模式之适配器模式:让不兼容的接口协同工作的艺术
  • Unreal5从入门到精通之如何实现UDP Socket通讯
  • 【C++进阶】---- 多态
  • 解锁文档处理新体验:Python库Agentic Document Extraction
  • OneCode3.0 通信架构简介——MCPServer微内核设计哲学与实现
  • Web学习笔记4
  • 算法训练营day16 513.找树左下角的值、112. 路径总和、106.从中序与后序遍历序列构造二叉树
  • 探索 Sort.h:多功能排序算法模板库
  • [element-ui]el-table在可视区域底部固定一个横向滚动条
  • 智源全面开源RoboBrain 2.0与RoboOS 2.0:刷新10项评测基准,多机协作加速群体智能
  • MCP 第三波升级!Function Call 多步调用 + 流式输出详解
  • QWidget 和 QML 的本质和使用上的区别
  • 慢查询日志监控:定位性能瓶颈的第一步
  • 【抖音滑动验证码风控分析】
  • 小架构step系列14:白盒集成测试原理
  • C# TCP粘包与拆包深度了解
  • spark广播表大小超过Spark默认的8GB限制
  • FatJar打包和FatJar启动配置文件修改。
  • pattern of distributed system 读书笔记-Overview of the Patterns
  • Rsyslog介绍及运用
  • JAVA并发--深入了解CAS机制
  • VirtualBox 安装 CentOS7 后无法获取 IP 的排查与修复
  • 网络请求和下载
  • 在Adobe Substance 3D Painter中,已经有基础图层,如何新建一个图层A,clone基础图层的纹理和内容到A图层
  • Zabbix在MySQL性能监控方面的运用
  • 多线程(6)
  • Rust配置国内源
  • MySql:sql语句中数据库别名命名和查询问题
  • 什么是存储引擎以及MySQL常见的三种数据库存储引擎