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

14day-ai入门-人工智能基础学习-OpenCV-图像预处理4

一、图像轮廓特征查找

图像轮廓特征查找其实就是他的外接轮廓。(外接矩形)

1.1 外接矩形

  • boundingRect(轮廓点)

    返回的是左上角坐标x,y和宽,高,然后使用rectangle画出矩形

形状的外接矩形有两种,如下图:

1.2 最小外接矩形

我们知道凸包点形成的多边形会将所有的图像点包围起来,所以最小矩形的边必然会和凸包多边形的边有一条重合。

随便取一条边,然后连接这条边上的一条点和其他的点相连求出到这条边的投影,最大的就是最宽的点,同理这一条边的另一个点也是如此,这样就找到了宽,高就是点到这条边的最大垂直距离,然后得到面积,重复每一条边就可以找到最小的面积了。

需要使用到的API说明:

cnt,th  = cv2.findContours() 找到外部轮廓的所有点列表

rect = cv2.minAreaRect(cnt)

传入的cnt参数为contours中的轮廓,可以遍历contours中的所有轮廓,然后计算出每个轮廓的小面积外接矩形

  • rect 是计算轮廓最小面积外接矩形:rect 结构通常包含中心点坐标 (x, y)、宽度 width、高度 height 和旋转角度 angle

cv2.boxPoints(rect).astype(int)

cv2.boxPoints(rect)返回 是一个形状为 4行2列的数组,每一行代表一个点的坐标(x, y),顺序按照逆时针或顺时针方向排列

将最小外接矩形转换为边界框的四个角点,并转换为整数坐标

1.3 最小外接圆

寻找最小外接圆使用的算法是Welzl算法。Welzl算法基于一个定理:希尔伯特圆定理表明,对于平面上的任意三个不在同一直线上的点,存在一个唯一的圆同时通过这三个点,且该圆是最小面积的圆(即包含这三个点的圆中半径最小的圆,也称为最小覆盖圆)。

然后我们通过这个定理来找到最小的外接圆,先随机找三个点,画出一个圆然后看是否所有的点都在园内或者圆上,如果不是,就以外面的一个点和圆上的两个点画出一个新的圆,重复这个操作。

需要使用的API说明

cv2.minEnclosingCircle(points) -> (center, radius)

参数说明:

  • points:输入参数图片轮廓数据

返回值:

  • center:一个包含圆心坐标的二元组 (x, y)

  • radius:浮点数类型,表示计算得到的最小覆盖圆的半径。

cv2.circle(img, center, radius, color, thickness)

  • img:输入图像,通常是一个numpy数组,代表要绘制圆形的图像。

  • center:一个二元组 (x, y),表示圆心的坐标位置。

  • radius:整型或浮点型数值,表示圆的半径长度。

  • color:颜色标识,可以是BGR格式的三元组 (B, E, R),例如 (255, 0, 0) 表示红色。

  • thickness:整数,表示圆边框的宽度。如果设置为 -1,则会填充整个圆。

二、直方图均衡化

2.1 什么是直方图

直方图是对数据进行统计的一种方法,并且将统计值组织到一系列实现定义好的 bin 当中。其中, bin 为直方图中经常用到的一个概念,可以译为 “直条” 或 “组距”,其数值是从数据中计算出的特征统计量,这些数据可以是诸如梯度、方向、色彩或任何其他特征。

  • 直方图:反映图像像素分布的统计图,横坐标就是图像像素的取值,纵坐标是该像素的个数。也就是对一张图像中不同像素值的像素个数的统计。

  • 增加对比度:黑的更黑,白的更白。

 

2.2 绘制直方图

就是以像素值为横坐标,像素值的个数为纵坐标绘制一个统计图。

hist=cv2.calcHist(images, channels, mask, histSize, ranges)

  • images:输入图像列表,可以是一幅或多幅图像(通常是灰度图像或者彩色图像的各个通道)。

  • channels:一个包含整数的列表,指示在每个图像上计算直方图的通道编号。如果输入图像是灰度图,它的值就是 [0];如果是彩色图像的话,传入的参数可以是 [0],[1],[2] 它们分别对应着通道 B,E,R。

  • mask(可选):一个与输入图像尺寸相同的二值掩模图像,其中非零元素标记了参与直方图计算的区域,None为全部计算。

  • histSize:一个整数列表,也就是直方图的区间个数(BIN 的数目)。用中括号括起来,例如:[256]。

  • ranges:每维数据的取值范围,它是一个二维列表,每一维对应一个通道的最小值和最大值,例如对灰度图像可能是 [0, 256]

