Различие между прямоугольником и квадратом на изображении с использованием opencv2 python

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

import cv2

raw_image = cv2.imread('test1.png')
cv2.imshow('Original Image', raw_image)
cv2.waitKey(0)

bilateral_filtered_image = cv2.bilateralFilter(raw_image, 5, 175, 175)
cv2.imshow('Bilateral', bilateral_filtered_image)
cv2.waitKey(0)

edge_detected_image = cv2.Canny(bilateral_filtered_image, 75, 200)
cv2.imshow('Edge', edge_detected_image)
cv2.waitKey(0)

_, contours, hierarchy = cv2.findContours(edge_detected_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

contour_list = []
for contour in contours:
    approx = cv2.approxPolyDP(contour,0.01*cv2.arcLength(contour,True),True)
    area = cv2.contourArea(contour)
    if ((len(approx) >= 3)):
        contour_list.append(contour)

cv2.drawContours(raw_image, contour_list,  -1, (0,0,0), 2)
cv2.imshow('Objects Detected',raw_image)
cv2.waitKey(0)

Это образец изображения


person Nuance    schedule 13.11.2017    source источник
comment
Было бы лучше, если бы вы могли загрузить некоторые образцы входных изображений, предпочтительно двоичные. Кроме того, ваши фигуры повернуты?   -  person ZdaR    schedule 13.11.2017
comment
Да, фигуры можно поворачивать относительно друг друга, и на одном изображении может быть несколько фигур.   -  person Nuance    schedule 13.11.2017
comment
Подшить, возможно проверить равенство сторон. Это то, что отличает квадрат от прямоугольника.   -  person Yves Daoust    schedule 13.11.2017


Ответы (4)


Это квадрат, если его ширина и высота равны. В противном случае это прямоугольник.

for contour in contours:
    approx = cv2.approxPolyDP(contour,0.01*cv2.arcLength(contour,True),True)
    area = cv2.contourArea(contour)
    if ((len(approx) == 4)):
        (x, y, w, h) = cv2.boundingRect(approx)
        if  ((float(w)/h)==1):
            cv2.putText(raw_image, "square", (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, 0, 2)
        else:
            cv2.putText(raw_image, "rectangle", (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, 0, 2)

        contour_list.append(contour)

Это изменение обнаруживает только квадраты и прямоугольники. Внесите необходимые изменения в цикл for для обнаружения кругов. Вы можете работать с len(approx), чтобы сделать это различие.

введите здесь описание изображения

person I.Newton    schedule 13.11.2017
comment
Именно то, что я хотел сделать. Я искал функцию cv2.boundingRect(приблизительно). Я основал его на документах opencv. Кстати спасибо за быстрый ответ. - person Nuance; 13.11.2017

У меня есть альтернативный способ:

  1. Найдите все связанные компоненты.

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

  3. Сгруппируйте эти характерные точки, лежащие на одних и тех же компонентах связности.

  4. Используйте отношение (расстояние/угол) между точками этих функций на всех связанных компонентах, и, соответственно, вы можете классифицировать эти геометрические фигуры.

person flamelite    schedule 13.11.2017

Отличие прямоугольника от квадрата в том, что у квадрата 4 равные стороны, что делает его особым прямоугольником. Я научился этому в детском саду.

Существует бесчисленное множество способов определения квадрата.

Его окружность всегда равна sqrt (площади), поэтому его круглость всегда 0,0625

Расстояние между всеми углами равно a или * sqrt(2)

Центроид имеет одинаковое расстояние a / 2 до всех 4 сторон.

...

Вы называете это.

person Piglet    schedule 13.11.2017
comment
Да, я использую одну из упомянутых вами техник... Спасибо. - person Nuance; 13.11.2017

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

person Ojas.M    schedule 03.05.2020