I would like to filter out cnts with small area. But I got the an error. What is the proper way to use filter?
code
JavaScript
x
5
1
def drawCnts(img, cnts):
2
cnts = filter(lambda cnt: cv2.contourArea(cnt)> 400, cnts) # adding this line gets error
3
cv2.drawContours(img, cnts, -1, (0, 255, 0), 3)
4
imshow(img)
5
JavaScript
1
17
17
1
import imUtils
2
import configure as cfg
3
import cv2
4
5
folder = 'test_images/'
6
img = imUtils.imread(folder + '1.cr3')
7
gray = cv2.cvtColor(imUtils.toOpenCVU8(img.copy()), cv2.COLOR_BGR2GRAY)
8
thresh = cv2.adaptiveThreshold(gray,255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,27,9)
9
# apply close morphology
10
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
11
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
12
imUtils.imshow(thresh, 'thresh')
13
14
(cnts, _) = cv2.findContours(thresh.copy(),
15
cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
16
imUtils.drawCnts(img.copy(), cnts)
17
error
JavaScript
1
6
1
cv2.drawContours(img, cnts, -1, (0, 255, 0), 3)
2
cv2.error: OpenCV(4.6.0) :-1: error: (-5:Bad argument) in function 'drawContours'
3
> Overload resolution failed:
4
> - Can't parse 'contours'. Input argument doesn't provide sequence protocol
5
> - Can't parse 'contours'. Input argument doesn't provide sequence protocol
6
Advertisement
Answer
The filter function returns a generator but the drawContours function expects a list. To fix this, use the list command.
JavaScript
1
2
1
cnts = list(filter(lambda cnt: cv2.contourArea(cnt)> 400, cnts))
2
Another solution is to use a list comprehension to build the list, like this:
JavaScript
1
2
1
[cnt for cnt in cnts if cv2.contourArea(cnt) > 400]
2