Возможно ли использовать контур OpenCV в Python таким образом, чтобы углы не были обрезаны? - PullRequest
0 голосов
/ 12 февраля 2019

Я использую контурную функцию OpenCV в Python.Например, на изображении, подобном этому:

enter image description here

contours, _ = cv2.findContours(img_expanded_padded, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

enter image description here Это работает хорошо, за исключением того, что оно обрезаетуглы на внутренней стороне контура, как показано выше.Есть ли какие-либо варианты, которые оставили бы этот угол в?

Путешествие по контурам и заполнение их вручную будет слишком дорогим в вычислительном отношении.Выше приведен только пример.Это будет выполняться много раз для изображений 5400x5400 или более ...

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

# FIND ALL HORIZONTAL AND VERTICAL EDGES AND COMBINE THEM
edges_expanded_x = np.absolute(cv2.Sobel(img_expanded_padded,cv2.CV_64F, 1, 0, ksize=3))
edges_expanded_y = np.absolute(cv2.Sobel(img_expanded_padded,cv2.CV_64F, 0, 1, ksize=3))
edges_expanded = np.logical_or(edges_expanded_x, edges_expanded_y)

# GET RID OF DOUBLE EDGE THAT RESULTS FROM SOBEL FILTER
edges_expanded = np.multiply(img_expanded_padded,edges_expanded)

Существуют ли какие-либо настройки или функции OpenCV, которые я могу использовать для этого?

РЕДАКТИРОВАТЬ: Я должен уточнить, что моя цель - иметь непрерывный контур в один пиксель.Мне нужны контуры, а не массив всего изображения, включая контуры.

РЕДАКТИРОВАТЬ: Приведенные выше изображения увеличены в моем тестовом изображении.Фактические пиксели соответствуют красным сеткам на изображениях ниже.

enter image description here

enter image description here

1 Ответ

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

Нет необходимости использовать cv2.Sobel, вы можете просто рисовать контуры с cv2.drawContours на черном фоне.Черный фон можно нарисовать с помощью np.zeros.

img = cv2.imread('contouring.png',0)
contours, _ = cv2.findContours(img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
bgr = np.zeros((img.shape[0], img.shape[1]), dtype= 'uint8')
cv2.drawContours(bgr, contours, -1, (255,255,255), 1)

thin egdes

Если вы хотите, чтобы контурные линии были толстыми, используйтеcv2.dilate за это.Затем для предотвращения обрезки углов можно использовать cv2.bitwise_and вместе с cv2.bitwise_not, как показано ниже

bgr = cv2.dilate(bgr, np.ones((31, 31), np.uint8), iterations=1)
bgr = cv2.bitwise_and(bgr, cv2.bitwise_not(img))

Это дает контуры толщиной 15 пикселей.thick edges

РЕДАКТИРОВАТЬ - первое изображение тонких контуров все еще срезает углы.Чтобы получить однопиксельные контуры без углов, мы можем использовать размер ядра 3 * 3.

img = cv2.imread('contouring.png',0)
contours, _ = cv2.findContours(img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
bgr = np.zeros((img.shape[0], img.shape[1]), dtype= 'uint8')
cv2.drawContours(bgr, contours, -1, (255,255,255), 1)
bgr = cv2.dilate(bgr, np.ones((3, 3), np.uint8), iterations=1)
bgr = cv2.bitwise_and(bgr, cv2.bitwise_not(img))

Это дает нам RESULT

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

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