【发布时间】:2018-07-21 11:31:18
【问题描述】:
上下文:我正在执行对象本地化并希望实现返回抑制机制(即在 红色 边界框位于trigger 行动。)
问题:我不知道如何根据原始输入 (init_input) 准确缩放边界框 (red)。如果理解了这种缩放,那么黑色十字应该准确地放置在红色边界框的中间。
我目前这个函数的代码如下:
def IoR(b, init_input, prev_coord):
"""
Inhibition-of-Return mechanism.
Marks the region of the image covered by
the bounding box with a black cross.
:param b:
The current bounding box represented as [x1, y1, x2, y2].
:param init_input:
The initial input volume of the current episode.
:param prev_coord:
The previous state's bounding box coordinates (x1, y1, x2, y2)
"""
x1, y1, x2, y2 = prev_coord
width = 12
x_mid = (b[2] + b[0]) // 2
y_mid = (b[3] + b[1]) // 2
# Define vertical rectangle coordinates
ver_x1 = int(((x_mid) * IMG_SIZE / (x2 - x1)) - width)
ver_x2 = int(((x_mid) * IMG_SIZE / (x2 - x1)) + width)
ver_y1 = int((b[1]) * IMG_SIZE / (y2 - y1))
ver_y2 = int((b[3]) * IMG_SIZE / (y2 - y1))
# Define horizontal rectangle coordinates
hor_x1 = int((b[0]) * IMG_SIZE / (x2 - x1))
hor_x2 = int((b[2]) * IMG_SIZE / (x2 - x1))
hor_y1 = int(((y_mid) * IMG_SIZE / (y2 - y1)) - width)
hor_y2 = int(((y_mid) * IMG_SIZE / (y2 - y1)) + width)
# Draw vertical rectangle
cv2.rectangle(init_input, (ver_x1, ver_y1), (ver_x2, ver_y2), (0, 0, 0), -1)
# Draw horizontal rectangle
cv2.rectangle(init_input, (hor_x1, hor_y1), (hor_x2, hor_y2), (0, 0, 0), -1)
想要的效果如下图所示:
注意:我相信这个问题的复杂性是由于每次我采取行动(并因此进入下一个状态)时图像都会调整大小(到 224、224、3)。因此,确定缩放的“锚”必须从之前的状态缩放中提取出来,如下代码所示:
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.
IMG_SIZE = 224
:param init_input:
The initial input volume of the current episode.
:param b_prime:
The subsequent state's bounding box.
:param g: (init_g)
The initial ground truth box of the target object.
"""
# 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), interpolation=cv2.INTER_AREA)
# Resize ground truth box
g[0] = int((g[0] - x1) * IMG_SIZE / (x2 - x1)) # x1
g[1] = int((g[1] - y1) * IMG_SIZE / (y2 - y1)) # y1
g[2] = int((g[2] - x1) * IMG_SIZE / (x2 - x1)) # x2
g[3] = int((g[3] - y1) * IMG_SIZE / (y2 - y1)) # y2
return observable_region, g, (b_prime[0], b_prime[1], b_prime[2], b_prime[3])
解释:
有一个状态t,代理正在预测目标对象的位置。目标对象有一个ground truth box(图像中的黄色,草图中的点),代理当前的“定位框”是红色的边界框。比如说,在状态t,代理决定最好向右移动。因此,边界框向右移动,然后下一个状态 t' 是通过在红色边界框周围添加额外的 16 像素上下文来确定的,裁剪 原始 图像相对于这个边界,然后将裁剪后的图像放大回 224、224 的尺寸。
假设代理现在确信其预测是准确的,因此它选择了trigger 操作。这基本上意味着,结束当前目标对象的定位事件,并在智能体预测对象所在的位置(即红色边界框的中间)放置一个黑色十字。现在,由于当前状态是在上一个动作之后被裁剪后放大的,因此必须相对于正常/原始/初始图像重新缩放边界框,然后才能在图像上准确地绘制黑色十字。
就我的问题而言,状态之间的第一次重新调整运行良好(本文中的第二个代码)。然而,缩小到正常水平并绘制黑色十字是我似乎无法理解的。
这是一张希望有助于解释的图片:
这是我当前解决方案的输出(请点击图片放大):
【问题讨论】:
-
我认为你想要
x_mid = (b[2] + b[0]) // 2而不是减号。y_mid也是如此。 -
@MarkSetchell 谢谢!我已根据您的回复更新了帖子。
-
有很多东西你没有展示。什么是 IMG_SIZE ?如何调用 IoR 函数?
-
@Sunreef
IMG_SIZE = 224,图片的尺寸。 IoR 使用 red 区域的边界框[x1, y1, x2, y2]调用。init_input是原始 (224, 224, 3) 图像。即init_input = np.copy(init_region) -
问题是缩放问题。我相信我需要跟踪一个参考点,这是我接下来要弄清楚如何实现它的方法。
标签: python opencv image-processing