Как обнаружить / найти контуры флажка с помощью OpenCV - PullRequest
4 голосов
/ 19 апреля 2019

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

Я использую findContours для рисования контуров только на флажках в отсканированном документе.Но алгоритм извлекает все контуры текста.

from imutils.perspective import four_point_transform
from imutils import contours
import numpy as np
import argparse, imutils, cv2, matplotlib
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

image = cv2.imread("1.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(blurred, 75, 200)

im_test = [blurred, cv2.GaussianBlur(gray, (7, 7), 0), cv2.GaussianBlur(gray, (5, 5), 5), cv2.GaussianBlur(gray, (11, 11), 0)]
im_thresh = [ cv2.threshold(i, 127, 255, 0)  for i in im_test ]
im_thresh_0 = [i[1] for i in im_thresh ]
im_cnt = [cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[0] for thresh in im_thresh_0]

im_drawn = [cv2.drawContours(image.copy(), contours, -1, (0,255,0), 1) for contours in im_cnt]

plt.imshow(im_drawn[0])
plt.show()

Входное изображение: enter image description here

Ответы [ 2 ]

2 голосов
/ 20 апреля 2019

Поскольку мы хотим обнаруживать только флажки, идея состоит в том, чтобы использовать два метода фильтрации, чтобы изолировать нужные поля от слов.После предварительной обработки и нахождения контуров мы можем выполнить итерацию по каждому контуру и применить фильтры.Мы используем cv2.contourArea() с минимальным и максимальным пороговыми уровнями, а затем вычисляем соотношение сторон, используя cv2.approxPolyDP(), так как квадрат будет иметь соотношение сторон, близкое к 1.

Чтобы обнаружить края на изображении, мы можем использовать cv2.Canny() и затем захватите контуры, используя cv2.findContours(), что приводит к этому изображению.Обратите внимание на то, как были обнаружены все контуры, включая слова и флажки.

enter image description here

Далее мы перебираем каждый обнаруженный контур и фильтруем, используя пороговую область и соотношение сторон.Используя этот метод, все 52 флажка были обнаружены.

enter image description here

Выход

('checkbox_contours', 52)

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

Другой набор входных изображений

image image

Выход

('checkbox_contours', 2)

Код

import numpy as np
import imutils, cv2

original_image = cv2.imread("1.jpg")
image = original_image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(blurred, 120, 255, 1)

cv2.imshow("edged", edged)

cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)

checkbox_contours = []

threshold_max_area = 250
threshold_min_area = 200
contour_image = edged.copy()

for c in cnts:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.035 * peri, True)
    (x, y, w, h) = cv2.boundingRect(approx)
    aspect_ratio = w / float(h)
    area = cv2.contourArea(c) 
    if area < threshold_max_area and area > threshold_min_area and (aspect_ratio >= 0.9 and aspect_ratio <= 1.1):
        cv2.drawContours(original_image,[c], 0, (0,255,0), 3)
        checkbox_contours.append(c)

print('checkbox_contours', len(checkbox_contours))
cv2.imshow("checkboxes", original_image)
cv2.waitKey(0)
1 голос
/ 19 апреля 2019

Хорошо ... Флажки всегда находятся в этой области изображения? Флажки Всегда поддерживать одинаковую область размера на изображении?

Если да, вы можете запустить findContours только в этой области изображения ...

Или, может быть, шаблон, соответствующий нескольким объектам, например, из документов OpenCV: https://docs.opencv.org/3.4.3/d4/dc6/tutorial_py_template_matching.html

...