I found out that the .size.height
and .size.width
operators of OpenCV's RotatedRect class don't work in Python whereas they work in C++. Let me elaborate with a simplified code snippet:
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()
where the class definition is as follows:
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
The error I'm receiving is as follows. The exact lines work perfectly fine in the C++ version of the above code.
File "filename", line 106, in expand_minRect
self.minRect.size.height = self.minRect.size.height + value
AttributeError: 'tuple' object has no attribute 'size'
I tried the following. I was expecting the second printed value (of variable width2
) to be greater than the first printed value (of variable width1
) by 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)
However it didn't work as the variable type of self.minRect[1][0]
is Tuple and Tuples cannot be modified.
File "filename", line 111, in expand_minRect
self.minRect1[0] = self.minRect1[0] + value
TypeError: 'tuple' object does not support item assignment
I did some research, I couldn't find a Python documentation for RotatedRect but I found a stackoverflow answer stating that
Python still lacks of RotatedRect class
So all things to a side, assuming that the RotatedRect support in Python3 is incomplete, how can I work around this and expand the width and height of my minRect
variable?
According to this tutorial, minAreaRect
returns a rectangle with ((center_x,center_y),(width,height),angle)
. Thus, if you modify your expand_minRect
to recreate it with the correct components, it should work.
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
Note: The problem emerges from the fact that OpenCV python has a less object-oriented implementation than OpenCV c++. It does not return a struct which enables accessing each attribute by name (like ".size
"). You need to know the tuple order and assumptions for each element.