imutils基础(5)基于OpenCV与imutils实现蒙太奇

今天我们将学习如何使用OpenCV和imutils包构建图像的蒙太奇。

1.使用 OpenCV 实现蒙太奇

今天的博客文章有四个主要部分。
在第一部分中,我们将学习如何从保存在磁盘上的图像数据集构建图像路径列表。
然后,我们将使用build_montages函数获取这个图像列表并创建实际的蒙太奇。
接下来,我们将在屏幕上显示蒙太奇。
最后,我将提供一个使用蒙太奇在 OpenCV 中显示图像的示例。

2.使用 OpenCV 创建蒙太奇

首先,打开一个新文件,将其命名为 montage_example.py ,然后插入以下代码:

# 导入包
from imutils import build_montages
from imutils import paths
import argparse
import random
import cv2

导入我们需要的 Python 包。请注意 build_montages 是如何从 imutils 包中导入的。
然后,我们可以解析我们的命令行参数:

# 构造参数parse并解析参数
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--images", required=True,
	help="path to input directory of images")
ap.add_argument("-s", "--sample", type=int, default=21,
	help="# of images to sample")
args = vars(ap.parse_args())

我们的脚本需要一个命令行必选参数,第二个可选参数,每个参数的详细信息如下:

  • –images :包含要构建蒙太奇的图像的目录的路径。
  • –samples :一个可选的命令行参数,指定要采样的图像数量(我们默认这个值是 21 个图像)。

接下来,我们可以使用 --images 路径随机选择一些输入图像:

# 抓取图像的路径,然后随机选择样本
imagePaths = list(paths.list_images(args["images"]))
random.shuffle(imagePaths)
imagePaths = imagePaths[:args["sample"]]

要获取 --images 目录中所有图像路径的列表,我们调用 list_images 函数。出于本练习的目的,我们随机打乱图像路径,然后抽取这些图像的样本以显示在我们的屏幕上。此采样返回的一组图像路径将用于构建我们的蒙太奇。

鉴于我们的 imagePaths ,我们准备构建蒙太奇:

# 初始化图像列表
images = []
# 遍历图像路径列表
for imagePath in imagePaths:
	# 加载图像并更新图像列表
	image = cv2.imread(imagePath)
	images.append(image)
# 构建图像的蒙太奇
montages = build_montages(images, (128, 196), (7, 3))

我们初始化了图像列表。 然后我们遍历 imagePaths,从磁盘加载每个图像,然后将图像附加到我们的图像列表中。 为了实际构建蒙太奇,我们调用 build_montages 函数——所有繁重的工作都在这里完成。

build_montages 函数需要三个参数:

  • image_list :此参数是通过 OpenCV 加载的图像列表。在我们的例子中,我们提供了图像列表。
  • image_shape :包含蒙太奇中每个图像的宽度和高度的元组。这里我们指出蒙太奇中的所有图像都将调整为 129 x 196。将蒙太奇中的每个图像调整为固定大小是一项要求,以便我们可以在结果 NumPy 数组中正确分配内存。注意:蒙太奇中的空白区域将填充黑色像素。
  • montage_shape :第二个元组,这个元组指定了蒙太奇中的列数和行数。在这里,我们表明我们的蒙太奇将有 7 列(7 张图像宽)和 3 行(3 张图像高)。

build_montages 函数以 NumPy 数组格式返回蒙太奇图像列表。 如果图像列表中的图像多于 montage_shape 可以容纳的图像,则会为额外的图像创建一个新的蒙太奇。重复此过程,直到所有图像都已添加到蒙太奇中。我们的最终代码块将蒙太奇显示到我们的屏幕上:

# 循环蒙太奇并显示每个蒙太奇
for montage in montages:
	cv2.imshow("Montage", montage)
	cv2.waitKey(0)

我们遍历每个蒙太奇(同样,类似于在页面上显示 N 个(虚假)“搜索结果”)。

然后在我们的屏幕上显示当前的蒙太奇。 cv2.waitKey 调用会暂停脚本的执行,直到我们选择当前活动的窗口并按下键盘上的任意键。这将导致 for 循环前进。 一旦我们到达蒙太奇列表的末尾,脚本就会退出。

3.显示蒙太奇

在这里插入图片描述

4.build_montages源码

def build_montages(image_list, image_shape, montage_shape):
    """
    将单个图像列表转换为指定行和列的“蒙太奇”图像列表。
    一旦填充了蒙太奇图像的行和列,就会启动新的蒙太奇图像。
    不完整的蒙太奇图像的空白空间充满黑色像素
    ---------------------------------------------------------------------------------------------
    :参数 image_list: 输入图像的python列表
    :参数 image_shape: 元组,每个图像被调整后的大小(宽度,高度)
    :参数 montage_shape: 元组,图像蒙太奇的形状(宽度,高度)
    :return: numpy 数组格式的蒙太奇图像列表
    ---------------------------------------------------------------------------------------------
    示例用法:
    # 加载单个图像
    img = cv2.imread('lena.jpg')
    # 复制图像 25 次
    num_imgs = 25
    img_list = []
    for i in xrange(num_imgs):
        img_list.append(img)
    # 5x5蒙太奇
    montages = build_montages(img_list, (256, 256), (5, 5))
    # 遍历蒙太奇列表并显示
    for montage in montages:
        cv2.imshow('montage image', montage)
        cv2.waitKey(0)
    ----------------------------------------------------------------------------------------------
    """
    if len(image_shape) != 2:
        raise Exception('image shape must be list or tuple of length 2 (rows, cols)')
    if len(montage_shape) != 2:
        raise Exception('montage shape must be list or tuple of length 2 (rows, cols)')
    image_montages = []
    # 从黑色画布开始绘制图像
    montage_image = np.zeros(shape=(image_shape[1] * (montage_shape[1]), image_shape[0] * montage_shape[0], 3),
                          dtype=np.uint8)
    cursor_pos = [0, 0]
    start_new_img = False
    for img in image_list:
        if type(img).__module__ != np.__name__:
            raise Exception('input of type {} is not a valid numpy array'.format(type(img)))
        start_new_img = False
        img = cv2.resize(img, image_shape)
        # 将图像绘制到黑色画布上
        montage_image[cursor_pos[1]:cursor_pos[1] + image_shape[1], cursor_pos[0]:cursor_pos[0] + image_shape[0]] = img
        cursor_pos[0] += image_shape[0]  # 增加光标 x 位置
        if cursor_pos[0] >= montage_shape[0] * image_shape[0]:
            cursor_pos[1] += image_shape[1]  # 增加光标y位置
            cursor_pos[0] = 0
            if cursor_pos[1] >= montage_shape[1] * image_shape[1]:
                cursor_pos = [0, 0]
                image_montages.append(montage_image)
                # 重置黑色画布
                montage_image = np.zeros(shape=(image_shape[1] * (montage_shape[1]), image_shape[0] * montage_shape[0], 3),
                                      dtype=np.uint8)
                start_new_img = True
    if start_new_img is False:
        image_montages.append(montage_image)  # 添加未完成的蒙太奇
    return image_montages

在这里插入图片描述

参考目录

https://www.pyimagesearch.com/2017/05/29/montages-with-opencv/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值