返回值hist 是一个长度为255的数组,数组中的每个值表示图像中对应灰度等级的像素计数

minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(hist)

获取直方图的最小值、最大值及其对应最小值的位置索引、最大值的位置索引

cv2.line(img, pt1, pt2, color, thickness)

  • img:原始图像,即要在上面画线的numpy数组(一般为uint8类型)。

  • pt1pt2:分别为线段的起点和终点坐标,它们都是元组类型,例如 (x1, y1)(x2, y2) 分别代表线段两端的横纵坐标。

  • color:线段的颜色,通常是一个包含三个元素的元组 (B, E, R) 表示BGR色彩空间的像素值,也可以是灰度图像的一个整数值。

  • thickness:线段的宽度,默认值是1,如果设置为负数,则线宽会被填充。

2.3 直方图均衡化

一副效果好的图像通常在直方图上的分布比较均匀,直方图均衡化就是用来改善图像的全局亮度和对比度。

如果一幅图像整体很亮,那所有的像素值的取值个数应该都会很高,所以应该把它的直方图做一个横向拉伸,就可以扩大图像像素值的分布范围,提高图像的对比度

通俗的讲,就是遍历图像的像素统计出灰度值的个数、比例与累计比例,并重新映射到0-255范围(也可以是其他范围)内,其实从观感上就可以发现,下面两幅图中前面那幅图对比度不高,偏灰白。

  • 直方图均衡化作用:

    • 增强对比度

    • 提高图像质量

2.3.1 自适应直方图均衡化

自适应直方图均衡化(Adaptive Histogram Equalization, AHE),通过调整图像像素值的分布,使得图像的对比度和亮度得到改善。

具体过程如下所示:

假设有一个3*3的图像,其灰度图的像素值如上图所示,现在我们要对其进行直方图均衡化,首先就是统计其每个像素值的个数、比例以及其累计比例。如下图所示。

接下来我们就要进行计算,就是将要缩放的范围(通常是缩放到0-255,所以就是255-0)乘以累计比例,得到新的像素值,并将新的像素值放到对应的位置上,比如像素值为50的像素点,将其累计比例乘以255,也就是0.33乘以255得到84.15,取整后得到84,并将84放在原图像中像素值为50的地方,像素值为100、210、255的计算过程类似,最终会得到如下图所示的结果,这样就完成了最基本的直方图均衡化的过程。

dst = cv.equalizeHist(imgGray)

imgGray为需要直方图均衡化的灰度图,返回值为处理后的图像

该方法适用于图像的灰度分布不均匀,且灰度分布集中在更窄的范围,图像的细节不够清晰且对比度较低的情况,然而,传统的直方图均衡化方法会引入噪声,并导致图像中出现过度增强的区域。这是因为直方图均衡化方法没有考虑到图像的局部特征和全局对比度的差异。如下图:

2.3.2 对比度受限的自适应直方图均衡化

很明显,因为全局调整亮度和对比度的原因,脸部太亮,大部分细节都丢失了。自适应均衡化就是用来解决这一问题的:它在每一个小区域内(默认8×8)进行直方图均衡化。当然,如果有噪点的话,噪点会被放大,需要对小区域内的对比度进行了限制,所以这个算法全称叫:对比度受限的自适应直方图均衡化(Contrast Limited Adaptive Histogram Equalization, CLAHE)。

其主要步骤为:

先将图片分块,然后对每一块分别处理,但是要保证每一块都只是相差了一个像素点的距离,为了保证图像平滑。

clahe = cv2.createCLAHE(clipLimit=None, tileGridSize=None)

  • clipLimit(可选):对比度限制参数,用于控制直方图均衡化过程中对比度增强的程度。如果设置一个大于1的值(如2.0或4.0),CLAHE会限制对比度增强的最大程度,避免过度放大噪声。如果不设置,OpenCV会使用一个默认值。

  • tileGridSize(可选):图像分块的大小,通常是一个包含两个整数的元组,如(8, 8),表示将图像划分成8x8的小块进行独立的直方图均衡化处理。分块大小的选择会影响到CLAHE的效果以及处理速度。

创建CLAHE对象后,可以使用 .apply() 方法对图像进行CLAHE处理:

img=clahe.apply(image)

  • image:要均衡化的图像。

  • img均衡后的图像

