DrGraph原理示教 - OpenCV 4 功能 - 二值化

二值化,也就是处理结果为0或1,当然是针对图像的各像素而言的
1或0,对应于有无,也就是留下有用的,删除无用的,有用的部分,就是关心的部分
在图像处理中,也不仅仅只是1或0,因为这两个值看起来都是黑的,人眼很难分辨清楚,那就放大一些,255或0,黑白就出来了
目标识别、图像分割、目标提取等后续应用,很多会基于二值化的结果。所以图像分析的二值化处理是一个重要环节。比如CSDN的OpenCV技能树:
在这里插入图片描述

广义来说,分析或处理的结果中,各像素点只在0/255间取值,那就算是二值化,所以阈值、腐蚀与膨胀、开运算与闭运算、连通区域分析、轮廓等都算是
但在OpenCV 4中,阈值的结果可能也是彩色图像,开闭运算的输入就是二值化图像… 这个概念可能是错的,因为我还没有从头处理开闭运算。
所以,还是自己按自己的标准来处理,利于理解就行,无所谓对错

inRange

OpenCV中的inRange()函数可以实现图像的二值化,其功能是将在两个阈值内的像素值设置为白色(255),而不在阈值区间内的像素值设置为黑色(0)。函数的语法格式如下:

void cv::inRange(InputArray _src, InputArray _lowerb, InputArray _upperb, OutputArray _dst);

其中,_src表示输入图像,可以是灰度图像或彩色图像;_lowerb表示下界的阈值,可以是一个标量值或与输入图像通道数相同的数组;_upperb表示上界的阈值,与_lowerb的类型相同,指定上界阈值;_dst表示输出图像,用于存储计算得到的阈值图像。
在这里插入图片描述
二值图像,可作为copyTo的参数,实现原图的部分拷贝
在这里插入图片描述
具体实现代码:

    cv::Mat originMat = dstMat.clone();int paramIndex = 0;bool combineMaskFlag = GetParamValue_Bool(paramIndex++);    // 0 - 过滤原图显示int min0 = GetParamValue_Int(paramIndex++);   // 1 - 通道0下限int max0 = GetParamValue_Int(paramIndex++);   // 2 - 通道0上限int min1 = GetParamValue_Int(paramIndex++);   // 3 - 通道1下限int max1 = GetParamValue_Int(paramIndex++);   // 4 - 通道1上限int min2 = GetParamValue_Int(paramIndex++);   // 5 - 通道2下限int max2 = GetParamValue_Int(paramIndex++);   // 6 - 通道2上限int dim = dstMat.channels();cv::Mat maskMat;if(dim == 1)inRange(dstMat, Scalar(min0), Scalar(max0), dstMat);if(dim == 2)inRange(dstMat, Scalar(min0, min1), Scalar(max0, max1), dstMat);if(dim >= 3)inRange(dstMat, Scalar(min0, min1, min2), Scalar(max0, max1, max2), dstMat);if(combineMaskFlag)originMat.copyTo(dstMat, dstMat);

基准偏差过滤

二值化本质上是针对各像素点进行逻辑判断处理。想明白这点,那就可以实现色通,即在指定彩色颜色相邻区域内OK,其余颜色不再关心。比如绿幕抠图,那就把绿色颜色干掉,只留下其余部分,也就是前景。好象这里说反了,不过理解起来是一样的。
基准偏差,那就是有基准,有偏差,在这个范围内是期望的,出了这个范围就不OK
在这里插入图片描述
基准可以是灰度、单通道或彩色,代码写起来很简单,我整成功能函数,以便后续调用

    cv::Mat originMat = dstMat.clone();int paramIndex = 0;bool combineMaskFlag = GetParamValue_Bool(paramIndex++);    // 0 - 过滤原图显示bool reverseFlag = GetParamValue_Bool(paramIndex++);        // 1 - 反相int channelType = GetParamValue_Int(paramIndex++);          // 2 - 基准类型QColor baseColor = GetParamValue_Color(paramIndex++);       // 3 - 基准值int delta = GetParamValue_Int(paramIndex++);                // 4 - 偏差量if(channelType != 5) { // 灰度基本偏差if(channelType == 4)    // 灰度图dstMat = CvHelper::ToMat_GRAY(dstMat);else {  // 目标单通道// 首先要确保有相应的通道存在int dstChannelNumber = channelType + 1;if(dstChannelNumber == 2)dstChannelNumber = 3;if(dstMat.channels() < dstChannelNumber)dstMat = CvHelper::ChangeMatDim(dstMat, dstChannelNumber);std::vector<cv::Mat> channels;split(dstMat, channels);dstMat = channels[channelType];}dstMat = CvHelper::BuildTransMaskMat(dstMat, baseColor.red() % 0x100, delta);} else { // 彩色基本偏差dstMat = CvHelper::BuildTransMaskMat(dstMat, baseColor, delta);}if(reverseFlag)bitwise_not(dstMat, dstMat);if(combineMaskFlag)originMat.copyTo(dstMat, dstMat);// 生成MASK屏蔽图形 - 彩色基准偏差 - 色通 -> transColor ± delta之间通过,之外不过
