【问题标题】:Draw rectange with 3:2 aspect ratio on image在图像上绘制长宽比为 3:2 的矩形
【发布时间】:2019-02-16 12:17:37
【问题描述】:

我正在尝试绘制一个纵横比为 3:2 的矩形。 我正在使用 OpenCV 来检测图像中的对象。因此,从输出值中,我绘制了一个具有最小 X、最小 Y、最大 X、最大 Y 的矩形。现在我需要使该矩形从起点即最小 x 和最小 Y 的纵横比为 3:2。

它不应超出原始图像的最大 X 和最大 Y 以及 矩形不应小于周围的现有矩形 检测到的对象。

【问题讨论】:

  • 你需要 any 3:2 的新矩形 (r_new) 使得 (i) r_newr_old 的交集等于 r_old 和(ii) r_new 不应外推“原始”图像。对吗?
  • 是的...@Berriel

标签: python opencv image-processing


【解决方案1】:

这是解决此问题的一种方法:

# determine the y / x length of the rectangle
len_X = maxX - minX
len_Y = maxY - minY

# determine the largest side, this will be the 3 in the aspect ratio
if len_X > len_Y:
    # check if the shorter side is larger than a 3:2 ration
    if len_Y > len_X * (3/2):
        # if so, increase larger side to 3:2 ratio
        len_X = len_Y * 1.5
    else:
        # else, increase shorter side to 3:2 ratio
        len_Y = len_X * (3/2) 
else:
    # same as above
    if len_X > len_Y * (3/2):
        len_Y = len_X * 1.5
    else:
        len_X = len_Y * (3/2) 

# if the rectangle exceeds the image, constrain the rectangle
# other option (commented): move the starting position
if minX + len_X > img.shape[1]:
    len_X = img.shape[1]-minX
    #minX = img.shape[1]-len_X
if minY + len_Y > img.shape[0]:
    len_Y = img.shape[0]-minY
    #minY = img.shape[0]-len_Y

# draw the rectangle
cv2.rectangle(img, (minX, minY), (minX + len_X, minY + len_Y), (0,0,255),1)

【讨论】:

  • 嗨,J.D 我试过你的答案,它给出了 3/2.5 的比率而不是 3/2
  • 你能提供一个例子 minX, maxX, minY, maxY 吗?
【解决方案2】:

首先计算新的盒子大小,使其 w:h 为 3:2。如果它的一侧比图像的长,则修剪框。

确定盒子大小后,我们再计算盒子中心。默认情况下,盒子中心保持不变,但如果盒子越过图像的边界,它就会移动。

最后我们可以使用box size和box center来计算box角的坐标。

import cv2

def draw_rectangle(img, min_x, min_y, max_x, max_y):
    # resize box to 3:2(only enlarge it)
    # determine the box_w and box_h
    box_w, box_h = max_x-min_x, max_y-min_y
    if box_w/box_h < 3/2:
        box_w = int(box_h*(3/2))
    else:
        box_h = int(box_w*(2/3))

    # trim the box so it won't be bigger than image
    h, w = img.shape[:2]
    box_w = w if box_w > w else box_w
    box_h = h if box_h > h else box_h

    # determine the center of box

    # the default box center
    box_center_x = (min_x+max_x)//2
    box_center_y = (min_y+max_y)//2

    # shift the box if it cross the boundary
    if box_center_x + box_w//2 > w:
        box_center_x = w - box_w//2
    elif box_center_x - box_w//2 < 0:
        box_center_x = box_w//2
    if box_center_y + box_h//2 > h:
        box_center_y = h - box_h//2
    elif box_center_y - box_h//2 < 0:
        box_center_y = box_h//2

    # calculate the corner of the box
    min_x, max_x = box_center_x - box_w//2, box_center_x + box_w//2
    min_y, max_y = box_center_y - box_h//2, box_center_y + box_h//2
    cv2.rectangle(img, (min_x, min_y), (max_x, max_y), (255,0,0), thickness=10)
    return img

img = cv2.imread('image.jpg')
min_x, min_y, max_x, max_y = 0, 0, 400, 230
img = draw_rectangle(img, min_x, min_y, max_x, max_y)
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

【讨论】:

  • 我需要 3:2 的比例,但你需要 2:3,无论如何它可以通过交换它来工作。还有一件事 3/2 结果 1.5 是浮动的,所以我们应该使用 3.0/2.0 而不是 3/2。
  • 很抱歉,但我认为您的意思是 h:w=3:2。我使用的是 Python 3,所以代码对我有用。
  • 我不这么认为。我现在看不到。
  • @Codecracker 还有什么我可以帮助你的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-22
  • 2020-05-08
  • 2018-09-13
  • 1970-01-01
相关资源
最近更新 更多