三、模板匹配

3.1模板匹配

模板匹配就是用模板图(通常是一个小图)在目标图像(通常是一个比模板图大的图片)中不断的滑动比较,通过某种比较方法来判断是否匹配成功,找到模板图所在的位置。

  • 不会有边缘填充。

  • 类似于卷积,滑动比较,挨个比较象素。

  • 返回结果大小是:目标图大小-模板图大小+1。

3.2 api

res=cv2.matchTemplate(image, templ, method)

  • image:原图像,这是一个灰度图像或彩色图像(在这种情况下,匹配将在每个通道上独立进行)。

  • templ:模板图像,也是灰度图像或与原图像相同通道数的彩色图像。

  • method:匹配方法,可以是以下之一:

    • cv2.TM_CCOEFF

    • cv2.TM_CCOEFF_NORMED

    • cv2.TM_CCORR

    • cv2.TM_CCORR_NORMED

    • cv2.TM_SQDIFF

    • cv2.TM_SQDIFF_NORMED

    • 这些方法决定了如何度量模板图像与原图像子窗口之间的相似度。

  • 返回值res

    函数在完成图像模板匹配后返回一个结果矩阵,这个矩阵的大小与原图像不相同。

  • 注意:模板匹配过程皆不需要边缘填充,直接从目标图像的左上角开始计算。所以从左上角开始记录的对应块的相似度。

    匹配方法不同,返回矩阵的值的含义也会有所区别。以下是几种常用的匹配方法及其返回值含义:

    1. cv2.TM_SQDIFFcv2.TM_SQDIFF_NORMED

      返回值越接近0,表示匹配程度越好。最小值对应的最佳匹配位置。

    2. cv2.TM_CCORRcv2.TM_CCORR_NORMED

      返回值越大,表示匹配程度越好。最大值对应的最佳匹配位置。

    3. cv2.TM_CCOEFFcv2.TM_CCOEFF_NORMED

      返回值越大,表示匹配程度越好。最大值对应的最佳匹配位置。

3.2.1 平方差匹配

cv2.TM_SQDIFF

以模板图与目标图所对应的像素值使用平方差公式来计算,其结果越小,代表匹配程度越高,计算过程举例如下。

注意:模板匹配过程皆不需要边缘填充,直接从目标图像的左上角开始计算。

3.2.2 归一化平方差匹配

cv2.TM_SQDIFF_NORMED

与平方差匹配类似,只不过需要将值统一到0到1,计算结果越小,代表匹配程度越高。

3.2.3 相关匹配

cv2.TM_CCORR

使用对应像素的乘积进行匹配,乘积的结果越大其匹配程度越高。

这里面是有bug的,小伙伴们可以自己想想。

3.2.4 归一化相关匹配

cv2.TM_CCORR_NORMED

与相关匹配类似,只不过是将其值统一到0到1之间,值越大,代表匹配程度越高。

3.2.5 相关系数匹配

cv2.TM_CCOEFF

需要先计算模板与目标图像的均值,然后通过每个像素与均值之间的差的乘积再求和来表示其匹配程度,1表示完美的匹配,-1表示最差的匹配。

3.2.6 归一化相关系数匹配

cv2.TM_CCOEFF_NORMED

也是将相关系数匹配的结果统一到0到1之间,值越接近1代表匹配程度越高。

3.3 绘制轮廓

找的目标图像中匹配程度最高的点,我们可以设定一个匹配阈值来筛选出多个匹配程度高的区域。

  • loc=np.where(array > 0.8) #loc包含array中所有大于0.8的元素索引的数组

np.where(condition) 是 NumPy 的一个函数,当条件为真时,返回满足条件的元素的索引。

  • zip(*loc)

    • *loc 是解包操作,将 loc 中的多个数组拆开,作为单独的参数传递给 zip

    • zip 将这些数组按元素一一配对,生成一个迭代器,每个元素是一个元组,表示一个坐标点。

x=list([[1,2,3,4,3],[23,4,2,4,2]])
print(list(zip(*x)))#[(1, 23), (2, 4), (3, 2), (4, 4), (3, 2)]

四、 霍夫变换

4.1 理解霍夫变换

  • 霍夫变换是图像处理的一种技术,主要用于检测图像中的直线、圆等几何形状。基本思想就是将图像空间中的点映射到参数空间中,通过在参数空间中寻找累计最大值实现对特定形状的检测。

 

