1 代码功能
该代码实现了一个图像处理的功能,具体来说是去除图像内部填充(或更准确地说,是提取并显示图像中轮廓的外围区域,而忽略内部填充)。以下是该功能的详细步骤:
-
读取图像:使用
cv2.imread()
函数从指定路径image_path
读取图像。如果图像无法加载(例如,文件不存在或路径错误),则打印错误消息并返回。 -
转换为灰度图像:通过
cv2.cvtColor()
函数将图像从BGR颜色空间转换为灰度图像。这是边缘检测前的必要步骤,因为边缘检测通常在灰度图像上执行。 -
应用边缘检测:使用
cv2.Canny()
函数对灰度图像进行Canny边缘检测。Canny边缘检测是一种流行的边缘检测算法,它通过计算图像梯度的局部最大值来检测边缘。这里设置了两个阈值(100和200),用于控制边缘检测的灵敏度。 -
查找轮廓:通过
cv2.findContours()
函数在边缘检测后的图像中查找轮廓。这里使用了cv2.RETR_EXTERNAL
标志,表示只检索最外层的轮廓,忽略轮廓内部的洞或轮廓上的其他轮廓。 -
创建掩膜:创建一个与灰度图像形状相同但全为黑色的图像(即掩膜)。然后,使用
cv2.drawContours()
函数在掩膜上绘制找到的轮廓,轮廓内的区域被设置为白色(255)。 -
应用掩膜到原图:由于掩膜是灰度图像(单通道),而原图是BGR图像(三通道),因此需要将掩膜转换为三通道图像(使用
cv2.cvtColor()
)。然后,使用cv2.bitwise_and()
函数将掩膜应用到原图上,以提取轮廓外围的区域,忽略内部填充。 -
显示结果:使用matplotlib的
plt.imshow()
函数显示原始图像、掩膜和结果图像。由于matplotlib默认以RGB格式显示图像,而OpenCV以BGR格式读取图像,因此在显示之前需要将图像从BGR转换为RGB。
最终,这段代码会显示三个图像:原始图像、掩膜(仅显示轮廓)和结果图像(只包含原始图像中轮廓外围的区域)。这可以用于去除图像中不需要的内部细节,只保留轮廓和轮廓外的区域。
2 代码
import cv2
import numpy as np
import matplotlib.pyplot as plt
def remove_interior_fill(image_path):
# 1. 读取图像
img = cv2.imread(image_path)
if img is None:
print(f"Error: Unable to load image at {image_path}")
return
# 2. 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
gray = cv2.equalizeHist(gray)
# 3. 应用边缘检测
edges = cv2.Canny(gray, 100, 200)
# 4. 查找轮廓
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 5. 创建掩膜
mask = np.zeros_like(gray)
cv2.drawContours(mask, contours, -1, 255, -1)
# 6. 应用掩膜到原图
# 注意:我们需要将掩膜扩展到原始图像的通道数
mask_3ch = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
result = cv2.bitwise_and(img, mask_3ch)
# 显示结果
plt.figure(figsize=(12, 4))
plt.subplot(1, 3, 1)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) # 转换为RGB以正确显示颜色
plt.title('Original')
plt.axis('off')
plt.subplot(1, 3, 2)
plt.imshow(cv2.cvtColor(mask_3ch, cv2.COLOR_BGR2RGB)) # 同样转换为RGB
plt.title('Mask')
plt.axis('off')
plt.subplot(1, 3, 3)
plt.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
plt.title('Result')
plt.axis('off')
plt.show()
# 使用示例
image_path = 'input.jpg'
remove_interior_fill(image_path)
3 运行结果
图 3-1 运行结果