关于使用 tf.image.crop_and_resize

R.i*_*go 4 machine-learning tensorflow

我正在研究适用于 fast-rcnn 的 ROI 池化层,我习惯于使用 tensorflow。我发现tf.image.crop_and_resize可以作为 ROI 池化层。

但是我尝试了很多次都没有得到我期望的结果。或者真正的结果是否正是我得到的?

这是我的代码

import cv2
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt 

img_path = r'F:\IMG_0016.JPG'
img = cv2.imread(img_path)
img = img.reshape([1,580,580,3])
img = img.astype(np.float32)
#img = np.concatenate([img,img],axis=0)

img_ = tf.Variable(img) # img shape is [580,580,3]
boxes = tf.Variable([[100,100,300,300],[0.5,0.1,0.9,0.5]])
box_ind = tf.Variable([0,0])
crop_size = tf.Variable([100,100])

#b = tf.image.crop_and_resize(img,[[0.5,0.1,0.9,0.5]],[0],[50,50])
c = tf.image.crop_and_resize(img_,boxes,box_ind,crop_size)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
a = c.eval(session=sess)

plt.imshow(a[0])
plt.imshow(a[1])
Run Code Online (Sandbox Code Playgroud)

我提交了我的原点img和结果:a0 , a1
如果我错了有人能教我如何使用这个功能吗?谢谢。

Les*_*rel 7

其实这里用Tensorflow是没有问题的。

文档tf.image.crop_and_resize(重点是我的):

盒子:一个 float32 类型的张量。形状为 [num_boxes, 4] 的二维张量。张量的第 i 行指定 box_ind[i] 图像中一个框的坐标,并以归一化坐标[y1, x1, y2, x2] 指定。将y的归一化坐标值映射到y * (image_height - 1)处的图像坐标,从而将归一化图像高度的[0, 1]区间映射到图像高度坐标中的[0, image_height - 1]。我们确实允许 y1 > y2,在这种情况下,采样裁剪是原始图像的上下翻转版本。宽度维度的处理方式类似。允许在 [0, 1] 范围之外的归一化坐标,在这种情况下,我们使用 extrapolation_value 来推断输入图像值。

box 参数需要标准化坐标。这就是为什么你会得到一个带有第一组坐标的黑匣子[100,100,300,300] (未标准化,也没有提供外推值),而不是第二组坐标[0.5,0.1,0.9,0.5]

但是,这就是为什么 matplotlib 在您第二次尝试时向您显示胡言乱语的原因,这只是因为您使用了错误的数据类型。引述matplotlib文件plt.imshow(重点是我的):

所有值都应在 [0 .. 1] 范围内(对于浮点数)或 [0 .. 255](对于整数)。超出范围的值将被剪裁到这些边界

当您在[0,1]范围之外使用浮点数时,matplotlib 将您的值限制为1. 这就是为什么你会得到那些彩色像素(纯红色、纯绿色或纯蓝色,或这些的混合)。将您的数组投射到uint_8以获得有意义的图像。

plt.imshow( a[1].astype(np.uint8))
Run Code Online (Sandbox Code Playgroud)

编辑: 根据要求,我将深入研究 tf.image.crop_and_resize.

[当提供非标准化坐标且没有外推值时],为什么我只得到一个空白结果?

引用文档:

允许在 [0, 1] 范围之外的归一化坐标,在这种情况下,我们使用 extrapolation_value 来推断输入图像值。

因此,允许在 [0,1] 之外的归一化坐标。但它们仍然需要归一化!在您的示例中,[100,100,300,300]您提供的坐标构成红色方块。您的原始图像是左上角的小绿点!参数的默认值extrapolation_value0,因此原始图像帧外的值被推断为[0,0,0]黑色。
裁剪和调整大小

但是如果你的用例需要另一个值,你可以提供它。像素将extrapolation_value%256在每个通道上采用 RGB 值。如果您需要裁剪的区域未完全包含在原始图像中,则此选项很有用。(例如,一个可能的用例是滑动窗口)。