一、步骤
-
导入库:cv2, numpy, matplotlib等。
-
读取图像,转灰度。
-
高斯模糊。
-
Canny边缘检测。
-
形态学闭运算。
-
查找轮廓,找到最大面积的轮廓。
-
创建掩膜,绘制该轮廓。
-
与原图叠加显示。
二、示例
import cv2
import numpy as np
import matplotlib.pyplot as plt
def extract_main_vein(image_path):
# 读取图像
img = cv2.imread(image_path)
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 高斯模糊降噪
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# Canny边缘检测
edges = cv2.Canny(blurred, 50, 150)
# 形态学闭运算(连接断裂部分)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (25, 25))
closed = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)
# 查找轮廓
contours, _ = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 筛选最大轮廓(按面积)
if contours:
max_contour = max(contours, key=cv2.contourArea)
# 创建掩膜
mask = np.zeros_like(gray)
cv2.drawContours(mask, [max_contour], -1, 255, thickness=cv2.FILLED)
# 形态学腐蚀去除细小分支
erode_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15, 15))
mask_eroded = cv2.erode(mask, erode_kernel, iterations=1)
# 与原图叠加显示
result = cv2.bitwise_and(img_rgb, img_rgb, mask=mask_eroded)
# 显示结果
plt.figure(figsize=(12, 6))
plt.subplot(131)
plt.imshow(img_rgb)
plt.title('Original Image')
plt.axis('off')
plt.subplot(132)
plt.imshow(mask_eroded, cmap='gray')
plt.title('Main Vein Mask')
plt.axis('off')
plt.subplot(133)
plt.imshow(result)
plt.title('Segmentation Result')
plt.axis('off')
plt.tight_layout()
plt.show()
else:
print("未检测到轮廓")
# 使用示例
image_path =r'd:/imgs/bak5/my_img01-B2.jpg'
extract_main_vein(image_path)
三、参数调整建议:
-
高斯模糊核大小((5,5)):可尝试3-15之间的奇数值
-
Canny阈值(50, 150):根据图像对比度调整
-
闭运算核大小(25,25):根据主梗宽度调整
-
腐蚀核大小(15,15):根据分支粗细调整
四、注意事项:
-
确保图像背景与烟叶对比度较高
-
主梗应保持相对完整的形态
-
如果效果不理想,可尝试:
- 调整形态学操作的核大小
- 修改Canny阈值参数
- 尝试不同的颜色空间处理(如HSV通道分离)









网友评论