在 python 中将图像分成两部分

Separate image as a two part in python

我有一张这样的图

如图所示,图片主要分为两部分。 上下.

我想把它们分开

第一次尝试,我用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

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

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

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