Получить периметр пикселей вокруг центрального пикселя - PullRequest
0 голосов
/ 16 ноября 2018

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

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

image description

Ответы [ 3 ]

0 голосов
/ 16 ноября 2018

Формула:

(x-cx)**2 + (y-cy)**2 = r**2

, где cx и cy - центр круга, а x и y - координаты, которые вы хотите проверить ... Теперь мы можем перебрать x и получить yс формулой, подобной этой:

y = sqrt(r**2 - (x-cx)**2) + cy

Другим способом будет итерация 360 градусов, вычисление x и y и добавление смещения (в центре) следующим образом:

x = cos(radians) * radius + cx
y = sin(radians) * radius + cy

Вторая версия дала мне более полный круг в моих тестах.Вот мой тестовый скрипт на python:

import numpy as np
import cv2
import math

img = np.zeros((480, 640, 1), dtype="uint8")
img2 = np.zeros((480, 640, 1), dtype="uint8")

center = (200, 200)
radius = 100

x = np.arange(center[0] - radius, center[0]+radius+1)
y_off = np.sqrt(radius**2 - (x - center[0]) **2)
y1 = np.int32(np.round(center[1] + y_off))
y2 = np.int32(np.round(center[1] - y_off))
img[y1, x] = 255
img[y2, x] = 255


degrees = np.arange(360)
x = np.int32(np.round(np.cos(degrees) * radius)) + center[0]
y = np.int32(np.round(np.sin(degrees) * radius)) + center[1]
img2[y,x] = 255


cv2.imshow("First method", img)
cv2.imshow("Second method", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

, и результаты следующие:

Метод 1

enter image description here

Метод 2

enter image description here

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


ОБНОВЛЕНИЕ:

Просто небольшое напоминание, убедитесь, что ваши точки на изображении, в примере выше, еслиВы помещаете центр в 0,0, он будет рисовать 1/4 круга в каждом углу, потому что он считает, что отрицательные значения начинаются с конца массива.

Для удаления дубликатов вы можете попробовать следующий код:

c = np.unique(np.array(list(zip(y,x))), axis=0  )
img2[c[:,0], c[:,1]] = 255
0 голосов
/ 16 ноября 2018

Просто нарисуйте круг на маске:

In [27]: mask = np.zeros((9, 9), dtype=np.uint8)

In [28]: cv2.circle(mask, center=(4, 4), radius=4, color=255, thickness=1)
Out[28]:
array([[  0,   0,   0,   0, 255,   0,   0,   0,   0],
       [  0,   0, 255, 255,   0, 255, 255,   0,   0],
       [  0, 255,   0,   0,   0,   0,   0, 255,   0],
       [  0, 255,   0,   0,   0,   0,   0, 255,   0],
       [255,   0,   0,   0,   0,   0,   0,   0, 255],
       [  0, 255,   0,   0,   0,   0,   0, 255,   0],
       [  0, 255,   0,   0,   0,   0,   0, 255,   0],
       [  0,   0, 255, 255,   0, 255, 255,   0,   0],
       [  0,   0,   0,   0, 255,   0,   0,   0,   0]], dtype=uint8)

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

In [33]: img
Out[33]:
array([[ 88, 239, 212, 160,  89,  85, 249, 242,  88],
       [ 47, 230, 206, 206,  63, 143, 152,  67,  58],
       [162, 212,   0, 213, 208, 169, 228,  14, 229],
       [230,  45, 103, 201, 188, 231,  80, 122, 131],
       [159,  31, 148, 158,  73, 215, 152, 158, 235],
       [213, 177, 148, 237,  92, 115, 152, 188, 223],
       [234,  67, 141, 173,  14,  18, 242, 208, 147],
       [ 53, 194, 229, 141,  37, 215, 230, 167,  82],
       [ 72,  78, 152,  76, 230, 128, 137,  25, 168]], dtype=uint8)

Вот значения по периметру:

In [34]: img[np.nonzero(mask)]
Out[34]:
array([ 89, 206, 206, 143, 152, 212,  14,  45, 122, 159, 235, 177, 188,
        67, 208, 229, 141, 215, 230, 230], dtype=uint8)

Установка значения изображения по периметру круга на 0:

In [35]: img[np.nonzero(mask)] = 0

In [36]: img
Out[36]:
array([[ 88, 239, 212, 160,   0,  85, 249, 242,  88],
       [ 47, 230,   0,   0,  63,   0,   0,  67,  58],
       [162,   0,   0, 213, 208, 169, 228,   0, 229],
       [230,   0, 103, 201, 188, 231,  80,   0, 131],
       [  0,  31, 148, 158,  73, 215, 152, 158,   0],
       [213,   0, 148, 237,  92, 115, 152,   0, 223],
       [234,   0, 141, 173,  14,  18, 242,   0, 147],
       [ 53, 194,   0,   0,  37,   0,   0, 167,  82],
       [ 72,  78, 152,  76,   0, 128, 137,  25, 168]], dtype=uint8)

Вы также можете легко получить координаты:

In [56]: np.where(mask)
Out[56]:
(array([0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8]),
 array([4, 2, 3, 5, 6, 1, 7, 1, 7, 0, 8, 1, 7, 1, 7, 2, 3, 5, 6, 4]))
0 голосов
/ 16 ноября 2018

Предположим, img - ваше изображение, radius - радиус круга, а x, y - координаты центра, вокруг которого вы хотите сфокусироваться.

Значение focus_img может бытьполученный с использованием

offset = math.ceil(radius * math.sqrt(2))
focus_img = img[y-offset:y+offset, x-offset:x+offset]
...