4.2 霍夫直线变换

使用API

lines=cv2.HoughLines(image, rho, theta, threshold)

  • image:输入图像,通常为二值图像,其中白点表示边缘点,黑点为背景。

  • rho:r的精度,以像素为单位,表示霍夫空间中每一步的距离增量, 值越大,考虑越多的线。

  • theta:角度θ的精度,通常以弧度为单位,表示霍夫空间中每一步的角度增量。值越小,考虑越多的线。

  • threshold:累加数阈值,只有累积投票数超过这个阈值的候选直线才会被返回。

返回值:cv2.HoughLines 函数返回一个二维数组,每一行代表一条直线在霍夫空间中的参数 (rho, theta)

import cv2 as cv
import numpy as np
# 读图
img = cv.imread('../images/huofu.png')
img_gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
​
# 二值化
_,binary = cv.threshold(img_gray,127,255,cv.THRESH_BINARY)
​
# 边缘检测
edges = cv.Canny(binary,30,70)
​
# 霍夫变换 返回的是r和theta
lines = cv.HoughLines(edges,0.8,np.pi/180,90)
print(lines.shape)
for line in lines:r,theta = line[0]sin_theta = np.sin(theta)cos_theta = np.cos(theta)x1,x2 = 0,img.shape[1]y1,y2 = int((r-x1*cos_theta)/sin_theta),int((r-x2*cos_theta)/sin_theta)cv.line(img,(x1,y1),(x2,y2),(0,255,0),1)
cv.imshow('img',img)
cv.waitKey(0)
cv.destroyAllWindows()

4.3 统计概率霍夫直线变换

前面的方法又称为标准霍夫变换,它会计算图像中的每一个点,计算量比较大,另外它得到的是整一条线(r和θ),并不知道原图中直线的端点。所以提出了统计概率霍夫直线变换(Probabilistic Hough Transform),是一种改进的霍夫变换,它在获取到直线之后,会检测原图中在该直线上的点,并获取到两侧的端点坐标,然后通过两个点的坐标来计算该直线的长度,通过直线长度与最短长度阈值的比较来决定该直线要不要被保留。

使用API

lines=cv2.HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=0, maxLineGap=0)

  • image:输入图像,通常为二值图像,其中白点表示边缘点,黑点为背景。

  • rho:极径分辨率,以像素为单位,表示极坐标系中的距离分辨率。

    • rho 越小,参数空间中极径的划分越精细,对直线距离的检测精度越高,但计算量也会越大(因为需要遍历更多可能的 ρ 值)。

    • 反之,rho 越大,参数空间的划分越粗糙,可能会将距离接近的直线判定为同一条,但计算速度更快。

举例说明:

rho=1 时,能区分开距离仅 1 像素的两条平行直线;

rho=5 时,对于距离小于 5 像素的两条平行直线,可能会被合并为一条检测结果。

  • theta:极角分辨率,以弧度为单位,表示极坐标系中角度的分辨率。

  • threshold:阈值,用于过滤掉弱检测结果,只有累计投票数超过这个阈值的直线才会被返回。

  • lines(可选):一个可初始化的输出数组,用于存储检测到的直线参数。

  • minLineLength(可选):最短长度阈值,比这个长度短的线会被排除。

  • maxLineGap(可选):同一直线两点之间的最大距离。当霍夫变换检测到一系列接近直角的线段时,这些线段可能是同一直线的不同部分。maxLineGap参数指定了在考虑这些线段属于同一直线时,它们之间最大可接受的像素间隔。

返回值lines:cv2.HoughLinesP 函数返回一个三维数组,每个元素是一个包含4个元素的数组,分别表示每条直线的起始点和结束点在图像中的坐标(x1, y1, x2, y2)。

4.4 霍夫圆变换

霍夫圆变换跟直线变换类似,它可以从图像中找出潜在的圆形结构,并返回它们的中心坐标和半径。只不过线是用(r,θ)表示,圆是用(x_center,y_center,r)来表示,从二维变成了三维,数据量变大了很多;所以一般使用霍夫梯度法减少计算量。

使用API

