[英]Opencv: how to draw a rotated bounding box in python
I am currently doing a project on painting recognition using opencv-python.我目前正在做一个使用 opencv-python 进行绘画识别的项目。 Right now I am able to detect most of the paintings decently however the bounding boxes are rectangles that include a lot of background.
现在我能够很好地检测到大部分画作,但是边界框是包含很多背景的矩形。 This is because the cv2.boundingRect() function finds the bounding rectangle with a perpendicular projection (afaik).
这是因为 cv2.boundingRect() function 找到了具有垂直投影的边界矩形 (afaik)。 However I want to find the best bounding box without detecting any background.
但是我想在不检测任何背景的情况下找到最佳边界框。
The main part of my code:我的代码的主要部分:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
hue, saturation, value = cv2.split(hsv)
blurred_sat = cv2.GaussianBlur(saturation, (5, 5), 0)
edges = cv2.Canny(blurred_sat, 45, 100)
kernel = np.ones((3, 3), np.uint8)
dilate = cv2.dilate(edges, kernel, iterations=6)
erode = cv2.erode(dilate, kernel, iterations=2)
contours, hierarchy = cv2.findContours(erode, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key=cv2.contourArea, reverse=True)[:10]
# cv2.drawContours(frame, contours, -1, (255, 255, 0), 3)
for contour in contours:
area = cv2.contourArea(contour)
if area >= 3000:
x, y, w, h = cv2.boundingRect(contour)
subImg = frame[y:y+h, x:x+w]
cv2.rectangle(frame,
(x, y), (x + w, y + h),
(0, 255, 0),
2)
Current output image (video) Desired output image with desired bounding box in red当前 output 图像(视频)所需的 output 图像,所需边界框为红色
After finding and sorting the contours, you need to use cv2.minAreaRect()
function. This draws a rectangle enclosing each contour with the least area:找到轮廓并对其排序后,您需要使用
cv2.minAreaRect()
function。这会绘制一个矩形,用最小面积包围每个轮廓:
import numpy as np
# portion of code to find and sort contours
for contour in contours:
area = cv2.contourArea(contour)
if area >= 3000:
rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(frame, [box], 0, (0, 255, 0), 2)
Note: cv2.minAreaRect()
returns properties of the rotated rectangle (center, dimensions and angle of rotation).注意:
cv2.minAreaRect()
返回旋转矩形的属性(中心、尺寸和旋转角度)。 cv2.boxPoints()
is used to obtain the vertices of the rectangle. cv2.boxPoints()
用于获取矩形的顶点。 This is then passed into cv2.drawContours()
to draw them.然后将其传递到
cv2.drawContours()
以绘制它们。
Have a look at the documentation看看文档
For details on the algorithm:有关算法的详细信息:
Update:更新:
The following code approximates a quadrilateral around a contour and draws it on frame
.以下代码围绕轮廓近似四边形并将其绘制在
frame
上。 The variable value
determines how strong you want your approximations to be:变量
value
决定了您希望近似值的强度:
# use a value between 0 and 1
value = 0.02
for c in contours:
perimeter = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, value*perimeter, True)
if len(approx) == 4:
cv2.drawContours(frame, [approx], 0, (0, 0, 255), 5)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.