)
一、实验目的理解分水岭算法的基本理论掌握分水岭算法图像分割方法了解分水岭算法“过分割”的改进方法。二、实验内容1.1用分水岭分割的方法对图像blob_original.tif进行处理。import cv2 import numpy as np # 读取灰度图 img cv2.imread(r./image/blob_original.tif, cv2.IMREAD_GRAYSCALE) if img is None: raise FileNotFoundError(找不到文件 blob_original.tif请确认路径正确或修改路径。) # 可视化原图缩放方便显示大图时可调整比例 def show(winname, image, scale1.0): if scale ! 1.0: h, w image.shape[:2] image cv2.resize(image, (int(w*scale), int(h*scale)), interpolationcv2.INTER_AREA) cv2.imshow(winname, image) # 1. 预处理高斯平滑去噪 blur cv2.GaussianBlur(img, (5,5), 0) # 2. 二值化Otsu _, th cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) # 确保前景是白255如果背景白占多数则反转 if np.sum(th255) np.sum(th0): th cv2.bitwise_not(th) # 3. 形态学操作开运算去小噪点闭运算填小孔 kernel cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)) opening cv2.morphologyEx(th, cv2.MORPH_OPEN, kernel, iterations2) closing cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel, iterations2) # 4. 确定背景和前景 sure_bg cv2.dilate(closing, kernel, iterations3) dist cv2.distanceTransform(closing, distanceTypecv2.DIST_L2, maskSize5) # 使用经验阈值得到 sure foreground ret, sure_fg cv2.threshold(dist, 0.4*dist.max(), 255, 0) sure_fg np.uint8(sure_fg) unknown cv2.subtract(sure_bg, sure_fg) # 5. 标记连通域作为种子 ret, markers cv2.connectedComponents(sure_fg) markers markers 1 markers[unknown255] 0 # 6. 应用分水岭要求输入为彩色 img_color cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) markers cv2.watershed(img_color, markers) # 7. 绘制结果红色边界为 watershed 边界 img_watershed img_color.copy() img_watershed[markers -1] [0, 0, 255] # 显示中间和最终结果按需要注释掉某些窗口 show(Original, img) show(Watershed Boundary (Red), img_watershed) print(按任意键关闭所有窗口。) cv2.waitKey(0) cv2.destroyAllWindows()运行结果2选做题尽可能改进算法提高分割准确度做到类似图2分割效果的有加分哦图1 blob_original.tif图2 分割结果import cv2 import numpy as np # 读取灰度图 img cv2.imread(r./image/blob_original.tif, cv2.IMREAD_GRAYSCALE) if img is None: raise FileNotFoundError(找不到文件 blob_original.tif请确认路径正确或修改路径。) # 可视化原图缩放方便显示大图时可调整比例 def show(winname, image, scale1.0): if scale ! 1.0: h, w image.shape[:2] image cv2.resize(image, (int(w*scale), int(h*scale)), interpolationcv2.INTER_AREA) cv2.imshow(winname, image) # 1. 预处理高斯平滑去噪 blur cv2.GaussianBlur(img, (5,5), 0) # 2. 二值化Otsu _, th cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) # 确保前景是白255如果背景白占多数则反转 if np.sum(th255) np.sum(th0): th cv2.bitwise_not(th) # 3. 形态学操作开运算去小噪点闭运算填小孔 kernel cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)) opening cv2.morphologyEx(th, cv2.MORPH_OPEN, kernel, iterations2) closing cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel, iterations2) # 4. 确定背景和前景 sure_bg cv2.dilate(closing, kernel, iterations3) dist cv2.distanceTransform(closing, distanceTypecv2.DIST_L2, maskSize5) # 使用经验阈值得到 sure foreground ret, sure_fg cv2.threshold(dist, 0.4*dist.max(), 255, 0) sure_fg np.uint8(sure_fg) unknown cv2.subtract(sure_bg, sure_fg) # 5. 标记连通域作为种子 ret, markers cv2.connectedComponents(sure_fg) markers markers 1 markers[unknown255] 0 # 6. 应用分水岭要求输入为彩色 img_color cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) markers cv2.watershed(img_color, markers) # 7. 绘制结果红色边界为 watershed 边界 img_watershed img_color.copy() img_watershed[markers -1] [0, 0, 255] # 8. 用白色轮廓描边每个分割区域类似你给的图2效果 output img_color.copy() unique_markers np.unique(markers) for m in unique_markers: if m 1: # 忽略背景和未标记 continue mask np.zeros(markers.shape, dtypenp.uint8) mask[markers m] 255 contours, _ cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(output, contours, -1, (255,255,255), 2) # 显示中间和最终结果按需要注释掉某些窗口 show(Original, img) show(Contours (white), output) print(按任意键关闭所有窗口。) cv2.waitKey(0) cv2.destroyAllWindows()运行结果2.阅读分水岭算法分割硬币图像的示例程序熟悉分水岭分割算法的实现过程。3.设计算法读取blood.bmp图像经过一系列操作得到细胞的分割结果。图3 blood.bmpimport cv2 import numpy as np # 读取图像 image cv2.imread(r./image/blood.bmp) if image is None: raise FileNotFoundError(找不到文件 blood1.bmp请确认路径正确) gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 3. 二值化OTSU自动阈值反转使细胞为白色前景 _, binary cv2.threshold( gray, 0, 255, cv2.THRESH_BINARY_INV cv2.THRESH_OTSU ) # 4. 形态学操作开运算去除小噪声 kernel np.ones((3, 3), np.uint8) opening cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel, iterations2) # 5. 轮廓检测RETR_EXTERNAL只检测外轮廓避免细胞内部孔洞干扰 contours, _ cv2.findContours( opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE ) # 6. 统计细胞个数 cell_count len(contours) print(f检测到的细胞个数{cell_count}) # 1. 绘制轮廓到原图红色细轮廓便于观察检测结果 image_with_contours image.copy() cv2.drawContours(image_with_contours, contours, -1, (0, 0, 255), 1) # 红色线宽1 # 2. 显示各个阶段的图像 cv2.imshow(Original Image (原图), image) cv2.imshow(Binary Image (二值化图), binary) cv2.imshow(Opening Image (形态学开运算后), opening) cv2.imshow(Cell Detection Result (细胞检测结果), image_with_contours) # 等待按键关闭所有窗口0表示无限等待按任意键退出 cv2.waitKey(0) cv2.destroyAllWindows()运行结果