使用OpenCV 3和numpy创建缩略图拼接

时间:2017-11-03 11:40:18

标签: python image numpy opencv

我有一个相同大小的缩略图列表,我想将它们显示为具有给定宽度的马赛克。我们的想法是为形状为(thumb_height, thumb_width*width, 3)的每一行创建单个图像,然后通过获取单个图像将它们连接在一起。现在,如果宽度不是缩略图数量的除数,则最后一行将丢失一些图像。我们的想法是用黑色占位符填补空白。这是代码:

def show_images_mosaic(images, width):
    rows = []
    for i in range(0, len(images), width):
        rows.append(np.concatenate(images[i: i + width], axis=1))

    if len(rows) > 1:
        last_row = rows[-1]

        height = images[0].shape[0]
        last_row_width = last_row.shape[1]
        expected_width = rows[0].shape[1]

        if last_row_width < expected_width:
            filler = np.zeros((height, expected_width - last_row_width, 3))
            rows[-1] = np.concatenate((last_row, filler), axis=1)
        else:
            filler = None

    mosaic = np.concatenate(rows, axis=0)
    cv2.imshow('Mosaic', mosaic)

    for i, row in enumerate(rows):
        cv2.imshow('Row' + str(i), row)

    cv2.imshow('LastRowUnfilled', last_row)
    if filler is not None:
        cv2.imshow('Filler', filler)

    cv2.waitKey(0)

如果width是缩略图数量的除数,则此代码效果很好。但由于某些原因,当我必须填写最后一行时,它会中断。奇怪的是,它不会破坏最后一行,但它打破了整个图像,我真的无法理解为什么。此外,正确显示除最后一行之外的单行,但整个马赛克被打破,好像最后一行影响整个图像。

1 个答案:

答案 0 :(得分:2)

我认为你的问题可能与你的缩略图是8位图像有关。

默认情况下,np.zeros会创建一个类型为np.float64的数组。因此,当您将填充符与最后一行连接,然后将整个马赛克连接起来时,最终得到的数组最多包含255但值为dtype=np.float64的值。 OpenCV期望浮动图像在[0, 1]范围内。

要更正它,请按以下方式声明您的填充物:

filler = np.zeros((height, expected_width - last_row_width, 3), dtype=np.uint8)

N.B:如果将马赛克保存到磁盘,则不应该看到问题。如果这确实是问题,那么imshow只会被打破。