OpenCV Python-различные методы аппроксимации контуров имеют одинаковый выход [дубликат]



На этот вопрос уже есть ответ здесь:

Согласно этому учебнику Python, существуют два метода аппроксимации контуров для OpenCV cv2.findContours функция: cv2.CHAIN_APPROX_NONE и cv2.CHAIN_APPROX_SIMPLE . Первый метод сохраняет все граничные точки, а второй метод удаляет все избыточные точки.

import cv2

im = cv2.imread('simple.jpg')
imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
_, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, 
cv2.CHAIN_APPROX_SIMPLE)

img = cv2.drawContours(im, contours, -1, (0, 255, 0), 3)


cv2.imshow('Output', img)
wk = cv2.waitKey(0) & 0xFF
if wk == 27:
    cv2.destroyAllWindows()
Но этот код выдает одно и то же изображение, независимо от того, какой метод он использует.

Вот изображение после выполнения кода: вывод

Зеленые линии-это контуры. Как вы можете видеть, прямоугольник окружен зелеными линиями, но он должен быть определен только 4 точками, по одной на каждый угол.

506   2  

2 ответов:

Если вы посмотрите на учебник, в частности, в нижней части текста он читает:

Просто нарисуйте круг на всех координатах в контурном массиве (нарисованный синим цветом).

Mehul Jain правильно, если вы используете cv2.drawContours, он просто соединяет точки вместе при рисовании контура. Вы не заметите разницы между двумя методами аппроксимации. Что вам нужно сделать, это круги рисовать вместо этого.

Поэтому как только вы запустите cv2.findContours, Вы можете использовать выход contours, который представляет собой список всех контуров, найденных на изображении. Поскольку существует только один возможный контур, поскольку это квадрат, список должен быть длиной в один элемент. Также обратите внимание, что выход будет представлять собой массив (N, 1, 2) 3D NumPy, поэтому лучше всего преобразовать его в массив из 2 столбцов, прежде чем продолжить.

Далее, вы можете использовать cv2.circle, чтобы фактически взять каждую точку и нарисовать отдельные круги вместо фактического контура. Только тогда вы действительно увидите разница.

Взяв ваш код выше и изменив его так, чтобы мы делали два метода, мы должны сделать это вместо этого:

### Your code
import numpy as np
import cv2

im = cv2.imread('simple.jpg')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)

### Step #1
# Detect contours using both methods on the same image
_, contours1, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
_, contours2, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

### Step #2 - Reshape to 2D matrices
contours1 = contours1[0].reshape(-1,2)
contours2 = contours2[0].reshape(-1,2)

### Step #3 - Draw the points as individual circles in the image
img1 = im.copy()
img2 = im.copy()

for (x, y) in contours1:
    cv2.circle(img1, (x, y), 1, (255, 0, 0), 3)

for (x, y) in contours2:
    cv2.circle(img2, (x, y), 1, (255, 0, 0), 3)

### Step #4 - Stack the two images side by side and show it
out = np.hstack([img1, img2])
cv2.imshow('Output', out)
cv2.waitKey(0)
cv2.destroyAllWindows()

Давайте медленно пройдемся по коду. Первая часть кода-это то, что вы предоставили. Теперь мы переходим к тому, что является новым.

Шаг #1-обнаружение контуров с использованием обоих методов

Используя пороговое изображение, мы обнаруживаем контуры, используя как полные, так и простые приближения. Это сохраняется в двух списках, contours1 и contours2.

Шаг #2-преобразование в 2D матрицы

Сами контуры сохраняются в виде списка массивов NumPy. Для простого представленного изображения должен быть обнаружен только один контур, поэтому извлеките первый элемент списка, а затем используйте numpy.reshape для преобразования трехмерных матриц в их 2D-формы, где каждая строка является точкой (x, y).

Шаг №3-нарисуйте точки в виде отдельных кругов на изображении

Следующим шагом будет взять каждую точку (x, y) из каждого набора контуры и нарисуйте их на изображении. Мы делаем две копии исходного изображения в цветной форме, затем используем cv2.circle и перебираем каждую пару точек (x, y) для обоих наборов контуров и заполняем два разных изображения - по одному для каждого набора контуров.

Шаг #4-Сложите два изображения рядом и покажите его

Мы, наконец, используем numpy.hstack, Чтобы сложить изображения горизонтально, и мы показываем результат. Вы увидите, что оба изображения, где левое изображение является полным контуром приближение в то время как правильное изображение является упрощенным вариантом.

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

    Ничего не найдено.

Добавить ответ:
Отменить.