Opencv:如何在 python 中绘制旋转边界框
Opencv: how to draw a rotated bounding box in python
我目前正在使用opencv-python做一个关于绘画识别的项目。
现在我能够很好地检测到大部分画作,但是边界框是包含很多背景的矩形。
这是因为 cv2.boundingRect() 函数找到了具有垂直投影的边界矩形 (afaik)。但是我想在不检测任何背景的情况下找到最佳边界框。
我的代码主要部分:
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
等高线查找排序后,需要用到cv2.minAreaRect()
函数。这会绘制一个用最小面积包围每个轮廓的矩形:
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)
注: cv2.minAreaRect()
returns 旋转矩形的属性(中心,尺寸和旋转角度). cv2.boxPoints()
用于获取矩形的顶点。然后将其传递给 cv2.drawContours()
以绘制它们。
算法详情:
- Link 1
- Link 2
更新:
以下代码围绕轮廓近似四边形并将其绘制在 frame
上。变量 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)
我目前正在使用opencv-python做一个关于绘画识别的项目。 现在我能够很好地检测到大部分画作,但是边界框是包含很多背景的矩形。 这是因为 cv2.boundingRect() 函数找到了具有垂直投影的边界矩形 (afaik)。但是我想在不检测任何背景的情况下找到最佳边界框。
我的代码主要部分:
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
等高线查找排序后,需要用到cv2.minAreaRect()
函数。这会绘制一个用最小面积包围每个轮廓的矩形:
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)
注: cv2.minAreaRect()
returns 旋转矩形的属性(中心,尺寸和旋转角度). cv2.boxPoints()
用于获取矩形的顶点。然后将其传递给 cv2.drawContours()
以绘制它们。
算法详情:
- Link 1
- Link 2
更新:
以下代码围绕轮廓近似四边形并将其绘制在 frame
上。变量 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)