Нахождение плотного контура вокруг размытого объекта с помощью Python OpenCV - PullRequest
2 голосов
/ 11 марта 2020

У меня проблемы с поиском контуров вокруг размытого объекта. Вот несколько примеров того, чего я хочу достичь:

enter image description here

enter image description here

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

Я также безуспешно попробовал энтропийный фильтр скимаджа. Обнаружение Canny Edge также невозможно из-за размытой природы изображений.

Но так как мои глаза могут рисовать вокруг объектов, я думаю, что должен быть простой способ найти контур с помощью python и откройте резюме.

Заранее спасибо! Лука

Ответы [ 2 ]

1 голос
/ 12 марта 2020

Простой подход заключается в использовании порога Оцу или адаптивного порога для автоматического определения порогового значения. Идея состоит в том, чтобы размытие по Гауссу , порог для получения двоичного изображения, затем найти контуры и выделить контур с помощью cv2.drawContours. Возможно, вам придется настроить параметры, чтобы получить желаемый результат. Результаты:

Входные данные (снимок экрана) -> Выходные данные

enter image description here enter image description here

enter image description here enter image description here

import cv2
import numpy as np

# Load image, grayscale, Gaussian blur, Adaptive threshold
image = cv2.imread('2.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (9,9), 0)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,23,3)

# Find contours and filter using contour area
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    area = cv2.contourArea(c)
    if area > 10:
        cv2.drawContours(image, [c], -1, (36,255,12), 1)

cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.waitKey()     
0 голосов
/ 11 марта 2020

Мне кажется, я наконец-то получил ответ на свою проблему. Если кто-то борется с подобной проблемой, посмотрите возможности адаптивного порога open cv!

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