Фильтрация шума из очень шумного двоичного порогового изображения - PullRequest
3 голосов
/ 02 марта 2020

Я хотел бы иметь возможность проанализировать следующее изображение, получить линии и определить среднюю ширину. (Моя копия намного больше ~ 5K на ~ 4K) Невозможно перейти к следующему шагу из-за всех шумов после установки порога.

enter image description here

Используя мой код, я смог добраться до этой точки ...

enter image description here

Моя проблема в том, что в нем много шума между линиями, который выглядит как шум, который стал конденсированным.

Вот мой код ...

image = np.copy(origImg)
newImage = np.empty_like(image)

scale = 64

height = image.shape[0]
width = image.shape[1]

dH = int(height / scale)
dW = int(width / scale)

xi = int(dH)
yi = int(dW)

fragments = []
image = cv2.bilateralFilter(image,9,75,75)
image = cv2.medianBlur(image, 21)

for i in range(0,height,dH):
    for j in range(0,width,dW):
        fragment = image[i:i + int(dH), j:j + int(dW)]

        fragment = cv2.adaptiveThreshold(fragment, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 0)

        fragments.append(fragment)

analyzed = com.stackArrayToImage(fragments)

nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(analyzed, None, None, None, 8, cv2.CV_32S)
sizes = stats[1:, -1] 
img2 = np.zeros((labels.shape), np.uint8)

for i in range(0, nlabels - 1):
    if sizes[i] >= 100:  
        img2[labels == i + 1] = 255

analyzed = cv2.bitwise_not(img2)

analyzed = cv2.erode(analyzed, np.ones((5, 5)), iterations=2)
analyzed = cv2.dilate(analyzed, np.ones((5, 5), np.uint8))

dis.plotImages([origImg], "Origional")
dis.plotImages([analyzed], "Analyzed")
dis.displayStart() 

Можно ли как-нибудь убрать этот шум?

Большое спасибо!

1 Ответ

2 голосов
/ 03 марта 2020

Вы можете удалить часть шума с помощью фильтрации области контура с помощью cv2.contourArea. Идея состоит в том, чтобы фильтровать, используя некоторую пороговую область. Если контур проходит через этот фильтр, мы можем удалить шум, заполнив контур с помощью cv2.drawContours. Использование вашего двоичного изображения в качестве ввода:

enter image description here

Обнаруженные контуры для удаления выделены зеленым цветом

enter image description here

Результат

enter image description here

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

Код

import numpy as np
import cv2

# Load image, grayscale, Otsu's threshold
image = cv2.imread("1.png")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

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

result = 255 - thresh
cv2.imshow("image", image) 
cv2.imshow("thresh", thresh) 
cv2.imshow("result", result) 
cv2.waitKey()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...