如何在图片中识别出一些物体的位置。具体是什么不是形态学的范畴。
处理方法基本是对二进制图像进行处理。
卷积核决定着图像处理后的效果。
图像二值化
将图像的每个像素变成两种值, 如 0, 255。
全局二值化:全局按照某个阈值二值化
局部二值化
threshold(img, thresh, maxVal,type)
import cv2
# 读取图像
image = cv2.imread('your_image.jpg', cv2.IMREAD_GRAYSCALE)
# 进行简单阈值化
# 第一个参数是输入图像
# 第二个参数是用于分类像素值的阈值
# 第三个参数是当像素值高于阈值时要应用的新像素值
# 第四个参数是指定使用的阈值类型,如cv2.THRESH_BINARY、cv2.THRESH_BINARY_INV等
_, thresholded = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)
可以使用不同的阈值类型,根据应用的要求选择适当的类型。例如,cv2.THRESH_BINARY表示二进制阈值化,cv2.THRESH_BINARY_INV表示反二进制阈值化等。
后面三种不是二值化。
ostu: 类间方差最大
自适应阈值
由于光照不均与以及阴影的存在,只有一个阈值会使得在阴影处的白色被二值化为黑色。
cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst])
- src: 输入图像,应该是灰度图像。
- maxValue: 分类像素值的最大值,通常为255。
- adaptiveMethod: 指定阈值计算方法,可以是以下两者之一:
- cv2.ADAPTIVE_THRESH_MEAN_C:使用邻域块的平均值作为阈值。
- cv2.ADAPTIVE_THRESH_GAUSSIAN_C:使用邻域块的加权平均值(高斯窗口)作为阈值。
- thresholdType: 指定阈值类型,应该是以下两者之一:
- cv2.THRESH_BINARY:二进制阈值。
- cv2.THRESH_BINARY_INV:反二进制阈值。
- blockSize: 用于计算阈值的邻域块大小,必须是奇数。
- C: 从计算的平均值或加权平均值中减去的常数。
- dst (可选): 输出图像,可以与输入图像相同。如果未提供,函数将创建一个新的图像。
# 读取图像
image = cv2.imread('your_image.jpg', cv2.IMREAD_GRAYSCALE)
# 自适应阈值二值化
# 第一个参数是输入图像
# 第二个参数是用于分类像素值的最大值
# 第三个参数是指定使用的阈值类型,如cv2.ADAPTIVE_THRESH_MEAN_C或cv2.ADAPTIVE_THRESH_GAUSSIAN_C
# 第四个参数是指定阈值计算方法的区域大小,例如11表示计算每个像素周围的11x11区域
# 第五个参数是从计算的平均值或加权平均值中减去的常数
thresholded = cv2.adaptiveThreshold(
image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2
)
cv2.adaptiveThreshold函数使用局部均值作为阈值计算方法,然后将每个像素的阈值与其周围11x11区域的均值进行比较。你还可以尝试使用cv2.ADAPTIVE_THRESH_GAUSSIAN_C作为阈值计算方法,它使用局部区域的加权平均值。
获取卷积核
cv2.getStructuringElement(shape, ksize[, anchor])
参数说明:
- shape: 结构元素的形状,可以是 cv2.MORPH_RECT(矩形)、cv2.MORPH_ELLIPSE(椭圆)、cv2.MORPH_CROSS(十字形)等。
- ksize: 结构元素的大小,通常是一个 (width, height) 的元组。
- anchor(可选): 结构元素的锚点位置,默认为结构元素的中心。
import cv2
import numpy as np
# 创建一个 3x3 的矩形结构元素
kernel_rect = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
print("Rectangular Kernel:")
print(kernel_rect)
# 创建一个 3x3 的椭圆结构元素
kernel_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
print("\nElliptical Kernel:")
print(kernel_ellipse)
# 创建一个 3x3 的十字形结构元素
kernel_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
print("\nCross-shaped Kernel:")
print(kernel_cross)
腐蚀和膨胀
腐蚀:
用结构元素扫描图像,当结构元素完全包含在目标区域内时,保留中心点。
效果:消除细小物体、分离粘连目标、收缩物体边界。
膨胀:
用同一结构元素扫描腐蚀后的图像,当结构元素与目标区域有交集时,保留中心点。
效果:恢复被腐蚀物体的主要形状,但被完全消除的小物体无法恢复。
腐蚀 Erosion
将一个区域变小
卷积核都是全1 的,
在腐蚀操作中,结构元素(也称为内核)是一个小的图像,它定义了腐蚀的形状。在每一步腐蚀操作中,结构元素会在图像上滑动,并与图像的局部区域进行覆盖。在每个覆盖的位置,只有原图的像素全都包含在核中,该核中心点值才保留(个人理解?)。这个过程会导致图像中的边界逐渐变窄,因为图像中较亮的区域将被周围较暗的区域腐蚀。这会导致边界处的像素被腐蚀,对象会变小。


