Подсчитайте количество прямоугольников на изображении - PullRequest
2 голосов
/ 06 марта 2020

Фон

У меня есть два изображения, и я хочу посчитать количество прямоугольников в обоих из них.

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

Issue

Я не совсем понимаю, почему код находит количество прямоугольников, которые он выполняет. Например, на первом изображении это 8, я бы ожидал 4.

Во втором - 16, что я считаю правильным (15 внутренних и 1 внешний).

Код

Мой код выглядит следующим образом:

import cv2
import numpy as np

pic = 'boxes1'
image = cv2.imread(f'../Computer Vision/{pic}.jpg', 1)

blur = cv2.pyrMeanShiftFiltering(image, 11, 21)
gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

contours = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

rect_list = []

for cont in contours:
    peri = cv2.arcLength(cont, True)
    approx = cv2.approxPolyDP(cont, 0.015 * peri, True)
    if len(approx) == 4:
        x,y,w,h = cv2.boundingRect(approx)
        rect = x,y,w,h
        rect_list.append(rect)
        cv2.rectangle(image,(x,y),(x+w,y+h),(36,255,12),2)

cv2.imshow('thresh', thresh)
cv2.imwrite(f'output_{pic}.png', thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
print(len(rect_list))

Токовые выходы

Код находит 8 прямоугольников на первом изображении и 16 на втором. Я думаю, что первое должно быть 4, а второе, вероятно, правильно (?) (15 внутренних и 1 внешнее).

Код сохраняет следующие выходные данные:

1 Ответ

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

Учитывая, что прямоугольник имеет ровно четыре угла, мы можем использовать этот факт и просто подсчитать количество углов в изображении. Количество прямоугольников на изображении должно быть числом углов, разделенным на четыре. Вот подход:

  1. Получение двоичного изображения. Загрузка изображения, оттенки серого, Размытие по Гауссу и Порог Оцу .

  2. Удалите небольшой шум. Мы найдем контуры , затем отфильтруем с помощью фильтрации области контура с помощью cv2.contourArea и удалим шум, заполняя контур с помощью cv2.drawContours.

  3. Поиск углов. Мы используем детектор углов Ши-Томази, уже реализованный как cv2.goodFeaturesToTrack для определения угла. Посмотрите на this для объяснения каждого параметра.


Углы выделены зеленым цветом

enter image description here

Rectangles: 4.0

enter image description here

Rectangles: 16.0

Код

import cv2

# Load image, grayscale, blur, Otsu's threshold
image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Remove small noise with contour area filtering
cnts = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    area = cv2.contourArea(c)
    if area < 150:
        cv2.drawContours(thresh, [c], -1, 0, -1)

# Find corners and draw onto image
corners = cv2.goodFeaturesToTrack(thresh,150,0.5,5)
for corner in corners:
    x,y = corner.ravel()
    cv2.circle(image,(x,y),3,(36,255,12),-1)

# The number of rectangles is corners / 4
print('Rectangles: {}'.format(len(corners)/4))

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