Необходимо определить вторые крайние точки изображения с помощью Contour - PullRequest
1 голос
/ 30 марта 2020

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

Я пытаюсь сделать, как показано ниже.

  1. Я нахожу все контуры изображения.
  2. Сортировка контура NumPy массив
  3. Удаление последнего элемента в массиве Numpy для удаления внешний контур, чтобы не учитывать в экстремальных точках обнаружения.
  4. Выберите крайние точки

ниже приведен код:

import imutils
import cv2
import numpy as np

image = cv2.imread(r"SimpleBoxTest.png")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)

thresh = cv2.threshold(gray, 45, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.erode(thresh, None, iterations=2)
thresh = cv2.dilate(thresh, None, iterations=2)

cnts = cv2.findContours(thresh.copy(), cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)

c=sorted(cnts, key=cv2.contourArea)
c = np.delete(c, (-1), axis=0) 

extLeft = tuple(c[c[:, :, 0].argmin()][0])
extRight = tuple(c[c[:, :, 0].argmax()][0])
extTop = tuple(c[c[:, :, 1].argmin()][0])
extBot = tuple(c[c[:, :, 1].argmax()][0])

Ниже приведена ошибка

Traceback (most recent call last):
  File "C:/TestCode/DocumentLayoutDetection/extreamPoints.py", line 41, in <module>
    extLeft = tuple(c[c[:, :, 0].argmin()][0])
IndexError: too many indices for array

Ниже изображение просто эталонное изображение, я буду пробовать и для других изображений Input image

Изображение 2 enter image description here

Ответы [ 2 ]

1 голос
/ 30 марта 2020

Вам не нужно удалять последний элемент, вы можете получить второй элемент с конца.

  • Результат c=sorted(cnts, key=cv2.contourArea) - это не массив NumPy, это список .
    Вы можете проверить тип, используя type(c), а результат - <class 'list'>.
    Вы можете удалить последний элемент, используя del: del c[-1], но это не обязательно.
  • Использование: c = c[-2] для извлечения второго последнего элемента списка.
    Теперь type(c) равно <class 'numpy.ndarray'>.
  • Найдите минимальное и максимальное значения, используя extLeft = c[:, :, 0].min() и extRight = c[:, :, 0].max().

Вот код:

import imutils
import cv2
import numpy as np

image = cv2.imread(r"SimpleBoxTest.png")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)

thresh = cv2.threshold(gray, 45, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.erode(thresh, None, iterations=2)
thresh = cv2.dilate(thresh, None, iterations=2)

cnts = cv2.findContours(thresh.copy(), cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)

c=sorted(cnts, key=cv2.contourArea)

#c = np.delete(c, (-1), axis=0) 

# c is a list, and not a numpy array, so use del instead of np.delete
# But why?
# del c[-1]

# Get one element before the last element in the list
c = c[-2] # Now c is a numpy.ndarray

extLeft = c[:, :, 0].min()
extRight = c[:, :, 0].max()
extTop = c[:, :, 1].min()
extBot = c[:, :, 1].max()

# Draw rectangle for testing
cv2.rectangle(image, (extLeft, extTop), (extRight, extBot), (0, 255, 0))

cv2.imshow("image", image)
cv2.waitKey()
cv2.destroyAllWindows();

Обновление:

Если вам нужны вторые вторые крайние точки среди всех найденных контуров, вы может повторять контуры в c:

# Mark all contours with red:
cv2.drawContours(image, cnts, -1, (0, 0, 255), thickness=5)

# Delete last element of the list
del c[-1]

# Initialize:
extLeft, extRight, extTop, extBot = 1e9, -1e9, 1e9, -1e9

# Iterate list and find the extreme points
for cc in c:
    extLeft = min(cc[:, :, 0].min(), extLeft)
    extRight = max(cc[:, :, 0].max(), extRight)
    extTop = min(cc[:, :, 1].min(), extTop)
    extBot = max(cc[:, :, 1].max(), extBot)

# Draw rectangle for testing
cv2.rectangle(image, (extLeft, extTop), (extRight, extBot), (0, 255, 0), thickness=5)

Решение без использования for для l oop:

  • Вы можете использовать np.vstack(c) для объединения NumPy массивов в списке.
    Затем найдите крайние точки в объединенном массиве.

Код:

# Delete last element of the list.
del c[-1]

# Concatenate arrays along vertical axis.
c = np.vstack(c)

# Find extreme points:
extLeft = c[:, :, 0].min()
extRight = c[:, :, 0].max()
extTop = c[:, :, 1].min()
extBot = c[:, :, 1].max()

Результат:
enter image description here

0 голосов
/ 30 марта 2020

Переменная c представляет собой список массивов, поэтому добавьте для l oop значение, чтобы перебрать его. Это решило ошибку:

for d in c:
    extLeft = tuple(d[d[:, :, 0].argmin()][0])
    extRight = tuple(d[d[:, :, 0].argmax()][0])
    extTop = tuple(d[d[:, :, 1].argmin()][0])
    extBot = tuple(d[d[:, :, 1].argmax()][0])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...