作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

需求说明

在对图像进行处理时,经常会有这类需求:想对感兴趣区域进行掩膜处理,只操作掩膜内数据,此时需要搭配掩膜绘制功能,并在绘制过程中希望能区分掩膜区和非掩膜区;除了掩膜本身的线条以外,还希望掩膜内图像是原色,掩膜外图像的颜色进行一定调整;通常可以采用图像透明化或者色彩单通道加深的方式实现。

比如对三通道的图像,可以将掩膜外数据的红通道数值提高,此时该部分图像就会偏红色,如下图1所示。

图1 颜色加深的蒙版效果

但是针对灰度图,因为图像数据本身就是单通道的,就不能借用颜色通道或者透明通道了;有一个基础的办法是将非掩膜区数据同时加减某个数值,这种方法简单但有一个弊端,比如我加了50,那原图200-255之间的数值都将变为255,这样就损坏了原图的某些特征信息。为此,我们采用非线性的算法将其进行较为合理的数值调整。

下面介绍具体实现流程。

具体流程

1)构造非线性参数。其中n为函数输入的参数,范围在-100到100;a、b、k为算法参数,公式见下。

n = min(max(n, -100), 100);
int k = 4;
float b = n / 100.f / k;
float a = 1.0f + k * b;

2)参照上式,对掩膜外数据进行如下处理。

float temp = pow(float(in[j]) / 255.f, 1.0f / a) * (1.0 / (1 + b));

3)temp的数值需要进行校准,因为灰度值如果是uchar型,范围在0-255之间,校准后乘上255,即可得到算法计算的结果。

if (temp > 1.0f)temp = 1.0f;
if (temp < 0.0f)temp = 0.0f;
uchar utemp = uchar(255 * temp);
r[j] = utemp;

4)掩膜内数值保持不变。

r[j] = in[j];

5)输出图像,完成。

功能函数

// 灰度图蒙版
cv::Mat GrayMask(cv::Mat input, cv::Mat mask, int n)
{// 通道判断if (input.channels() != 1){return input;}// 非线性参数// 当n=100时,非掩膜区呈灰色;当n=0时,非掩膜区无变化;当n=-100时,非掩膜区黑色// n越小,非掩膜区越暗,n越大,非掩膜区越灰// 目的是区分非掩膜区和掩膜区n = min(max(n, -100), 100);int k = 4;float b = n / 100.f / k;float a = 1.0f + k * b;// 蒙版处理cv::Mat result = cv::Mat::zeros(input.size(), input.type());for (int i = 0; i < input.rows; ++i){uchar *m = mask.ptr<uchar>(i);uchar *in = input.ptr<uchar>(i);uchar *r = result.ptr<uchar>(i);for (int j = 0; j < input.cols; ++j){if (m[j] == 0){float temp = pow(float(in[j]) / 255.f, 1.0f / a) * (1.0 / (1 + b));if (temp > 1.0f)temp = 1.0f;if (temp < 0.0f)temp = 0.0f;uchar utemp = uchar(255 * temp);r[j] = utemp;}else {r[j] = in[j];}}}return result;
}

C++测试代码

#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <stdio.h>
#include <io.h>
#include <chrono>
#include <time.h>
#include <stdio.h>
#include <direct.h>
#include <ctime>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>using namespace std;
using namespace cv;cv::Mat GrayMask(cv::Mat input, cv::Mat mask, int n);int main()
{// 读取灰度图cv::Mat src = imread("1.png",0);// 绘制掩膜cv::Mat mask = cv::Mat::zeros(src.size(), CV_8UC1);cv::circle(mask, cv::Point(src.cols / 2, src.rows / 2), 100, cv::Scalar(255), -1);// 灰度图蒙版cv::Mat result = GrayMask(src, mask, 100);// 结果显示imshow("src", src);imshow("result", result);waitKey(0);system("pause");return 0;
}// 灰度图蒙版
cv::Mat GrayMask(cv::Mat input, cv::Mat mask, int n)
{// 通道判断if (input.channels() != 1){return input;}// 非线性参数// 当n=100时,非掩膜区呈灰色;当n=0时,非掩膜区无变化;当n=-100时,非掩膜区黑色// n越小,非掩膜区越暗,n越大,非掩膜区越灰// 目的是区分非掩膜区和掩膜区n = min(max(n, -100), 100);int k = 4;float b = n / 100.f / k;float a = 1.0f + k * b;// 蒙版处理cv::Mat result = cv::Mat::zeros(input.size(), input.type());for (int i = 0; i < input.rows; ++i){uchar *m = mask.ptr<uchar>(i);uchar *in = input.ptr<uchar>(i);uchar *r = result.ptr<uchar>(i);for (int j = 0; j < input.cols; ++j){if (m[j] == 0){float temp = pow(float(in[j]) / 255.f, 1.0f / a) * (1.0 / (1 + b));if (temp > 1.0f)temp = 1.0f;if (temp < 0.0f)temp = 0.0f;uchar utemp = uchar(255 * temp);r[j] = utemp;}else {r[j] = in[j];}}}return result;
}