circles=cv2.HoughCircles(image, method, dp, minDist, param1, param2)

  • image:输入图像,通常是灰度图像。

  • method:使用的霍夫变换方法:霍夫梯度法,可以是 cv2.HOUGH_GRADIENT,这是唯一在OpenCV中用于圆检测的方法。

  • dp:累加器分辨率与输入图像分辨率之间的降采样比率,用于加速运算但不影响准确性。设置为1表示霍夫梯度法中累加器图像的分辨率与原图一致

  • minDist:检测到的圆心之间的最小允许距离,以像素为单位。在霍夫变换检测圆的过程中,可能会检测到许多潜在的圆心。minDist 参数就是为了过滤掉过于接近的圆检测结果,避免检测结果过于密集。当你设置一个较小的 minDist 值时,算法会尝试找出尽可能多的圆,即使是彼此靠得很近的圆也可能都被检测出来。相反,当你设置一个较大的 minDist 值时,算法会倾向于只检测那些彼此间存在一定距离的独立的圆。

  • param1param2:这两个参数是在使用 cv2.HOUGH_GRADIENT 方法时的特定参数,分别为:

    • param1(可选):阈值1,决定边缘强度的阈值。

    • param2:阈值2,控制圆心识别的精确度。较大的该值会使得检测更严格的圆。param2 通常被称为圆心累积概率的阈值。在使用霍夫梯度方法时,param2 设置的是累加器阈值,它决定了哪些候选圆点集合被认为是有效的圆。较高的 param2 值意味着对圆的检测更严格,只有在累加器中积累了足够高的响应值才认为是真实的圆;较低的 param2 值则会降低检测的门槛,可能会检测到更多潜在的圆,但也可能包含更多的误检结果。

返回值:cv2.HoughCircles 返回一个二维numpy数组,包含了所有满足条件的圆的参数。

五、图像亮度变换

我们知道,图像都是由一个个像素值组成的,图像的亮度变换实际上还是图像像素值的变换。

5.1 线性变换

使用 cv2.addWeighted() 函数,可以对图像的像素值进行加权平均,进而改变图像的整体亮度。亮度增益可以通过向每个像素值添加一个正值来实现。

cv2.addWeighted(src1, alpha, src2, beta, gamma)

  • src1:第一张输入图像,它将被赋予权重 alpha

  • alpha:第一个输入图像的权重。

  • src2:第二张输入图像,它将被赋予权重 beta

  • beta:第二个输入图像的权重。

  • gamma:一个标量,将被添加到权重求和的结果上,可用于调整总体亮度。

    计算公式为: dst = src1 * alpha + src2 * beta + gamma

5.3 直接像素值修改

如果只需要增加或减少固定的亮度值,可以直接遍历图像像素并对每个像素值进行加减操作。

使用的API:

numpy.clip(a, a_min, a_max)

用于对数组中的元素进行限定,将超出指定范围的元素值截断至指定的最小值和最大值之间

  • a:输入数组。

  • a_min:指定的最小值,数组中所有小于 a_min 的元素将被替换为 a_min

  • a_max:指定的最大值,数组中所有大于 a_max 的元素将被替换为 a_max

六、形态学变换

形态学变换(Morphological Transformations)是一种基于形状的简单变换,它的处理对象通常是二值化图像。形态学变换有两个输入,一个输出:输入为原图像、核(结构化元素),输出为形态学变换后的图像。其基本操作有腐蚀和膨胀,这两种操作是相反的,即较亮的像素会被腐蚀和膨胀。下面我们来说一下核、腐蚀与膨胀的概念。

6.1 核

自适应二值化中,我们已经接触过核了,还记得吗?就是那个在原图中不断滑动计算的3*3的小区域,那其实就是一个3*3的核。

核(kernel)其实就是一个小区域,通常为3*3、5*5、7*7大小,有着其自己的结构,比如矩形结构、椭圆结构、十字形结构,如下图所示。通过不同的结构可以对不同特征的图像进行形态学操作的处理。

 

6.2 腐蚀

腐蚀操作就是使用核在原图(二值化图)上进行从左到右、从上到下的滑动(也就是从图像的左上角开始,滑动到图像的右下角)。在滑动过程中,令核值为1的区域与被核覆盖的对应区域进行相乘,得到其最小值,该最小值就是卷积核覆盖区域的中心像素点的新像素值,接着继续滑动。由于操作图像为二值图,所以不是黑就是白,这就意味着,在被核值为1覆盖的区域内,只要有黑色(像素值为0),那么该区域的中心像素点必定为黑色(0)。这样做的结果就是会将二值化图像中的白色部分尽可能的压缩,如下图所示,该图经过腐蚀之后,“变瘦”了。

