The code below finds a contour based on its maximum area but when there is no contour to be found I want to append 0
to a list in order to work around the ValueError: max() arg is an empty sequence
error but it fails. Why is that?
contours = cv2.findContours(binaryimage, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if len(contours) == 2:
contours = contours[0]
else:
contours = contours[1]
maxcontour = max(contours, key=cv2.contourArea) #filter maximum contour based on contour area
if len(maxcontour) == 0:
areavalue.append(0)
maxarea = cv2.contourArea(maxcontour)
areavalue.append(maxarea)
Edit: Upon addition of the default = 0
I get an error for maxarea
maxcontour = max(contours, key=cv2.contourArea, default = 0) #filter maximum contour based on contour area
maxarea = cv2.contourArea(maxcontour)
areavalue.append(maxarea)
As of Python3.8 (it may be earlier), you can write
max(contours, key=cv2.contourArea, default=0)
where default
says what to return when the list is empty.
It seems to give me an error when I do this. The cause of the error comes from the fact I use
maxcontour = max(contours, key=cv2.contourArea, default =0)
formaxarea = cv2.contourArea(maxcontour)
. I have edited my code in the question to accommodate this.Oh. You need to make your "default=" be something reasonable for the situation. You either need to return some contour that has zero area, or you need
default=None
, and then test theNone
case before taking the area. The point is thatdefault=
gets rid of the error message frommax
in the empty case.Or of course, just test whether
contours
is empty (if contours:
) before even callingmax
. Whatever makes the most sense for your code.Oh I see. That makes so much sense. Thank you for your answer!
When setting
default = None
I get this errorValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()