测试效果

图2 原图

图3 灰度图蒙版效果

如果函数有什么可以改进完善的地方,非常欢迎大家指出,一同进步何乐而不为呢~

如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

OpenCV-灰度图蒙版GrayMask相关推荐

  1. python opencv 灰度图非局部平均去噪

    python opencv 灰度图非局部平均去噪 代码: import cv2 import numpy as np # 灰度图像去噪 def MeansDenoising(img,h,templat ...

  2. opencv 灰度图

    #include <opencv2/opencv.hpp> Mat srcImg = imread("D://3901781-2.JPG"); // 读取源图像 if  ...

  3. opencv灰度图转伪彩图或彩色图

    一.背景 一般例如红外图像,呈现出来的是灰度图效果,此时每个像素有一个,在0-255内,如果想要观看伪彩图,也就是人工设置的彩色,需要在灰度图的基础上,给它增加RGB三个通道的值,让它变为看起来有红绿 ...

  4. c++ opencv 灰度图转彩色图

    灰度图转彩色图______主要作用:在图上画彩色线条等等 //灰度图转彩色图 cv::Mat grayToRGB(const cv::Mat input_img) {//创建一个和灰度图一样大小的0值 ...

  5. Opencv中除了cv2.cvtColor彩色图转灰度图之外的其他6种方法

    文章目录 1.参考文章: 2.公式集成: 3.代码实现: 4.实验结果: 1.参考文章: https://mp.weixin.qq.com/s/jqVVZbZZRIqVt_Fs7HiUkg 2.公式集 ...

  6. python使用openCV把原始彩色图像转化为灰度图、使用矩阵索引的方式对数据数据进行剪裁(image cropping)

    python使用openCV把原始彩色图像转化为灰度图.使用矩阵索引的方式对数据数据进行剪裁(image cropping) 目录

  7. Python使用openCV把原始彩色图像转化为灰度图、使用OpenCV把图像二值化(仅仅包含黑色和白色的简化版本)、基于自适应阈值预处理(adaptive thresholding)方法

    Python使用openCV把原始彩色图像转化为灰度图.使用OpenCV把图像二值化(仅仅包含黑色和白色的简化版本).基于自适应阈值预处理(adaptive thresholding)方法 目录

  8. cv2 inrange灰度图_Python opencv将图片转为灰度图的方法示例

    这篇文章主要介绍了python opencv将图片转为灰度图的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 使用ope ...

  9. cv2 inrange灰度图_基于openCV,PIL的深色多背景复杂验证码图像转灰度二值化,并去噪降噪处理分析...

    title: [python]基于openCV,PIL的深色多背景复杂验证码图像转灰度二值化,并去噪降噪处理分析 type: categories copyright: true categories ...

最新文章

  1. RayTracking 光线跟踪算法
  2. Pytorch中改变形状和交换维度详解:view()、reshape()、transpose()、permute()以及contiguous()
  3. bzoj 1061: [Noi2008]志愿者招募【最小费用最大流】
  4. SpringBoot+Vue+Echarts实现双柱体柱状图
  5. PHP 运动会,运动会成绩管理系统
  6. 试验设计茆诗松电子版_非标机械设计有哪些设计过程?
  7. leetcode 三数之和 python_16.leetcode题目讲解(Python):最接近的三数之和
  8. 学习之路/免费的图库推荐
  9. 理解流 java 0325
  10. python字符串编码判断
  11. 内网计算机可以使用键盘,如何在同一个局域网里一套键盘鼠标操作多台电脑?...
  12. flink集成springboot案例_集成-Apache Flink+Spring Boot
  13. 根据银行卡号获取开户行和银行LOGO
  14. 怎样快速将pdf在线转换成word免费版
  15. hotmail手机端_hotmail邮箱app下载
  16. CAD参数绘制文字(网页版)
  17. 2.郝斌C语言课程大纲
  18. 韩松手机摄影笔记第八课--手机人物摄影
  19. 1185_SPC560B60L7_ADC0标准通道的Injected转换模式
  20. PHPexcel 导出身份证处理

热门文章

  1. recyclerview嵌套recyclerview
  2. Debug | jupyter notebok 500 : Internal Server Error
  3. Python爬虫之猫眼APP电影数据(十八)
  4. js 实现一个简单的存钱/取钱/查询/退出等操作的ATM功能.
  5. MySQL面试题和答案
  6. Havok物理引擎_百度百科
  7. 用计算机设计购物小票,商友星云系统软件票据和条码标签设计和打印
  8. 墨客与网易云达成战略合作
  9. usb接口驱动_UART串行总线舵机转接板规格、接线说明 amp; 驱动安装
  10. 魔力宝贝服务器端文件介绍,对魔力宝贝数据库的认识,及SQL数据库详细说明