在腐蚀操作的详细流程中,遍历图像的过程如下:

  1. 初始化

    • 设置一个起始位置(通常从图像的左上角开始)。

    • 准备好结构元素(structuring element),它是一个小的矩阵,大小通常是奇数,并且有一个明确的中心点。

  2. 逐像素处理: 对于输入图像中的每一个像素,执行以下步骤:

    a. 定位: 将结构元素移动到当前待处理像素的位置,使得结构元素的中心与该像素对齐。

    b. 区域覆盖: 结构元素会覆盖图像上的一个局部邻域,这个邻域由结构元素的尺寸决定。

    c. 条件检查: 检查结构元素覆盖区域内所有图像像素的颜色。对于二值图像来说,就是看这些像素是否都是白色(前景像素)。如果所有被结构元素覆盖的像素均为白色,则继续下一个步骤;否则,跳过此步骤,将中心像素视为背景像素。

    d. 侵蚀决策: 如果结构元素覆盖的所有像素都是白色,则原图像中的中心像素保持不变(在输出图像中仍为白色);否则,将中心像素变为黑色(在输出图像中变为背景色)。

  3. 迭代移动: 结构元素沿着图像从左到右、从上到下逐行逐列地移动,重复上述过程,直到整个图像都被结构元素遍历过。

  4. 循环处理: 如果指定了多个迭代次数,那么在整个图像完成一次遍历后,再次从头开始进行同样的遍历和侵蚀决策,直到达到指定的迭代次数。

通过这样的遍历方式,腐蚀操作能够逐步收缩目标物体边界,消除孤立的噪声像素以及细化连续的前景区域。

总结:二值图腐蚀后白色像素(非0)变少了

6.3 膨胀

膨胀与腐蚀刚好相反,膨胀操作就是使用核在原图(二值化图)上进行从左到右、从上到下的滑动,但是覆盖的区域出现白色,那么这个位置就为白色。

在膨胀操作的详细流程中,遍历图像的过程如下:

  1. 初始化

    • 设置一个起始位置(通常从图像的左上角开始)。

    • 准备好结构元素(structuring element),它是一个小的矩阵,大小通常是奇数,并且有一个明确的中心点。

  2. 逐像素处理: 对于输入图像中的每一个像素,执行以下步骤:

    a. 定位: 将结构元素移动到当前待处理像素的位置,使得结构元素的中心与该像素对齐。

    b. 区域覆盖: 结构元素会覆盖图像上的一个局部邻域,这个邻域由结构元素的尺寸决定。

    c. 条件检查: 检查结构元素覆盖区域内是否存在白色(前景)像素。对于二值图像来说,如果有任何一个被结构元素覆盖的像素是白色的,则继续下一步;否则,将中心像素保持原样(黑色或非目标物体像素不变)。

    d. 膨胀决策: 如果在结构元素覆盖的范围内找到了至少一个白色像素,则无论原中心像素是什么颜色,都将输出图像中的该中心像素设置为白色(前景色)。这表示即使原中心像素可能是背景像素,但只要其周围有白色像素存在,就认为该位置也应属于前景区域。

    e. 更新输出: 根据上述判断结果更新输出图像对应位置的像素值。

  3. 迭代移动: 结构元素沿着图像从左到右、从上到下逐行逐列地移动,重复上述过程,直到整个图像都被结构元素遍历过。

  4. 循环处理: 如果指定了多个迭代次数,那么在整个图像完成一次遍历后,再次从头开始进行同样的遍历和膨胀决策,直到达到指定的迭代次数。

通过这样的遍历方式,膨胀操作能够逐步扩大目标物体边界,连接断裂的前景部分,并填充内部空洞,使得物体轮廓更加明显且连续。

6.4 开运算

开运算是先腐蚀后膨胀,其作用是:分离物体,消除小区域。特点:消除噪点,去除小的干扰块,而不影响原来的图像

6.5 闭运算

闭运算与开运算相反,是先膨胀后腐蚀,作用是消除/“闭合”物体里面的孔洞,特点:可以填充闭合区域

6.6 礼帽运算

原图像与“开运算“的结果图之差,因为开运算带来的结果是放大了裂缝或者局部低亮度的区域,因此,从原图中减去开运算后的图,得到的效果图突出了比原图轮廓周围的区域更明亮的区域,且这一操作和选择的核的大小相关。