cv2.erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
- src: 输入图像,通常是二进制图像。
- kernel: 结构元素,用于定义腐蚀操作的形状。
- dst (可选): 输出图像,可以与输入图像相同。如果未提供,函数将创建一个新的图像。
- anchor (可选): 结构元素的锚点。默认值 (-1, -1) 表示锚点位于结构元素的中心。
- iterations (可选): 腐蚀操作的迭代次数,默认为 1。
- borderType (可选): 边界模式,表示当边界被腐蚀时如何处理。默认是 cv2.BORDER_CONSTANT。
- borderValue (可选): 当 borderType 为 cv2.BORDER_CONSTANT 时的边界值,默认为 0。
# 读取图像
img = cv2.imread('input_image.png', cv2.IMREAD_GRAYSCALE)
# 创建结构元素,这里使用一个 3x3 的矩形结构元素
kernel = np.ones((3, 3), np.uint8)
# 进行腐蚀操作
result = cv2.erode(img, kernel, iterations=1)
膨胀
将一个区域变大
开闭运算
开运算和闭运算是形态学处理中的两个重要操作,通常用于图像处理中的去噪、分割等任务。
开运算是先腐蚀后膨胀的过程。腐蚀操作可以消除小的噪点或细小的结构,而膨胀则可以恢复保留下来物体的形状,但被腐蚀掉的区域不会恢复。因此,开运算适合去除图像中的小物体或者平滑物体的边界,同时保持主要结构不变。例如,如果有一张包含许多小点的图像,开运算可以有效去除这些小点,而较大的物体则不受影响。
开运算
先做腐蚀再做膨胀。
最后的动作是放大的,就是开运算。
闭运算
先做膨胀再做腐蚀。
最后的动作是缩小的,就是闭运算。
闭运算适合的场景:填充小孔、连接邻近物体、平滑边界、处理断裂区域。
dst = cv2.morphologyEx(
src,
op,
kernel[,
dst[,
anchor[,
iterations[,
borderType[,
borderValue]]]]]
)
操作流程:
膨胀:扩大亮区,填充孔洞
腐蚀:收缩回原始尺寸,保持主要形状
顶帽 & 黑帽
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图像
image = cv2.imread('your_image.jpg', cv2.IMREAD_GRAYSCALE)
# 定义结构元素
kernel = np.ones((5, 5), np.uint8)
# 进行顶帽操作
tophat = cv2.morphologyEx(image, cv2.MORPH_TOPHAT, kernel)
# 进行黑帽操作
blackhat = cv2.morphologyEx(image, cv2.MORPH_BLACKHAT, kernel)
# 显示原始图像、顶帽结果和黑帽结果
plt.figure(figsize=(15, 5))
plt.subplot(131)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.axis('off')
plt.subplot(132)
plt.imshow(tophat, cmap='gray')
plt.title('Top Hat')
plt.axis('off')
plt.subplot(133)
plt.imshow(blackhat, cmap='gray')
plt.title('Black Hat')
plt.axis('off')
plt.show()
opencv 改变图片对比度
可以使用 cv2.convertScaleAbs 函数来改变图片的对比度。
可以按照一定的比例对图片的每个像素值进行缩放,同时还可以添加一个偏置,从而改变图片的对比度。