OpenCV RotatedRect не имеет атрибута «размер» в Python3. Как обойти это?

Я обнаружил, что операторы .size.height и .size.width класса OpenCV RotatedRect не работают на Python, тогда как они работают на C++. Позвольте мне уточнить с помощью упрощенного фрагмента кода:

cap = cv2.VideoCapture('video1.mp4')
filter = RandomClass(20)

while(cap.isOpened()):
    ret, frame = cap.read()              # Read a frame
    res = filter.classMain(frame)        # Process the frame
    if (res == 0):
        print('Success')                 # If processing completed, print Success
cap.release()

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

import cv2
import numpy as np

class RandomClass:
    def __inti__(self):
        self.set_skip_first(True)
    def get_skip_first(self):
        return self.skip_first
    def set_skip_first(self, value):
        self.skip_first = value
    def classMain(self, frame):
        if not get_skip_first():
            self.expand_minRect(100)        # expand the minRect by 100 pixels
            # use the expanded rectangle for some other processing here
        else:
            self.set_skip_first(False)
        # create a mask with cv2.inRange
        contour = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE, offset=(0,0))[1]
        # iterate over each contour and find the index of the largest contour
        self.minRect = cv2.minAreaRect(np.array(self.contours[self.largest_contour_index]))
        # execute some other processing here
        return 0
    def expand_minRect(self, value):
        self.minRect.size.height = self.minRect.size.height + value
        self.minRect.size.width = self.minRect.size.width + value

Ошибка, которую я получаю, выглядит следующим образом. Точные строки прекрасно работают в C++ версии приведенного выше кода.

Файл "имя файла", строка 106, в expand_minRect

self.minRect.size.height = self.minRect.size.height + значение

AttributeError: объект «кортеж» не имеет атрибута «размер»

Я попробовал следующее. Я ожидал, что второе напечатанное значение (переменной width2) будет больше первого напечатанного значения (переменной width1) на value.

def expand_minRect(self, value):
    _,(width1, height1),_ = self.minRect
    print(width)
    self.minRect[1][0] = self.minRect[1][0] + value
    _,(width2,height2),_ = self.minRect
    print(w)

Однако это не сработало, так как тип переменной self.minRect[1][0] — это кортеж, а кортежи не могут быть изменены.

Файл "имя файла", строка 111, в expand_minRect

self.minRect1[0] = self.minRect< a href="https://docs.opencv.org/3.4.2/db/dd6/classcv.size.height1RotatedRect.html" rel="nofollow noreferrer">1[0] + значение

TypeError: объект 'tuple' не поддерживает назначение элементов

Я провел некоторое исследование, я не смог найти документацию Python для RotatedRect, но я нашел ответ stackoverflow, в котором говорится, что

В Python по-прежнему отсутствует класс RotatedRect

Итак, все в сторону, если предположить, что поддержка RotatedRect в Python3 неполная, как я могу обойти это и увеличить ширину и высоту моей переменной minRect?


person csg    schedule 03.03.2020    source источник
comment
Помогает ли это?   -  person beaker    schedule 03.03.2020
comment
@breaker К сожалению, нет. Я видел этот сайт раньше. Код извлекает углы RotatedRect, а затем рисует линии, соединяющие эти углы. Мне, с другой стороны, нужно расширить эти углы на 100 пикселей. Я попытался найти уравнения двух линий, проходящих через диагональные углы, и найти 4 новых развернутых угла на этих двух линиях, но это не сработало так же хорошо, как код C++, где я могу просто использовать minRect.size.height += value. Можно ли найти исходный код класса RotatedRect, чтобы определить, как эта операция выполняется под капотом?   -  person csg    schedule 03.03.2020


Ответы (1)


Согласно этому руководству, minAreaRect возвращает прямоугольник с ((center_x,center_y),(width,height),angle). Таким образом, если вы измените свой expand_minRect, чтобы воссоздать его с правильными компонентами, он должен работать.

def expand_minRect(self, value):
    self.minRect = (self.minRect[0],                                          # keep the center
                    (self.minRect[1][0] + value, self.minRect[1][1] + value), # update the size
                    self.minRect[2])                                          # keep the angle

Примечание. Проблема возникает из-за того, что OpenCV python имеет менее объектно-ориентированную реализацию, чем OpenCV c++. Он не возвращает структуру, которая позволяет получить доступ к каждому атрибуту по имени (например, «.size»). Вам нужно знать порядок кортежа и предположения для каждого элемента.

person ilke444    schedule 03.03.2020
comment
Спасибо! (Тесеккурлер.). Это хорошая идея! Это решило мою проблему. Мое решение было слишком близко. - person csg; 03.03.2020