礼帽运算用来分离比邻近点亮一些的斑块。当一幅图像具有大幅的背景的时候,而微小物品比较有规律的情况下,可以使用礼帽运算进行背景提取

6.7 黑帽运算

黑帽运算为”闭运算“的结果图与原图像之差,

黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域,且这一操作和选择的核的大小相关。

黑帽运算用来分离比邻近点暗一些的斑块

6.8 形态学梯度

形态学梯度是一个基于结构元素的图像处理方法,它通过比较原图像与膨胀图和腐蚀图之间的差异来突出图像边缘特征。具体来说,对于图像中的每个像素点,其形态学梯度值是该像素点在膨胀后的图像值与其在腐蚀后的图像值之差。这样得到的结果通常能够强化图像的边缘信息,并且对噪声有一定的抑制作用

import cv2 as cv
import numpy as np
car = cv.imread('../images/car.png',cv.IMREAD_GRAYSCALE)
_,car = cv.threshold(car,127,255,cv.THRESH_BINARY_INV)
cv.imshow('car',car)
# 定义核
kernel = np.ones((5,5),dtype=np.uint8)
# 腐蚀
erosion = cv.erode(car,kernel,iterations = 1)
cv.imshow('erosion',erosion)
# 膨胀
dilation = cv.dilate(car,kernel,iterations = 1)
cv.imshow('dilation',dilation)
# 开运算
opening = cv.morphologyEx(car,cv.MORPH_OPEN,kernel)
cv.imshow('opening',opening)
# 闭运算
closing = cv.morphologyEx(car,cv.MORPH_CLOSE,kernel)
cv.imshow('closing',closing)
# 礼貌运算 原图与开运算
tophat = cv.morphologyEx(car,cv.MORPH_TOPHAT,kernel)
cv.imshow('tophat',tophat)
# 黑帽运算 闭运算与原图差
blackhat = cv.morphologyEx(car,cv.MORPH_BLACKHAT,kernel)
cv.imshow('blackhat',blackhat)
# 形态学梯度 膨胀和腐蚀差
gradient = cv.morphologyEx(car,cv.MORPH_GRADIENT,kernel)
cv.imshow('gradient',gradient)
cv.waitKey(10000)
cv.destroyAllWindows()

http://www.lryc.cn/news/606023.html

相关文章:

  • 我在 Arch Linux Plasma 6 Wayland 下驯服 Chromium 输入法的完整记录
  • ACOSRAR改进连续蚁群算法用于优化复杂环境下无人机路径规划,Matlab代码实现
  • 智慧工地系统:建筑工程管理的智能化革新与实践
  • 淘宝 API HTTP/2 多路复用与连接优化实践:提升商品数据采集吞吐量
  • Vue3 + Electron 技术栈下 MAC 地址获取的方法、准确性优化与应对策略
  • Electron 作品【AI聊天】桌面应用 —— 系列教程(含开源地址)
  • 发票闪印 v3.9.17 免费电子PDF发票批量打印工具绿色版
  • 【未解决】STM32无刷电机驱动电路问题记录
  • Apache Camel 简介
  • 【Lua】题目小练6
  • JavaScript函数性能优化秘籍:基于V8引擎优化
  • 【STM32】HAL库中的实现(二):串口(USART)/看门狗(IWDG/WWDG)/定时器(TIM)
  • JavaScript 框架语法特性对比-中文版
  • 39.MySQL索引
  • 用el-table实现的可编辑的动态表格组件
  • 树形DP-核心基础
  • DVD特工总部,DVD管理系统
  • 如何在 Ubuntu 24.04 或 22.04 LTS Linux 上安装 DaVinci Resolve
  • 【01】大恒相机SDK C++开发 —— 初始化相机,采集第一帧图像、回调采集、关闭相机
  • FastAPI的请求-响应周期为何需要后台任务分离?
  • Spire.XLS for .NET 中, 将 Excel 转换为 PDF 时, 如何设置纸张大小为A4纸,并将excel内容分页放置?
  • VBA代码解决方案第二十七讲:禁用EXCEL工作簿右上角的关闭按钮
  • 微信小程序性能优化与内存管理
  • 辐射源定位方法简述
  • 【25-cv-08807】David携Tyrone Acierto 雕塑版权发案
  • ros2--参数指令--rqt
  • sqli-labs:Less-16关卡详细解析
  • 揭秘动态测试:软件质量的实战防线
  • vue+elementui实现问卷调查配置可单选、多选、解答
  • 代码随想录day51图论2