I am working on a project using OpenCV in Python to process images and detect contours. I have a function get_contours which takes several parameters, including minArea to filter out small contours. However, it seems that the minArea parameter is not taking effect when I call the function.
Here is my get_contours function in my_utils.py:
import cv2
import numpy as np
def get_contours(img, cthr=[168, 228], minArea=100, filter=4, draw=True, debug=False):
finalCounters = []
img_Gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_Blur = cv2.GaussianBlur(img_Gray, (5, 5), 1)
if debug:
cthr[0] = cv2.getTrackbarPos('cthr1', "img_temp")
cthr[1] = cv2.getTrackbarPos('cthr2', "img_temp")
img_canny = cv2.Canny(img_Blur, cthr[0], cthr[1])
kernel = np.ones((5, 5))
img_dila = cv2.dilate(img_canny, kernel, iterations=3)
img_erode = cv2.erode(img_dila, kernel, iterations=2)
cv2.imshow("img_temp", img_erode)
contours, hierarchy = cv2.findContours(img_erode, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for i in contours:
area = cv2.contourArea(i)
if area > minArea:
epsilon = 0.02 * cv2.arcLength(i, True)
approx = cv2.approxPolyDP(i, epsilon, True)
bbox = cv2.boundingRect(approx)
if filter > 0:
if len(approx) == filter:
finalCounters.append((len(approx), area, approx, bbox, i))
else:
finalCounters.append((len(approx), area, approx, bbox, i))
finalCounters = sorted(finalCounters, key=lambda x: x[1], reverse=True)
if draw:
for con in finalCounters:
cv2.drawContours(img, [con[4]], -1, (0, 255, 0), 5)
cv2.imshow("frame", img)
return img, finalCounters
And here is the main script main.py where I call the function:
import cv2
import numpy as np
import my_utils
def nothing():
pass
if name == “main“:
webcam = False
path = 'img.png'
cap = cv2.VideoCapture(0)
cap.set(10, 160)
cap.set(3, 1920)
cap.set(4, 1080)
cv2.namedWindow("frame")
cv2.namedWindow("img_temp")
cv2.createTrackbar('cthr1', "img_temp", 0, 255, nothing)
cv2.createTrackbar('cthr2', "img_temp", 0, 255, nothing)
while True:
if webcam:
ret, frame = cap.read()
else:
frame = cv2.imread(path)
cv2.imshow("frame", frame)
cthr1 = cv2.getTrackbarPos('cthr1', "img_temp")
cthr2 = cv2.getTrackbarPos('cthr2', "img_temp")
img, contours = my_utils.get_contours(frame)
img, finalCounters = my_utils.get_contours(frame, cthr=[cthr1, cthr2], minArea=50000, debug=True)
if cv2.waitKey(1) == ord(' '):
break
cv2.destroyAllWindows()
cap.release()
In the main script, I call get_contours twice: the first call uses the default minArea value (100), and the second call uses minArea=50000 in debug mode. However, it seems that the minArea value of 50000 is not affecting the results as expected. The contours detected do not seem to respect the minArea threshold.
Why is the minArea parameter not taking effect when I call get_contours with minArea=50000?
How can I ensure that the minArea parameter correctly filters out small contours?
Any help would be greatly appreciated. Thank you!
李业彤 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.