如何在OpenCV Python中获得更多/更少期望区域的轮廓
问题描述:
我在图像上进行了一些轮廓检测,我想根据要固定的区域找到轮廓,在这种情况下,我希望轮廓标记为红色.
所以我想要红色轮廓周围的边界框
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
以下是该代码:
import cv2
import numpy as np
def 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)
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:
break
cv2.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
我该怎么做?
答
import cv2
import numpy as np
#EDIT: imutils to grab contours
import imutils
def 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 countourArea
rect = 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:
break
cv2.destroyAllWindows()
我对您的代码做了一些修改.结果如下:
I modified a bit your code.. The result is the following :