Обнаружение областей с низкой плотностью белых пикселей - PullRequest
0 голосов
/ 14 февраля 2019

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

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

(

В моей программе я получаю координаты белых пикселей перед тем, как сделать снимок.Затем я создаю черный BufferedImage и пишу белый пиксель на каждой координате, чтобы создать изображение, которое я прикрепил.Для меня самое важное - определить, содержит ли изображение полностью черные области, которые больше регулируемого размера (мне нужно экспериментировать, чтобы найти правильную настройку)

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

Я использую Java и OpenCV в своей программе,У кого-нибудь есть предложения о том, как поступить, чтобы сделать это?Есть ли какие-то функции в OpenCV, которые могут мне помочь?

Оцените все ответы

1 Ответ

0 голосов
/ 15 февраля 2019

Вот грубый способ решить эту проблему.Я решил это с помощью Python, но все те же правила применяются к Java.

Я начинаю с того, что получаю тестовый набор для работы с точками, которые имеют пробел и некоторую случайность.

w, h = 1000, 1000
spacing = 25
blast_size = 100


def distance(p1, p2):
    return math.sqrt(math.pow(p1[0] - p2[0], 2) + math.pow(p1[1] - p2[1], 2))


def keep_point(p):
    if p[0] < 0 or p[0] >= w or p[1] < 0 or p[1] >= h:
        return False
    d = distance(p, (w/2, h/2))
    if d > blast_size:
        return True
    return False


grid = [
    (i + random.randint(-spacing, spacing), j + random.randint(-spacing, spacing))
    for i in range(spacing, w, spacing*2)
    for j in range(spacing, h, spacing*2)
]
grid = list(filter(keep_point, grid))


initial = np.zeros((h, w), np.uint8)
for i, j in grid:
    image[i, j] = 255

cv2.imshow("Initial", initial)
cv2.waitKey()

enter image description here

Далее я вычисляю минимальное расстояние, которое каждая точка имеет до соседа.Наибольшее минимальное расстояние будет использовано как радиус нашей свертки.После завершения свертки разрыв будет очень заметным.Чтобы получить центр разрыва после свертки, я беру среднее из контуров.Если у вас может быть несколько пропусков, вам нужно будет обнаружить капли в этом месте.

# Don't include self as a neighbor
def distance_non_equal(p1, p2):
    if p1 == p2:
        return float('inf')
    return distance(p1, p2)


min_distance = [
    min(map(lambda p2: distance_non_equal(p1, p2), grid))
    for p1 in grid
]

radius = int(max(min_distance))

kernel = np.zeros((2*radius+1, 2*radius+1), np.uint8)
y,x = np.ogrid[-radius:radius+1, -radius:radius+1]
mask = x**2 + y**2 <= radius**2
kernel[mask] = 255

convolution = cv2.filter2D(image, cv2.CV_8U, kernel)

contours = cv2.findContours(convolution, 0, 2)
avg = np.mean(contours[0],axis=1)
x = int(round(avg[0,0,0]))
y = int(round(avg[0,0,1]))

convolution[x, y] = 255
cv2.imshow("Convolution", convolution)
cv2.waitKey()

enter image description here

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

def get_angle(p):
    angle = math.degrees(math.atan2(y - p[1], x - p[0]))
    if angle < 0:
        angle += 360
    return angle

angles = list(map(get_angle, grid))
zones = [
    [
        p
        for angle, p in zip(angles, grid)
        if i < angle < i + 360//12
    ]
    for i in range(0,360,360//12)
]

closest = [
    min(zone, key=lambda p2: distance((x,y), p2))
    for zone in zones
]

final = np.zeros((h, w, 3), np.uint8)
for i, j in grid:
    final[i, j] = [100,100,100]
for i, j in closest:
    final[i, j] = [255,255,255]

cv2.imshow("final", final)
cv2.waitKey()

enter image description here

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