调整存储在数组中的所有图像的大小

时间:2020-03-18 10:27:24

标签: python numpy opencv image-processing image-resizing

我将通过sentence = [] acrostic = [] while True: user_input = input('word: ') if not user_input: break sentence.append(user_input) acrostic.append(user_input[0].upper()) print(' '.join(sentence)) print('-- {}'.format(''.join(acrostic))) 读取的图像存储在数组cv2.imread中。数组的形状为masks

我现在正在尝试复制此数组,但是将每个图像的大小调整为值(10, 5248, 7936, 3) (10 images, image height, image width, 3 channels)monitor_h。这是我所拥有的:

monitor_w

但是我从resized_masks = np.empty([masks.shape[0], monitor_h, monitor_w, masks.shape[3]]) for i in range(masks.shape[0]): resized_masks[i] = cv2.resize(np.copy(masks[i]), (monitor_w, monitor_h)) 获得的图像是黑白的。频道一定发生了什么。有线索吗?

2 个答案:

答案 0 :(得分:2)

要查看为什么图像会变成黑白图像,让我们逐步检查代码。

resized_masks = np.empty([masks.shape[0], monitor_h, monitor_w, masks.shape[3]])

此行默认情况下会创建类型为np.float的数组。

resized_masks[i] = cv2.resize(np.copy(masks[i]), (monitor_w, monitor_h))

此行将cv2.resize的结果分配给resized_masks的一部分。

您的原始图像以及因此cv2.resize的结果可能是np.uint8类型的。赋值将值转换为float并将其放入缓冲区。强制转换本身很好:5转换为5.0255转换为255.0。问题在于float的值被解释为被裁剪为[0.0, 1.0]的范围,而不是[0.0, 255.0]的范围。因此,即使图像中包含看起来正确的值,您最终还是得到的图像实际上都是零和一。

您可以通过显示来验证值正确

resized_masks.astype(masks.dtype)

这不是真正的解决方法。真正的解决方法是从正确的输出类型开始:

resized_masks = np.empty((masks.shape[0], monitor_h, monitor_w, masks.shape[3]), dtype=masks.dtype)

请注意,通常使用元组来表示形状而不是列表,但这在功能上无关紧要。

现在,让我们看看您的patch为何起作用。

resized_masks = list(resized_masks)

这将创建一个对每个子数组的引用的Python列表。由于您实际上是在切片,它们仍将指向内部的连续缓冲区,但是重要的是每个resized_masks[i]是一个单独的引用,而不是在同一数组对象中的切片。

resized_masks[i] = list(cv2.resize(np.copy(masks[i]), (monitor_w, monitor_h)))

由于resized_masks是一个包含引用的列表,因此现在将cv2.resize的结果分配给第i个列表元素,而不是将内容分配到适当大小的切片中。您不需要这里的list包装器,因为它引入了不必要的尺寸。

resized_masks = np.asarray(resized_masks)

这只是将列表重新组合成一个数组,因为所有元素的大小都是正确的(尽管您会看到一个额外的单位尺寸,如上所述)。如您所料,此解决方案效率极低。除了您要往返于列表并分配多个不必要的缓冲区之外,您还将丢弃原始的np.empty数组而不使用它。

您的补丁程序大致等同于

resized_masks = np.array([cv2.resize(np.copy(mask), (monitor_w, monitor_h)) for mask in masks])

我不建议那样做。

答案 1 :(得分:0)

所以我找到了解决问题的方法,但是我仍然想知道是什么使图像变成黑白的。

这是我想出的:

<DataTemplate x:Key="AxisCBTextTemplate">
    <TextBlock Text="{Binding AxisTitle}"/>
</DataTemplate>