【问题标题】:Separate image as a two part in python在python中将图像分成两部分
【发布时间】:2017-12-06 14:58:54
【问题描述】:

我有那种图片

如图所示,图像主要有两部分。 上下。

我想把它们分开。

在第一次尝试中,我使用 K-meas 算法实现。

In[2]: kmeans = KMeans(n_clusters=2, random_state=0).fit(... np.asarray(np.where(finalImage == 255)).T)

它适用于上下具有几乎相同数量的点的 Image1 案例。但不适用于图 2。

比我使用 cv2.findContours 获得最大面积 2 轮廓

im, contours, hierarchy = cv2.findContours(Img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

    # get first contour
    maxContour = 0
    for contour in contours:
        contourSize = cv2.contourArea(contour)
        if contourSize > maxContour:
            maxContour = contourSize
            maxContourData0 = contour

    # get second contour
    if contours.__len__() != 1:
        maxContour = 0
        for contour in contours:
            contourSize = cv2.contourArea(contour)
            if contourSize > maxContour and np.sum(np.subtract(contour[0:5],maxContourData0[0:5])) != 0:
                maxContour = contourSize
                maxContourData1 = contour

    mask = np.zeros_like(Img)
    cv2.fillPoly(mask, [maxContourData0], 1)
    if contours.__len__() != 1:
        cv2.fillPoly(mask, [maxContourData1], 1)

    finalImage = np.zeros_like(Img)
    finalImage[:, :] = np.multiply(Img, mask)

    cv2.imshow('final', finalImage)
    cv2.waitKey(0)

但它有时会走一个轮廓而不是 2...

有没有强制获取两个blob?

【问题讨论】:

  • 如果 blob 的实际大小并不重要,而只是相对大小,您可以在提取 blob 之前尝试应用腐蚀,这可能有助于消除两个 blob 之间的连接。

标签: python opencv image-processing computer-vision image-segmentation


【解决方案1】:

您可以尝试使用connectedComponents,但请注意,您应该将connectivity = 4 设置为默认值,而不是8

【讨论】:

  • 连通性是什么意思?
  • @JungseokCho Connectivity 定义了底层网格图的构建方式:8-connect 意味着每个像素都连接到它的所有 8 个邻居,而 4-connect 意味着一个像素只连接到四个像素上,下到最小和正确。
  • 请注意,您的示例中的两个段是“对角线”相互接触的:也就是说,它们被认为是用 8-connect 连接的,但考虑到 4-connect 是分开的
【解决方案2】:

如果您不介意运行时间,可以尝试光谱聚类。

K-means 不适用于这个问题,因为它隐含地假设集群是球形的,而光谱聚类更关心连通性。坏消息是它比 K-means 慢得多。

下面是我使用sklearn.cluster.SpectralClustering的实现:

t0 = time.time()
spectral = cluster.SpectralClustering(n_clusters=2, affinity='rbf', n_init=3)
spectral.fit(pts)
t1 = time.time()
print(t1-t0)

输出:

19.5850000381

【讨论】:

  • @JungseokCho 只需几秒钟。
  • 光谱聚类在不同尺度的聚类中存在一个已证明的问题。您应该在示例中谨慎使用它。
猜你喜欢
  • 1970-01-01
  • 2011-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-10
  • 1970-01-01
  • 2014-10-17
相关资源
最近更新 更多