python先使用颜色阈值分割,再对实体进行像素标记

问题描述

在这里插入图片描述

1、使用颜色的阈值分割方式,将图片二值化,提取出其中的红色五角星
2、python实现像素标记,获得图中红色五角星的数量。


颜色阈值分割

要求是使用颜色的阈值分割方式,将图片二值化,提取出其中的红色五角星,然后我就先寻找哪种色彩读取方式能够便于提取红色五角星,我首先将读取的图像转化为HSV,然后分别提取每个通道的结果,发现每个通道都很难将红色五角星和其他颜色进行很好的区分,然后我又以BGR的形式读取图像,发现G通道的结果可以对红色五角星进行很好的分离,但是右上角的五角星和背景相类似,所以需要在阈值分割时选取合适的参数,这里我首先是将两个五角星和右上角的背景提取出来,然后我又选取合适的参数分离出右上不是五角星的区域,通过二者相减可以得到两个五角星,但是此时又有一条边界线,所以我有使用开操作将边界线去除。

# 得到五角星和右上角
t1, dst = cv2.threshold(img[:, :, 1], 40, 255, cv2.THRESH_BINARY)

# 得到右上不是五角星的区域
t2, dst2 = cv2.threshold(img[:, :, 1], 20, 255, cv2.THRESH_BINARY)

# 此时有一条边界线
fin_img = dst2 - dst

# 使用形态学方法去除边界线
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
fin_img = cv2.morphologyEx(fin_img, op=cv2.MORPH_OPEN, kernel=kernel)

在这里插入图片描述


像素标记

在得到两个五角星后需要对每个五角星进行像素标记,这里我自己编写了一个顺次扫描法的像素标记方法,处理时使用到了图论的知识,将问题看成了无向图求解所有连通子图的问题,这里我使用到了networkx包,在得到连通子图后对像素点的标记进行修改,同一连通子图上的像素被标记为同一个实体,五角星的个数为连通子图的个数,然后对不同的实体设置不同的颜色,我这里是根据实体的个数将256个灰度级进行划分,我仅将绘图的过程进行分享,由于这个功能我花费了挺多时间,我这里就仅提供下思路吧有需要可以私信联系我哈

# 将各像素点的标号进行修改,并绘图
pro_img = np.zeros(fin_img.shape, dtype=np.uint8)
for i in range(h):
    for j in range(w):
        if img_flag[i][j] != 0:
            img_flag[i][j] = map_p[img_flag[i][j]]
            pro_img[i][j] = img_flag[i][j] * int(255 / num)

最后的结果如下:
在这里插入图片描述

### 使用PythonOpenCV分离图像中的粘连区域 为了有效分离图像中的粘连区域,可以采用多种技术组合来提高准确性。以下是几种常用的方法及其具体实现: #### 方法一:基于距离变换的距离阈值法 这种方法通过计算每个像素到最近背景像素的距离,并设定一定阈值来进行分割。 ```python import cv2 import numpy as np def distance_transform_separation(image_path): # 读取灰度图并进行二值化处理 img = cv2.imread(image_path, 0) _, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # 距离变换 dist_transform = cv2.distanceTransform(thresh, cv2.DIST_L2, 5) # 应用固定阈值获取前景掩模 ret, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0) # 将前景转换成8位无符号整型 sure_fg = np.uint8(sure_fg) # 获取未知区域 unknown = cv2.subtract(thresh, sure_fg) # 进行分水岭算法标记 markers = cv2.watershed(cv2.cvtColor(img, cv2.COLOR_GRAY2BGR), sure_fg)[1] return markers ``` 此方法利用了距离变换特性,在一定程度上改善了单纯使用形态学操作难以解决的问题[^3]。 #### 方法二:结合K-Means聚类的分割方式 当目标物体颜色分布较为均匀时,可尝试应用K-means聚类模型对色彩空间内的数据点分类,从而达到区分不同对象的目的。 ```python from sklearn.cluster import KMeans def kmeans_segmentation(image_path, n_clusters=2): image = cv2.imread(image_path) Z = image.reshape((-1, 3)) # 归一化特征向量 Z = np.float32(Z / 255.0) criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0) attempts = 10 km = KMeans(n_clusters=n_clusters, random_state=None).fit(Z) labels = km.labels_ centers = km.cluster_centers_ res = centers[labels.flatten()] segmented_image = res.reshape((image.shape)) return segmented_image ``` 该方案适用于具有明显色差的对象间分离任务,尤其适合于复杂背景下提取特定类别实体的情况。 #### 方法三:混合策略——腐蚀再膨胀恢复形状 针对某些特殊场景下的粘连现象,可以通过适当调整结构元素大小实施开闭运算序列,即执行一次较大尺度的腐蚀去除连接部分后再做相应尺寸范围内的膨胀还原原始轮廓。 ```python kernel_size = (9, 9) # 可调参数取决于实际需求 morph_kernel = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=kernel_size) eroded_img = cv2.erode(src=image_binary, kernel=morph_kernel, iterations=1) dilated_img = cv2.dilate(eroded_img, morph_kernel, iterations=1) ``` 上述三种手段各有优劣之处,可根据待解决问题的具体特点灵活选用或综合运用以获得更佳效果。值得注意的是,预处理阶段的质量控制同样至关重要,良好的去噪和平滑措施有助于后续步骤顺利开展[^1][^2].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值