如何为不连续的照片彩色蒙版区域生成单独的边框

时间:2019-02-03 21:38:06

标签: python opencv computer-vision

我想通过彩色遮罩为照片的大约非连续区域生成边界框-在这种情况下,该区域是包含植被的绿色带-以便可以裁剪该区域以传递给图像分类功能。

使用GDAL,可以很容易地使用地理空间栅格来完成对具有相似特征(https://www.gdal.org/gdal_polygonize.html)的Geotiff区域进行多边形处理的操作。但是在这种情况下,我正在尝试对照片进行处理。我还没有找到纯栅格的解决方案。

例如,拍一张像这样的照片:

enter image description here

使用openCV和numpy掩盖为绿色区域:

 try:
            hsv=cv.cvtColor(image,cv.COLOR_BGR2HSV)
        except:
            print("File may be corrupt")
            return(0,0)
        # Define lower and uppper limits of what we call "brown"
        brown_lo=np.array([18,0,0])
        brown_hi=np.array([28,255,255])

        green_lo=np.array([29,0,0])
        green_hi=np.array([88,255,255])

        # Mask image to only select browns
        mask_brown=cv.inRange(hsv,brown_lo,brown_hi)
        mask_green=cv.inRange(hsv,green_lo,green_hi)


        hsv[mask_brown>0]=(18,255,255)
        hsv[mask_green>0]=(53,255,255)

        image2=cv.cvtColor(hsv,cv.COLOR_HSV2BGR)
        cv.imwrite(QUERIES + 'queries/mask.jpg', image2)

enter image description here

我想为此处指示的区域生成拳击箱或多边形:

enter image description here

有什么想法怎么做?

我尝试使用openCV轮廓和凸包算法,但它们并不能真正带我到任何地方:

enter image description here

 threshold = val
    # Detect edges using Canny
    canny_output = cv.Canny(src_gray, threshold, threshold * 2)
    # Find contours
    _, contours, _ = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
    # Find the convex hull object for each contour
    hull_list = []
    for i in range(len(contours)):
        hull = cv.convexHull(contours[i])
        hull_list.append(hull)
    # Draw contours + hull results
    drawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)
    for i in range(len(contours)):
        color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
        cv.drawContours(drawing, contours, i, color)
        cv.drawContours(drawing, hull_list, i, color)
    # Show in a window
    cv.imshow('Contours', drawing)

1 个答案:

答案 0 :(得分:1)

因此,当您尝试使用轮廓线时它不起作用时,我尝试采用聚类的方式。我从K-means开始,这是开始IMO的最佳位置。这是代码:

import cv2
import numpy as np
from sklearn.cluster import KMeans, MeanShift
import matplotlib.pyplot as plt

def centroid_histogram(clt):
    numlabels = np.arange(0, len(np.unique(clt.labels_)) + 1)
    (hist, _) = np.histogram(clt.labels_, bins=numlabels)

    hist = hist.astype("float")
    hist /= hist.sum()

    return hist


def plot_colors(hist, centroids):
    bar = np.zeros((50, 300, 3), dtype="uint8")
    startX = 0

    for (percent, color) in zip(hist, centroids):
        endX = startX + (percent * 300)
        cv2.rectangle(bar, (int(startX), 0), (int(endX), 50),
                      color.astype("uint8").tolist(), -1)
        startX = endX

    return bar

image1 = cv2.imread('mean_shift.jpg')
image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)
image = image1.reshape((image1.shape[0] * image1.shape[1], 3))

#clt = MeanShift(bandwidth=2, bin_seeding=True)
clt = KMeans(n_clusters=3)
clt.fit(image)

hist = centroid_histogram(clt)
bar = plot_colors(hist, clt.cluster_centers_)
plt.figure()
plt.axis("off")
plt.imshow(bar)
plt.show()

使用3个群集中心,我得到以下结果:

Cluster Probability

并使用6个群集中心:

Cluster Probability 6

基本上可以显示图像中这些颜色的比例。

帮助我做到这一点的链接:

https://www.pyimagesearch.com/2014/05/26/opencv-python-k-means-color-clustering/

https://github.com/log0/build-your-own-meanshift/blob/master/Meanshift%20Image%20Segmentation.ipynb

现在,我在这里看到了几个问题:

  1. 您可能不知道所有图像中的簇数。在这种情况下,您应该查看Mean-Shift。与K-Means算法不同,meanshift不需要预先指定簇数。簇的数量由算法根据数据确定。

  2. 我在这些问题中使用了SLIC。它是基于K均值的算法的子集,非常有效。您也可以尝试一下,因为它在scikit中可用,它是python IMO中用于机器学习的goto库。在同一方向上,您也可以尝试this

希望我能为您提供一些帮助!干杯!