【问题标题】:Use python opencv to generate irregular masks image without knowing the number of masks在不知道掩码数量的情况下使用python opencv生成不规则掩码图像
【发布时间】:2022-06-10 20:31:13
【问题描述】:

我有一些图像和对应的 ROI 位置,我想用这些数据生成掩码图像,我尝试生成一些掩码图像,但是当只有一个 ROI 时它工作正常,但是当有更多超过两个 ROI 会导致 mask 连接。

有什么方法可以在不知道有多少 ROI 的情况下生成 Mask 图像?

代码:

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]]

结果:

【问题讨论】:

  • 你的逻辑错了。您正在做的是通过所有 ROI 点来获得多边形。这会将它们全部视为一个多边形,并为您提供您现在得到的结果。在我们看来,它看起来像 2 个集群,但对于计算机来说,它只会看起来像一个集群/多边形。因此,您只需将一组点单独传递给您的函数。您可以通过使点彼此靠近来尝试此操作。为此,请尝试使用任何聚类算法,例如 K-Means Clustering,然后逐个传递每个聚类。

标签: python opencv image-processing


【解决方案1】:

由于单个数组中有许多点,因此您必须将它们聚集在一起。如前所述,K-means 非常适合这项工作。

还有一个问题,你怎么知道有多少个 ROIs?换句话说,您将您的点分为多少个集群

我使用了this post中详细介绍的剪影法,在scikit-learn中可用

代码:

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()

必须选择具有最高轮廓分数的聚类才能提供最佳聚类结果。根据上图的最佳聚类数为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)

希望这能给你一个想法。您可以进一步优化它。记住您的数据集可能的最大 ROI 数量

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    • 1970-01-01
    相关资源
    最近更新 更多