Удалить капли определенного размера из видео мага OpenCV Python - PullRequest
0 голосов
/ 05 апреля 2020

У меня есть следующее изображение из сети сегментации. enter image description here

Это представление дороги (белого цвета), грунта (синего цвета) и троек (зеленого цвета), которое хорошо видно на входном изображении ниже.

enter image description here

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

Я испробовал несколько различных методов: сначала я попытался обнаружить пятна, а затем заполнить их. Это работает очень хорошо, но проблема в том, что мои капли не имеют форму круга или квадрата. Поэтому при их заполнении заполняется не только капля, но и область вокруг нее.

def filterBlobs(image,size):

    imageGray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 
    # Detect blobs.
    keypoints = detector.detect(imageGray)

    for x in range(1,len(keypoints)):
        image=cv2.circle(image, (np.int(keypoints[x].pt[0]),np.int(keypoints[x].pt[1])), radius=np.int(keypoints[x].size), color=(0,255,0), thickness=-1)

return image

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

def filterContours(image,size):
    edged = cv2.Canny(image, 175, 200)

    cv2.imshow("canny", edged)

    contours, hierarchy = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    #cv2.drawContours(image, contours, -1, (0,0,255), 100)


    for contour in contours:
        area = cv2.contourArea(contour)
        print(area)
        #if area < size:
            #cv2.drawContours(image,[contour],0,255,-1)
        cv2.fillPoly(image, pts =[contour], color=(0,0,255), maxLevel=2)
        #cv2.drawContours(image, [approx], -1, (0, 0, 255), 3)
        #hull = cv2.convexHull(cnt)

    return image

Я также попробовал medianblur. Это дает действительно приятное сглаживание краев, но исключение не удаляет пятна. Я подозреваю, что решение - комбинация медианблюра и заполнения капли.

median = cv2.medianBlur(img, 21)

Я также пробовал морфологические преобразования с открытием и закрытием. Хотя open дал лучший результат, он тоже был не очень хорош. Это связано с тем, что много деталей было потеряно при большом размере ядра, там, где по-прежнему нежелательные пятна и края не сглажены.

    kernel = np.ones((5,5),np.uint8)
    img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

В идеале мне нужен метод, который очищает сегментированное изображение таким образом, что сегментированное изображение четко представляет дорогу на входном изображении. И что весь шум от сегментированного изображения исчез.

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

Пожалуйста, предоставьте также пример кода Python, если это возможно. Также приветствуется пример c ++, я могу перевести его на Python.

Спасибо Sieuwe

РЕДАКТИРОВАТЬ: Забыл добавить, что это работает в режиме реального времени из видео подачи. FPS от 15 до 20 - моя цель. Любая тяжелая обработка, которая занимает много времени, невозможна. Он работает на i7 и GTX1080, поэтому мощности достаточно для умеренной обработки.

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