问题描述
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)
最后的结果如下: