Python - OpenCV - return 最低底部矩形
Python - OpenCV - return lowest bottom rectangle
我有一个生成 HSV 掩码的脚本,并根据面积检测一些矩形:
我已经包括了一些区域限制,我的目标是只检测最低的底部框(上图中红色的那个)。
这是我的检测代码部分,我想在其中添加只能保留 1 个盒子的新功能:
cnts, hierarchy = cv2.findContours(mask_merged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in cnts:
p_box = round((cv2.contourArea(c)/image_area)*100,1)
print('p_box'+str(p_box))
if (p_box <= 2.2) and (p_box >= 0.7):
(x, y, w, h) = cv2.boundingRect(c)
print(x,y,w,h)
print(cv2.contourArea(c))
cv2.imshow('frame_ocr_zone',image_src[y:y+h, x:x+w])
cv2.rectangle(image_src, (x,y), (x+w,y+h), (0, 255, 0), 2)
## BEGIN - draw rotated rectangle
rect = cv2.minAreaRect(c)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(image_src,[box],0,(123, 245, 66),5)
font = cv2.FONT_HERSHEY_SIMPLEX
color = (157,252,3)
thickness = 2
fontScale = 1
org = (x-50,y-20)
我正在寻找此处报告的代码:
https://www.pyimagesearch.com/2015/04/20/sorting-contours-using-python-and-opencv/#pyi-pyimagesearch-plus-pricing-modal
我想修改这里的功能(排序):
def sort_contours(cnts, method="left-to-right"):
# initialize the reverse flag and sort index
reverse = False
i = 0
# handle if we need to sort in reverse
if method == "right-to-left" or method == "bottom-to-top":
reverse = True
# handle if we are sorting against the y-coordinate rather than
# the x-coordinate of the bounding box
if method == "top-to-bottom" or method == "bottom-to-top":
i = 1
# construct the list of bounding boxes and sort them from top to
# bottom
boundingBoxes = [cv2.boundingRect(c) for c in cnts]
(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),
key=lambda b:b[1][i], reverse=reverse))
# return the list of sorted contours and bounding boxes
return (cnts, boundingBoxes)
但我想不通只取回 1 个盒子(从上到下排序,并保持最大 c?)
提前感谢您的任何建议。
###更新
我确实在这里找到了 post:
Python opencv sorting contours
这段代码实际上能够做到这一点:
def get_contour_precedence(contour, cols):
tolerance_factor = 10
origin = cv2.boundingRect(contour)
return ((origin[1] // tolerance_factor) * tolerance_factor) * cols + origin[0]
im, contours, h = cv2.findContours(img.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours.sort(key=lambda x:get_contour_precedence(x, img.shape[1]))
首先我们将初始 X 和初始 Y 定义为 0,而且我们没有轮廓,因此 none 然后我们遍历轮廓检查 x 坐标和 y 坐标,因为底角有x 和 y 比其他的大
intial_x,intial_y = 0,0
my_cnt =None
for c in cnts:
(x, y, w, h) = cv2.boundingRect(c)
if x>intial_x and y>intial_y:
my_cnt = c
intial_x = x+w
intial_y =y+h
else:
continue
def get_contour_precedence(contour, cols):
tolerance_factor = 10
origin = cv2.boundingRect(contour)
return ((origin[1] // tolerance_factor) * tolerance_factor) * cols + origin[0]
im, contours, h = cv2.findContours(img.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours.sort(key=lambda x:get_contour_precedence(x, img.shape[1]))
我有一个生成 HSV 掩码的脚本,并根据面积检测一些矩形:
我已经包括了一些区域限制,我的目标是只检测最低的底部框(上图中红色的那个)。
这是我的检测代码部分,我想在其中添加只能保留 1 个盒子的新功能:
cnts, hierarchy = cv2.findContours(mask_merged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in cnts:
p_box = round((cv2.contourArea(c)/image_area)*100,1)
print('p_box'+str(p_box))
if (p_box <= 2.2) and (p_box >= 0.7):
(x, y, w, h) = cv2.boundingRect(c)
print(x,y,w,h)
print(cv2.contourArea(c))
cv2.imshow('frame_ocr_zone',image_src[y:y+h, x:x+w])
cv2.rectangle(image_src, (x,y), (x+w,y+h), (0, 255, 0), 2)
## BEGIN - draw rotated rectangle
rect = cv2.minAreaRect(c)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(image_src,[box],0,(123, 245, 66),5)
font = cv2.FONT_HERSHEY_SIMPLEX
color = (157,252,3)
thickness = 2
fontScale = 1
org = (x-50,y-20)
我正在寻找此处报告的代码: https://www.pyimagesearch.com/2015/04/20/sorting-contours-using-python-and-opencv/#pyi-pyimagesearch-plus-pricing-modal
我想修改这里的功能(排序):
def sort_contours(cnts, method="left-to-right"):
# initialize the reverse flag and sort index
reverse = False
i = 0
# handle if we need to sort in reverse
if method == "right-to-left" or method == "bottom-to-top":
reverse = True
# handle if we are sorting against the y-coordinate rather than
# the x-coordinate of the bounding box
if method == "top-to-bottom" or method == "bottom-to-top":
i = 1
# construct the list of bounding boxes and sort them from top to
# bottom
boundingBoxes = [cv2.boundingRect(c) for c in cnts]
(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),
key=lambda b:b[1][i], reverse=reverse))
# return the list of sorted contours and bounding boxes
return (cnts, boundingBoxes)
但我想不通只取回 1 个盒子(从上到下排序,并保持最大 c?)
提前感谢您的任何建议。
###更新 我确实在这里找到了 post: Python opencv sorting contours
这段代码实际上能够做到这一点:
def get_contour_precedence(contour, cols):
tolerance_factor = 10
origin = cv2.boundingRect(contour)
return ((origin[1] // tolerance_factor) * tolerance_factor) * cols + origin[0]
im, contours, h = cv2.findContours(img.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours.sort(key=lambda x:get_contour_precedence(x, img.shape[1]))
首先我们将初始 X 和初始 Y 定义为 0,而且我们没有轮廓,因此 none 然后我们遍历轮廓检查 x 坐标和 y 坐标,因为底角有x 和 y 比其他的大
intial_x,intial_y = 0,0
my_cnt =None
for c in cnts:
(x, y, w, h) = cv2.boundingRect(c)
if x>intial_x and y>intial_y:
my_cnt = c
intial_x = x+w
intial_y =y+h
else:
continue
def get_contour_precedence(contour, cols):
tolerance_factor = 10
origin = cv2.boundingRect(contour)
return ((origin[1] // tolerance_factor) * tolerance_factor) * cols + origin[0]
im, contours, h = cv2.findContours(img.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours.sort(key=lambda x:get_contour_precedence(x, img.shape[1]))