Как создать отдельные ограничивающие рамки для несмежных областей цветовой маски фото - PullRequest
0 голосов
/ 04 февраля 2019

Я хочу сгенерировать ограничивающие рамки для приблизительно несмежных областей фотографии по цветовой маске - в данном случае, с зелеными полосами, содержащими растительность, - чтобы я мог обрезать эту область, чтобы перейти к функции классификации изображений.

Это довольно легко сделать с помощью геопространственных растров, используя GDAL, для полигонизации областей геотифов, имеющих сходные характеристики (https://www.gdal.org/gdal_polygonize.html). Но в этом случае я пытаюсь сделать это с фотографией.Я не нашел решения для чистых растров.

Например, сделайте такую ​​фотографию:

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 голосов
/ 08 февраля 2019

Итак, когда вы попробовали с контурами, и это не сработало, я попытался пойти по пути кластеризации.Я начал с 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, средство смещения не требует указания количества кластеров заранее.Количество кластеров определяется алгоритмом по отношению к данным.

  2. Я использовал SLIC в задачах такого рода.Это подмножество алгоритмов, основанных на K-средних, и оно очень эффективно.Вы также можете попробовать его, поскольку он доступен в scikit , который является библиотекой goto для машинного обучения в python IMO.В том же направлении вы также можете попробовать эту .

Надеюсь, я вам чем-то помог!Ура!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...