在OpenCV中绘制倾斜的矩形

15

我正在使用OpenCV和Python开发一个涉及身体追踪的项目,并且使用HSV值来找到肤色,然后在其周围绘制一个框。

尽管我可以找到所跟踪的对象并在其周围绘制一个框,但矩形总是垂直的。我想知道是否有任何方式可以使矩形旋转以更好地显示检测到的对象,类似于minEnclosingCircle函数,但使用矩形。

图像可能更好地解释了我的需求。我得到的框是绿色的,而我想要的是用黄色画出来的。正如您所看到的,掩模显示出一个倾斜的矩形也将更好地包含所选区域。我还包括了原始图像。

我的代码如下:

import numpy as np
import cv2

# Input image
image = cv2.imread('TestIn.png')

# Converts to grey for better reulsts
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Converts to HSV
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# HSV values
lower_skin = np.array([5,36,53])
upper_skin = np.array([19,120,125])

mask = cv2.inRange(hsv, lower_skin, upper_skin)

mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)

# Finds contours
im2, cnts, hierarchy = cv2.findContours(mask.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# Draws contours
for c in cnts:
    if cv2.contourArea(c) < 3000:
        continue

    (x, y, w, h) = cv2.boundingRect(c)
    cv2.rectangle(image, (x,y), (x+w,y+h), (0, 255, 0), 2)

cv2.imshow('mask', mask)
cv2.imshow('image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

输入图片:

输入图片

输出图片(绿色框为输出框,黄色框为期望框):

输出图片。绿色框为输出框,黄色框为期望框


1
minAreaRect函数可以计算出你想要的内容。但是你必须手动绘制线条,因为RotatedRect对象没有绘图功能。 - Micka
请参考文档中的OpenCV官方教程中的第7节。 - Dan Mašek
1个回答

22
您需要使用 cv2.minAreaRect(...),然后使用cv2.boxPoints(...)以获得一系列点,表示可以由其他OpenCV绘图函数(如cv2.drawContours(...)cv2.polylines(...))使用的多边形格式。这是基于OpenCV文档中的示例,我添加了一些语句以实现所需的结果。
import numpy as np
import cv2

# Input image
image = cv2.imread('oaHUs.jpg')

# Converts to grey for better reulsts
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Converts to HSV
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# HSV values
lower_skin = np.array([5,36,53])
upper_skin = np.array([19,120,125])

mask = cv2.inRange(hsv, lower_skin, upper_skin)

mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)

# Finds contours
im2, cnts, hierarchy = cv2.findContours(mask.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# Draws contours
for c in cnts:
    if cv2.contourArea(c) < 3000:
        continue

    (x, y, w, h) = cv2.boundingRect(c)
    cv2.rectangle(image, (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,[box],0,(0,191,255),2)
    ## END - draw rotated rectangle

cv2.imwrite('out.png', image)

输出:


没问题。如果解决了您的问题,请放心接受答案。 - Dan Mašek
太棒了!谢谢 :) - Scott

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接