Mat CvHelper::BuildTransMaskMat(cv::Mat &srcMat, QColor transColor, BYTE delta) {cv::Mat bgrMat = ToMat_BGR(srcMat);BYTE r = transColor.red();BYTE g = transColor.green();BYTE b = transColor.blue();BYTE maxR = std::min(255, int(r + delta));BYTE minR = std::max(0,   int(r - delta));BYTE maxG = std::min(255, int(g + delta));BYTE minG = std::max(0,   int(g - delta));BYTE maxB = std::min(255, int(b + delta));BYTE minB = std::max(0,   int(b - delta));cv::Mat maskMat;inRange(bgrMat, Scalar(minB, minG, minR), Scalar(maxB, maxG, maxR), maskMat);return maskMat;
}
// 生成MASK屏蔽图形 - 灰度基准偏差 - 灰通 -> transByte ± delta之间通过,之外不过
Mat CvHelper::BuildTransMaskMat(cv::Mat &srcMat, BYTE transByte, BYTE delta) {cv::Mat grayMat = ToMat_GRAY(srcMat);cv::Mat resultMat(grayMat.rows, grayMat.cols, CV_8UC1);BYTE * pSrc = grayMat.data;BYTE * pDst = resultMat.data;int low = transByte - delta, high = transByte + delta;BYTE LOW = std::max(0, low);BYTE HIGH = std::min(0xFF, high);for(int row = 0; row < grayMat.rows; ++row)for(int col = 0; col < grayMat.cols; ++col) {BYTE v = *pSrc++;BYTE value = 0x0;if(IS_IN_RANGE(v, LOW, HIGH))value = 0xFF;*pDst++ = value;}return resultMat;
}

在这里插入图片描述

分量偏差过滤

与基准偏差过滤对应的是分量偏差过滤,即各像素点分量差在目标范围内/外作为选择判断的基准。代码就太简单了。运行效果如下图所示。
在这里插入图片描述
为更实用,在逻辑处理前,先将图像转化为RGB三通道,不含A通道即可。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ES6语法(五)封装模块化公共工具函数、引入npm包 ,并上传到npm中进行下载

1. 模块化 模块化是指将一个大的程序文件&#xff0c;拆分为许多小的文件&#xff08;模块&#xff09;&#xff0c;然后将小的文件组合起来。 1.1. 优点 &#xff08;1&#xff09;防止命名冲突 &#xff08;2&#xff09;代码复用 &#xff08;3&#xff09;高维护性 &…

【快速全面掌握 WAMPServer】06.整明白 PHP

网管小贾 / sysadm.cc 我们今天就要来学习了解一下作为 LAMP 四剑客之一的 PHP 。 PHP 是 Hypertext Preprocessor 即“超文本预处理器”的缩写&#xff0c;是在服务端执行的一种脚本程序语言。 通常它被用于 Web 开发&#xff0c;并可以嵌入 HTML 中&#xff0c;是具有交互功…

yolov5单目测距+速度测量+目标跟踪(算法介绍和代码)

YOLOv5模型介绍 YOLOv5是目前最先进的目标检测算法之一&#xff0c;在多个数据集上取得了优秀的表现。相较于YOLOv4&#xff0c;YOLOv5采用了更深的Backbone网络和更高的分辨率输入图像&#xff0c;以提高检测精度和速度。 1.单目测距实现方法 在目标检测的基础上&#xff…

大模型入门0: 基础知识

transformerscaling law分布式训练 自然语言处理包括几大任务 NLP: 文本分类&#xff0c;词性标注&#xff0c;信息检索NLG&#xff1a;机器翻译&#xff0c;自动摘要&#xff0c;问答QA、对话机器ChatBot下游任务: 词性标注&#xff08;POS&#xff09;&#xff0c;句法分析…

全面分析解决mfc110u.dll丢失的5种方法,简单三步即可搞定

在计算机使用过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中“找不到mfc110u.dll”是常见的一种。mfc110u.dll是Microsoft Foundation Class&#xff08;MFC&#xff09;库中的一个动态链接库文件&#xff0c;它提供了许多用于开发Windows应用程序的函数和类。…

leetcode LCR 170. 交易逆序对的总数(hard)【小林优质解法】

链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 代码&#xff1a; class Solution {int[]help; //归并排序的辅助数组public int reversePairs(int[] record) {int lengthrecord.length;// help 数组的实例化写在递归外面&#xff…

Linux基础知识点(六-共享内存)

一、共享内存基本概念 什么是共享内存&#xff1f;顾名思义&#xff0c;共享内存就是将内存进行共享&#xff0c;它允许多个不相关的进程访问同一个逻辑内存&#xff0c; 直接将一块裸露的内存放在需要数据传输的进程面前&#xff0c;让它们自己使用。因此&#xff0c;共享内存…

PostgreSQL表全解

文章目录 一、 约束1、 主键2、 非空3、唯一4、检查5、外键6、默认值 二、触发器1、构建表信息&#xff0c;填充数据2、触发器函数3、触发器 三、 表空间四、 视图五、索引1、 索引的基本概念2、索引的分类3、创建索引 六、 物化视图 一、 约束 1、 主键 primary key -- 主键…

霍夫曼编码简介

本专栏目录&#xff1a;全球SAR卫星大盘点与回波数据处理专栏目录 算法科普&#xff1a;有趣的霍夫曼编码 前言 霍夫曼编码 ( Huffman coding ) 是一种可变长的前缀码。霍夫曼编码使用的算法是 David A. Huffman 还是在 MIT 的学生时提出的&#xff0c;并且在 1952 年发表了名为…

【电商项目实战】购物车完善

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《电商项目实战》。&#x1f3af;&#x1f3af; &am…

CharRNN实现简单的文本生成

文本数字表示 统计文档中的字符&#xff0c;并且统计字符个数。这里是为了将文字转换为数字表示。 import numpy as np import re import torch class TextConverter(object):def __init__(self,text_path,max_vocab5000):"""建立一个字符索引转换,主要还是为…

C++初阶------------------入门C++

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…