美文网首页
28.击中击不中变换(二值图像/结构元素/集合/convertT

28.击中击不中变换(二值图像/结构元素/集合/convertT

作者: 小嗷_a2e2 | 来源:发表于2018-06-27 11:59 被阅读139次

本文作者:小嗷

微信公众号:aoxiaoji

吹比QQ群:736854977

微信链接:https://mp.weixin.qq.com/s?__biz=MzU1MTgxNjQyMg==&mid=2247483871&idx=1&sn=d291fddb429e335ca801f7cffb017878&chksm=fb8adc56ccfd554082cb87416d3f95f308302981bcd570161815a70e8ddb47dcf8fa1c8684b3#rd


image image image

在本篇中,您将学习如何通过使用“Hit-or-Miss”转换(也称为“Hit-or-Miss”转换)在二进制映像中找到给定的配置或模式。(命中/错过)

这种变换也是更高级的形态学操作的基础,如细化或修剪。

我们将使用OpenCV函数morphologyEx()。

本文你会找到以下问题的答案:

  1. 二值图像

  2. 结构元素

  3. 集合

  4. 击中击不中变换(Hit-or-Miss)

  5. convertTo

  6. saturate_cast

  7. moveWindow


2.1 二值图像

二值图像(Binary Image)是指将图像上的每一个像素只有两种可能的取值或灰度等级状态,人们经常用黑白、B&W、单色图像表示二值图像。

image.gif

二值图像是指在图像中,灰度等级只有两种,也就是说,图像中的任何像素不是0就是1,再无其他过渡的灰度值。

2.2 结构元素

结构元素就是核模块。

image.gif

上图中间这个模块称为结构元素(专业名词)

image.gif

2.3 集合

集合是指具有某种特定性质的具体的或抽象的对象汇总成的集体,这些对象称为该集合的元素。

例如全中国人的集合,它的元素就是每一个中国人。

我们通常用大写字母如A,B,S,T,...表示集合,而用小写字母如a,b,x,y,...表示集合的元素。

2.3.1 若x是集合S的元素,则称x属于S,

记为x∈S。

2.3.2 若y不是集合S的元素,则称y不属于S,

记为y∉S。

2.3.3 空集

有一类特殊的集合,它不包含任何元素,如{x|x∈R x²+1=0} ,我们称之为空集,记为∅。

2.3.4 子集

设S,T是两个集合,如果S的所有元素都属于T

image 则称S是T的子集,记为 image

2.3.5 相等

如果两个集合S和T的元素完全相同,则称S与T两个集合相等,记为S=T 。显然我们有 image

2.3.6 并交集

并集定义

并集定义:由所有属于集合A或属于集合B的元素所组成的集合,记作A∪B(或B∪A),读作“A并B”(或“B并A”),即A∪B={x|x∈A,或x∈B}。并集越并越多。

交集定义

由属于A且属于B的相同元素组成的集合,记作A∩B(或B∩A),读作“A交B”(或“B交A”),即A∩B={x|x∈A,且x∈B}。交集越交越少。

若A包含B,则A∩B=B,A∪B=A

2.3.7 补集(重点)

击中击不中需要用到。所以,小嗷就写写集合

相对补集定义:由属于A而不属于B的元素组成的集合,称为B关于A的相对补集,记作A-B或A\B,即A-B={x|x∈A,且x∉B'}。

绝对补集定义:A关于全集合U的相对补集称作A的绝对补集,记作A'或∁u(A)或~A。有U'=Φ;Φ'=U

例如:A的补集

意思就是除了A中的元素外的元素所组成的集合

也就是说A里面有的,A的补集一定没有

A里面没有的,A的补集里一定有

所以A的补集和A的交集是空集

2.3.8 幂集

定义:设有集合A,由集合A所有子集组成的集合,称为集合A的幂集。 定理:有限集A的幂集的基数等于2的有限集A的基数次幂

2.4 击中击不中变换(Hit-or-Miss)理论

形态学运算符根据图像的形状来处理图像。

这些操作符将一个或多个结构化元素应用到输入映像中,以获得输出映像。两个基本的形态学操作是侵蚀和扩张。

这两个操作的组合产生高级形态转换,如打开、关闭或顶帽转换。要了解这些和其他基本的形态学操作的更多信息,请参考以前的教程(第25篇腐蚀和膨胀)和(第27篇更多的形态学转换)。

对于在二值图中查找模式,“Hit-or-Miss”转换非常有用。特别地,它找到了那些邻域与第一个结构元素B1的形状匹配的像素,同时又与第二个结构元素B2的形状不匹配。在数学上,应用于图像A的操作可以表示为:

image

简单来说:

“Hit-or-Miss”找到那些邻域与B1(核)的形状匹配的像素

“Hit-or-Miss”找到那些邻域与B2(核)的形状不匹配的像素

具体操作:

首先,建立一个比B大的模板W;使用此模板对图像A进行腐蚀,得到图像假设为Process1;

其次,用B减去W,从而得到V模板(W-B);使用V模板对图像A的补集进行腐蚀,得到图像假设为Process2;

然后,Process1与Process2取交集;得到的结果就是B的位置。这里的位置可能不是B的中心位置,要视W-B时对齐的位置而异;

因此,“Hit-or-Miss” 操作包括三个步骤:

  • 用结构元素B1腐蚀图像A(B1等于W)。

  • 用结构元素B2腐蚀图像A (Ac)的补集(B2=B1-B)。

  • 第一步的结果和第二步的结果的交集。

第二步例子,第一步和第三步相对简单就不写(如果不懂就公众号或者QQ邮箱call小嗷)

结构元素B1和B2可以组合成单个元素b。我们来看一个例子:

image.gif

B1为第一个结构元素,B2为第二个结构元素,b为第三个结构元素(B1-B2=b)

结构元素(内核)。左:内核“击中”。中间:内核“不击中”。右:最后结合内核

在这种情况下,我们正在寻找一种模式,其中的中心像素属于背景,而北部、南部、东部和西部像素属于前景。附近的其他像素可以是任何类型的,我们不关心它们。现在,让我们将这个核应用到一个输入图像:

image.gif

二值图(原图)

image

输出二值图像

您可以看到模式只在图像中的一个位置找到255

前面示例对应的代码如下所示。

 1#include <opencv2/core.hpp> 2#include <opencv2/imgproc.hpp> 3#include <opencv2/highgui.hpp> 4using namespace cv; 5int main(){ 6    Mat input_image = (Mat_<uchar>(8, 8) << 7        0, 0, 0, 0, 0, 0, 0, 0, 8        0, 255, 255, 255, 0, 0, 0, 255, 9        0, 255, 255, 255, 0, 0, 0, 0,10        0, 255, 255, 255, 0, 255, 0, 0,11        0, 0, 255, 0, 0, 0, 0, 0,12        0, 0, 255, 0, 0, 255, 255, 0,13        0, 255, 0, 255, 0, 0, 255, 0,14        0, 255, 255, 255, 0, 0, 0, 0);15    Mat kernel = (Mat_<int>(3, 3) <<16        0, 1, 0,17        1, -1, 1,18        0, 1, 0);19    Mat output_image;20    morphologyEx(input_image, output_image, MORPH_HITMISS, kernel);21    const int rate = 50;22    kernel = (kernel + 1) * 127;23    kernel.convertTo(kernel, CV_8U);24    resize(kernel, kernel, Size(), rate, rate, INTER_NEAREST);25    imshow("kernel", kernel);26    moveWindow("kernel", 0, 0);27    resize(input_image, input_image, Size(), rate, rate, INTER_NEAREST);28    imshow("Original", input_image);29    moveWindow("Original", 0, 200);30    //rate就是用来或大尺寸31    resize(output_image, output_image, Size(), rate, rate, INTER_NEAREST);32    imshow("Hit or Miss", output_image);33    moveWindow("Hit or Miss", 500, 200);34    waitKey(0);35    return 0;36}

效果图

image.gif image.gif

3.1 MorphTypes

看第27篇,ths

image

网址:

https://docs.opencv.org/master/d4/d86/groupimgprocfilter.html#gga7be549266bad7b2e6a04db49827f9f32acf55ff766595ec0174ba42852f0ac264

"hit or miss" .- 只支持CV_8UC1二进制图像。

3.2 saturate_cast的用法

saturate_cast<uchar>(value):(value)确保值大小范围为0~255之间</uchar>

3.3 convertTo的用法

1void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;  

参数:

  • m:目标矩阵。如果m在运算前没有合适的尺寸或类型,将被重新分配。

  • rtype:目标矩阵的类型。因为目标矩阵的通道数与源矩阵一样,所以rtype也可以看做是目标矩阵的位深度。如果rtype为负值,目标矩阵和源矩阵将使用同样的类型。

  • alpha:尺度变换因子(可选)。【比例因子】

  • beta:附加到尺度变换后的值上的偏移量(可选)【将输入数组元素按比例缩放后添加的值】。

(在第5篇线性混合addWeighted谈到alpha、beta)

函数将源矩阵中的像素值转换为目标类型。最后会使用溢出保护函数saturate_cast<> ,以避免转换过程中可能出现的溢出。函数执行如下运算:

image

convertTo:就是转换类型

3.4 MoveWindow

改变指定窗口的位置和大小。

image

任务:

简单调用API函数就OK(估计以后实战中,经常使用形态学图像处理问题)

代码如下:

 1#include <opencv2/core.hpp> 2#include <opencv2/imgproc.hpp> 3#include <opencv2/highgui.hpp> 4using namespace cv; 5int main() { 6    Mat input_image = imread("D://9.jpg",2); 7 8    imshow("Hit or Miss原图", input_image); 9    Mat kernel = (Mat_<int>(3, 3) <<10        0, 1, 0,11        1, -1, 1,12        0, 1, 0);13    Mat output_image, output_image1;14    Mat element = getStructuringElement(0, Size(3, 3),Point(-1,-1)); 15    erode(input_image, output_image1, element);16    imshow("腐蚀图", output_image1);1718    morphologyEx(input_image, output_image, MORPH_HITMISS, kernel);1920    imshow("Hit or Miss", output_image);2122    waitKey(0);23    return 0;24}

原图:

image.gif

效果图:

image

效果有点像内部和外部梯度的效果图,当然日后轮廓相关边缘检测,分水岭要用到

image
  1. 本人是抱着玩一玩的心态,学习opencv(其实深度学习没有外界说的这么高深,小嗷是白板,而且有工作在身并且于代码无关)

  2. 大家可以把我的数学水平想象成初中水平,毕竟小嗷既不是代码靠吃饭又不是靠数学吃饭,毕业N年

  3. 写文章主要是为了后人少走点弯路,多交点朋友,一起学习

  4. 如果有好的图像识别群拉我进去QQ:631821577

  5. 就我一个白板,最后还是成的,你们别怕,慢慢来把

image

分享可以无数次,转载成自己文章QQ邮箱通知一下,未经授权请勿转载。

  • 邮箱:631821577@qq.com

  • QQ群:736854977

  • 有什么疑问公众号提问,下班或者周六日回答,ths

推荐文章:

8.更正曝光不足的图像(图像的对比度和亮度及轨迹条) --- OpenCV从零开始到图像(人脸 + 物体)识别系列 【没有排版好】

(公众号底下的文章分类 -> 编程 -> 查看第四篇文章)【已经排版好,建议PC电脑看】

25.消除不相关的细节/裂缝桥接(形态学 --膨胀与腐蚀详解 )--- OpenCV从零开始到图像(人脸 + 物体)识别系列

27.形态学图像运算(形态学梯度计算/开运算/闭运算/顶帽运算/黑帽)-- OpenCV从零开始到图像(人脸 + 物体)识别系列

感言

很多书上都用集合论来讲这一变换,对应用者来说似乎没这必要。简单来说击中-击不中运算常用于二值图像,它用于基于结构元素的配置,从图像中寻找具有某种像素排列特征的目标,如单个像素、颗粒中交叉或纵向的特征、直角边缘或其他用户自定义的特征等。计算时,只有当结构元素与其覆盖的图像区域完全相同时,中心像素的值才会被置为1,否则为0。下图给出了一个例子。

image

和简单的腐蚀操作不一样。击中或击不中变换,只有当结构元素与其覆盖的图像区域完全相同(包括物体前景点还含有背景点,也就是补集也要一样)时,所对应的区域输出图象。

书上有这么一句话:“当不需要背景时,击中或击不中变换退化为腐蚀操作”

相关文章

  • 28.击中击不中变换(二值图像/结构元素/集合/convertT

    本文作者:小嗷 微信公众号:aoxiaoji 吹比QQ群:736854977 微信链接:https://mp.we...

  • 形态学图像处理2

    二值图像中的形态学应用 击中击不中 形态学击中击不中变换常用于图像中某种特定形状的精确定位,是一种形状检测的基本工...

  • android使用opencv图片腐蚀与扩张

    数学形态学中运算有 膨胀(或扩张)、腐蚀(或侵蚀)、开启、闭合、骨架抽取、极线腐蚀、击中击不中变换、Top-hat...

  • 形态学操作

    · 形态学操作主要包括:腐蚀,膨胀,开运算,闭运算,形态学梯度运算,顶帽运算,黑帽运算,击中击不中 腐蚀 将图像的...

  • 形态学图像处理

    形态学图像处理 以下为二值图像 有结构元,集合。结构元具有原点,原点可以自己确定,一般为重心位置。 腐蚀为A的补集...

  • opencv+python学习记录(九)伽马变换

    一、什么是Gamma变换 Gamma变换是对输入图像灰度值进行的非线性操作,使输出图像灰度值与输入图像灰度值呈指数...

  • matlab|二值形态学处理

    图像的二值形态学处理,是利用集合论的思想,能够简化图像数据,保持基本形状特征,除去不相干的结构,此外还能并行实现。...

  • 图像的几何变换1

    图像的几何变换又称为图像空间变换,它将一幅图像中的坐标位置映射到另一幅图像中的新生位置。几何变换不改变图像的像素值...

  • Metal 创建和采样纹理

    您可以使用纹理在Metal中绘制和处理图像。纹理是纹理元素的结构化集合,通常称为纹理元素或像素。这些纹理元素的确切...

  • python数据分析与展示:图像的手绘效果

    一:图像的相关知识了解 二:图像的数组表示 三:图像的变换 读入图像后,获取像素RGB值,修改后保存为新的文件 四...

网友评论

      本文标题:28.击中击不中变换(二值图像/结构元素/集合/convertT

      本文链接:https://www.haomeiwen.com/subject/jtsbyftx.html