I doing some contour detection on a image and i want to find a contour based on a area that i will fix in this case i want the contour marked in red.
So i want a bounding box around the red contour
Following is the code for that:
import cv2
import numpy as npdef nothing(x):passcv2.namedWindow("Tracking")
cv2.createTrackbar("LH", "Tracking", 0, 255, nothing)
cv2.createTrackbar("LS", "Tracking", 0, 255, nothing)
cv2.createTrackbar("LV", "Tracking", 0, 255, nothing)
cv2.createTrackbar("UH", "Tracking", 255, 255, nothing)
cv2.createTrackbar("US", "Tracking", 255, 255, nothing)
cv2.createTrackbar("UV", "Tracking", 255, 255, nothing)while True:frame = cv2.imread('resultImages/imgCropped.png')img = frame.copy()hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)l_h = cv2.getTrackbarPos("LH", "Tracking")l_s = cv2.getTrackbarPos("LS", "Tracking")l_v = cv2.getTrackbarPos("LV", "Tracking")u_h = cv2.getTrackbarPos("UH", "Tracking")u_s = cv2.getTrackbarPos("US", "Tracking")u_v = cv2.getTrackbarPos("UV", "Tracking")l_b = np.array([65, 0, 28])u_b = np.array([120, 120, 130])mask = cv2.inRange(hsv, l_b, u_b)res = cv2.bitwise_and(frame, frame, mask=mask)res1 = res.copy()res = cv2.cvtColor(res,cv2.COLOR_BGR2GRAY)cont,_ = cv2.findContours(res,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)closed_contours = []open_contours = []for i in cont:if cv2.contourArea(i) > cv2.arcLength(i, True):closed_contours.append(i)else:open_contours.append(i)print(len(closed_contours))cont_img = cv2.drawContours(img, closed_contours, -1, 255, 3)c = max(closed_contours, key=cv2.contourArea)x, y, w, h = cv2.boundingRect(c)cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)cv2.imshow("frame", frame)cv2.imshow("mask", mask)cv2.imshow("res", res1)cv2.imshow("img",cont_img)key = cv2.waitKey(1)if key == 27:breakcv2.destroyAllWindows()
This detects the contour and displays a ton of useful information i have already set some tracker value so no tinkering with trackers to get it is needed
How Can I Do This ?
import cv2
import numpy as np
#EDIT: imutils to grab contours
import imutilsdef nothing(x):pass
'''
cv2.namedWindow("Tracking")
cv2.createTrackbar("LH", "Tracking", 0, 255, nothing)
cv2.createTrackbar("LS", "Tracking", 0, 255, nothing)
cv2.createTrackbar("LV", "Tracking", 0, 255, nothing)
cv2.createTrackbar("UH", "Tracking", 255, 255, nothing)
cv2.createTrackbar("US", "Tracking", 255, 255, nothing)
cv2.createTrackbar("UV", "Tracking", 255, 255, nothing)
'''frame = cv2.imread('so.jpg')
img = frame.copy()hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)l_h = cv2.getTrackbarPos("LH", "Tracking")
l_s = cv2.getTrackbarPos("LS", "Tracking")
l_v = cv2.getTrackbarPos("LV", "Tracking")u_h = cv2.getTrackbarPos("UH", "Tracking")
u_s = cv2.getTrackbarPos("US", "Tracking")
u_v = cv2.getTrackbarPos("UV", "Tracking")l_b = np.array([65, 0, 28])
u_b = np.array([120, 120, 130])mask = cv2.inRange(hsv, l_b, u_b)res = cv2.bitwise_and(frame, frame, mask=mask)
res1 = res.copy()res = cv2.cvtColor(res,cv2.COLOR_BGR2GRAY)cont = cv2.findContours(res,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
#EDIT: I CAN'T REALLY REMEMBER WHAT IT DOES, BUT IT IS WORKING..
cont = imutils.grab_contours(cont)closed_contours = []
open_contours = []for count,i in enumerate(cont):#EDIT:produce boxes out of contours found before computing countourArearect = cv2.minAreaRect(i)box = cv2.boxPoints(rect)i = np.int0(box)#HINT:IMPROVE THIS CONDITIONS. IT IS BASED ON FILTERING THE OTHER BOXES APPEARED..if (cv2.contourArea(i) < 2000 and cv2.contourArea(i)>100):#cv2.arcLength(i, True):print(cv2.contourArea(i))closed_contours.append(i)#EDIT:(0,0,255) made box appeared in red color
cont_img = cv2.drawContours(img, closed_contours, -1, (0,0,255), 3)
c = max(closed_contours, key=cv2.contourArea)
x, y, w, h = cv2.boundingRect(c)#EDIT: REMOVED CODE OUT OF WHILE- IT S NOT A VIDEO TO GRAB CONCURRENT FRAMES
while True:#cv2.imshow("frame", frame)#cv2.imshow("mask", mask)#cv2.imshow("res", res1)cv2.imshow("img",cont_img)key = cv2.waitKey(1)if key == 27:breakcv2.destroyAllWindows()
I modified a bit your code.. The result is the following :