我有一些图像和相应的ROI位置,我想用这些数据生成一个遮罩图像,我try 过生成一些遮罩图像,但当只有一个ROI时效果很好,但当有两个以上的ROI时会导致遮罩连接.

是否有任何方法可以在不知道有多少ROI的情况下生成遮罩图像?

代码:

import numpy as np
import cv2
from skimage import morphology

def get_mask(imgshape, roi):
    mask = np.zeros(imgshape, dtype=np.int32)
    mask = cv2.fillConvexPoly(mask, roi, 255)
    mask = morphology.binary_closing(mask)
    return mask

mask_img = get_mask((200,200), roi_pos)

ROI = [[104,  94],[105,  94],[106,  93],[105,  92],[104,  91],
[103,  92],[103,  93],[ 95,  94],[ 96,  94],[ 97,  92],[ 97,  91],
[ 97,  91],[ 95,  91],[ 94,  91],[ 93,  93],[ 94,  94]]

Resluts: enter image description here

推荐答案

由于单个数组中有多个点,因此必须对它们进行群集.正如Rahul所提到的,K-means非常适合这项工作.

还有一个问题,你怎么知道how many ROIs are present?换句话说,how many clusters do you divide your points into

我在this post中使用了silhouette method详细井,在scikit-learn中可用

Code:

import cv2
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

# array of points/coordinates
r = np.array(ROI)

# this range can be increases if many ROIs are present
range_n_clusters = [2, 3, 4, 5]
# list to store silhouette score for each cluster   
silhouette_avg = []
for num_clusters in range_n_clusters:
 kmeans = KMeans(n_clusters=num_clusters)
 kmeans.fit(r)
 cluster_labels = kmeans.labels_
 silhouette_avg.append(silhouette_score(r, cluster_labels))
 
plt.xlabel('Values of K') 
plt.ylabel('Silhouette score') 
plt.title('Silhouette analysis For Optimal k')
plt.plot(range_n_clusters,silhouette_avg,'bx-')
plt.show()

enter image description here

必须 Select 轮廓分数最高的聚类,以获得最佳聚类结果.基于上图的最优聚类数为2.

# K-Means model with 2 clusters
final_kmeans = KMeans(n_clusters = 2)
final_kmeans.fit(r)
final_kmeans.predict(r)

# points and labels to separate lists
r_list = r.tolist()
labels = final_kmeans.predict(r).tolist()
# number of unique clusters
num_clusters = np.unique(final_kmeans.predict(r)).tolist()

# sample mask for demonstration
mask = np.zeros((300, 250,1), dtype=np.uint8)

# select points by their cluster labels and draw them
for clus in num_clusters:
  points = []
  for i, j in zip(r_list, labels):
    if j == clus:
      points.append(i)
  mask = cv2.fillConvexPoly(mask, np.array(points), 255)

enter image description here

希望这能给你一个 idea .您可以进一步优化它.记住数据集可能的最大ROI数.您可以try 其他聚类算法,也可以寻找可以获得最佳聚类数的方法

Python相关问答推荐

解析讨论论坛只给我第一个用户 comments ,但没有给我其他用户回复

如何将Matplotlib的fig.add_axes本地坐标与我的坐标关联起来?

如何终止带有队列的Python进程?+ 队列大小的错误?

通过交换 node 对链接列表进行 Select 排序

无法使用equals_html从网址获取全文

通过优化空间在Python中的饼图中添加标签

具有多个选项的计数_匹配

DataFrame groupby函数从列返回数组而不是值

Pystata:从Python并行运行stata实例

ModuleNotFound错误:没有名为flags.State的模块; flags不是包

通过Selenium从页面获取所有H2元素

组/群集按字符串中的子字符串或子字符串中的字符串轮询数据框

部分视图的DataFrame

如何根据一列的值有条件地 Select 前N组?

UNIQUE约束失败:customuser. username

CommandeError:模块numba没有属性generated_jit''''

在matplotlib中删除子图之间的间隙_mosaic

在极中解析带有数字和SI前缀的字符串

OpenCV轮廓.很难找到给定图像的所需轮廓

一个telegram 机器人应该发送一个测验如何做?""