python
复制代码
import cv2 as cv
import numpy as np
# 1. 读取图像并校验
src = cv.imread('./image/28.bmp')
if src is None:
print('图像读取失败,请检查路径!')
exit()
# 备份原图(避免后续操作修改原始数据)
src_origin = src.copy()
# 初始化结果画布
result = np.zeros_like(src)
# 2. 手动背景去除:过滤白色背景(RGB=255,255,255)
# 遍历图像所有像素(优化双层循环,避免冗余自增)
for i in range(src.shape[0]):
for j in range(src.shape[1]):
# 获取当前像素的BGR值
b, g, r = src[i, j]
# 判断是否为白色背景像素
if b == 255 and g == 255 and r == 255:
src[i, j] = [0, 0, 0] # 白色背景转为黑色
else:
result[i, j] = src[i, j] # 保留前景像素
# 3. 分水岭算法前置处理(可选,进阶分割)
gray = cv.cvtColor(result, cv.COLOR_BGR2GRAY)
# 二值化:强化前景与背景对比
ret, binary = cv.threshold(gray, 10, 255, cv.THRESH_BINARY)
# 距离变换:获取前景种子点
dist_transform = cv.distanceTransform(binary, cv.DIST_L2, 5)
ret, sure_fg = cv.threshold(dist_transform, 0.7*dist_transform.max(), 255, 0)
sure_fg = np.uint8(sure_fg)
# 查找未知区域(背景-前景)
sure_bg = cv.dilate(binary, np.ones((3,3), np.uint8), iterations=2)
unknown = cv.subtract(sure_bg, sure_fg)
# 4. 标记连通域,执行分水岭分割
ret, markers = cv.connectedComponents(sure_fg)
markers = markers + 1 # 背景标记为1,避免与未知区域混淆
markers[unknown==255] = 0 # 未知区域标记为0
markers = cv.watershed(src_origin, markers)
src_origin[markers == -1] = [0, 0, 255] # 分割线标红
# 5. 显示结果
cv.namedWindow('背景去除结果', cv.WINDOW_NORMAL)
cv.resizeWindow('背景去除结果', 600, 600)
cv.imshow('背景去除结果', result)
cv.namedWindow('分水岭分割结果', cv.WINDOW_NORMAL)
cv.resizeWindow('分水岭分割结果', 600, 600)
cv.imshow('分水岭分割结果', src_origin)
cv.waitKeyEx(0)
cv.destroyAllWindows()