我正在调整图像init_input
的大小以及该图像内目标对象g
的边界框的大小,以执行对象定位。我目前正在通过确定要上采样的像素数并将其一半添加到每个边界框坐标中来调整边界框的大小。
我的代码如下:
def next_state(init_input, b_prime, g):
"""
Returns the observable region of the next state.
Formats the next state's observable region, defined
by b_prime, to be of dimension (224, 224, 3). Adding 16
additional pixels of context around the original bounding box.
The ground truth box must be reformatted according to the
new observable region.
:param init_input:
The initial input volume of the current episode.
:param b_prime:
The subsequent state's bounding box. RED
:param g:
The ground truth box of the target object. YELLOW
"""
# Determine the pixel coordinates of the observable region for the following state
context_pixels = 16
x1 = max(b_prime[0] - context_pixels, 0)
y1 = max(b_prime[1] - context_pixels, 0)
x2 = min(b_prime[2] + context_pixels, IMG_SIZE)
y2 = min(b_prime[3] + context_pixels, IMG_SIZE)
# Determine observable region
observable_region = cv2.resize(init_input[y1:y2, x1:x2], (224, 224))
# Difference between crop region and image dimensions
x1_diff = x1
y1_diff = y1
x2_diff = IMG_SIZE - x2
y2_diff = IMG_SIZE - y2
# Resize ground truth box
g[0] = int(g[0] - 0.5 * x1_diff) # x1
g[1] = int(g[1] - 0.5 * y1_diff) # y1
g[2] = int(g[2] + 0.5 * x2_diff) # x2
g[3] = int(g[3] + 0.5 * y2_diff) # y2
return observable_region, g
我遇到的问题是此方法不准确。如下面的示例所示,边界框仍处于关闭状态。我的想法是,这是由于插值在调整图像大小的过程中起作用的(因此,所拍摄的像素之间存在偏斜,而不是0.5
)。任何有关如何解决此问题的建议将不胜感激。
答案 0 :(得分:1)
基本上,在两个维度上均等缩放是一个好主意,以防止圆形和方形挤压。因此,首先,您必须找到比例。为此,您需要找到边界框的最大尺寸并添加32(两侧均为16像素),因此:
longest = max( x_size, y_size) + 32
scale = 224.0 / longest
然后,通过计算边界框的中心并在各个方向上加longest
的一半来找到角点:
center_x = (x1 + x2) / 2
center_y = (y1 + y2) / 2
org_x1 = center_x - longest/2
org_x2 = center_x + longest/2
org_y1 = center_y - longest/2
org_y2 = center_y + longest/2
然后,将坐标为(org_x1,org_y1,org_x2,org_y2)的矩形重新缩放为(224,224)矩形,边界框的角将是16.0 * scale
与图像角的偏移量。
好,据我所知,您将init_input[y1:y2, x1:x2]
的大小调整为(224,224)
,并想知道地面真实区域将在哪里。好吧,原本的地面真矩形距离拐角处只有16个像素,所以您必须找到这些新的偏移量,然后完成。
x_offset = 16.0 * 224.0 / (x2-x1)
y_offset = 16.0 * 224.0 / (y2-y1)
然后地面真值矩形将在(x_offset,y_offset)的左上角和在((224-x_offset),(224-y_offset))的右下角
您可能会忽略我在除法器上方编写的其余代码,它是在假设您保留x / y比的情况下编写的,而您不是=)
这是第三次尝试弄清您的工作...如果将init_input[y1:y2, x1:x2]
缩放为(224,224)
,则可以计算出转换后任意随机点(x,y)的坐标为:
x_new = (x - x1) * 224.0 / (x2 - x1)
y_new = (y - y1) * 224.0 / (y2 - y1)
最好根据图像大小来最小/最大新值,这样您就不会落在图像边框之外:
x_new = max( 0, min( 224, x_new))
y_new = max( 0, min( 224, y_new))