【python】OpenCV—Merge Image

在这里插入图片描述

1、np.hstack / np.vstack

利用 numpy 的 hstack 和 vstack,对图片进行拼接

import cv2
import numpy as np

h, w = 256,256
img1 = cv2.resize(cv2.imread("1.jpg"), (w, h))
img2 = cv2.resize(cv2.imread("2.png"), (w, h))

horizontal = np.hstack((img1, img2))
cv2.imwrite("horizontal.jpg", horizontal)

vertical = np.vstack((img1, img2))
cv2.imwrite("vertical.jpg", vertical)

输入图片
在这里插入图片描述
在这里插入图片描述

horizontal

在这里插入图片描述

vertical

在这里插入图片描述

2、Slice

学习来自 Python 图像合并:利用 OpenCV 的强大功能

图片 reszie 成同样大小,生成空白图,利用切片,给相应区域赋值

import cv2
import numpy as np

dimension = 256
canvas_dimension = 2 * dimension

img1 = cv2.resize(cv2.imread("1.png"), (dimension, dimension))
img2 = cv2.resize(cv2.imread("2.png"), (dimension, dimension))
img3 = cv2.resize(cv2.imread("3.png"), (dimension, dimension))
img4 = cv2.resize(cv2.imread("4.png"), (dimension, dimension))

canvas = np.zeros((canvas_dimension, canvas_dimension, 3), dtype=np.uint8)

canvas[0:dimension, 0:dimension] = img1
canvas[0:dimension, dimension:canvas_dimension] = img2
canvas[dimension:canvas_dimension, 0:dimension] = img3
canvas[dimension:canvas_dimension, dimension:canvas_dimension] = img4

# cv2.imwrite("merge.jpg", canvas)
cv2.imshow("merge", canvas)
cv2.waitKey(0)
cv2.destroyAllWindows()

输入图片1
在这里插入图片描述

输入图片2
在这里插入图片描述

输入图片3
在这里插入图片描述

输入图片4
在这里插入图片描述

合并结果
在这里插入图片描述

3、cv2.addWeighted

import cv2
w, h = 960, 540
img1 = cv2.resize(cv2.imread("1.jpg"), (w, h))
img2 = cv2.resize(cv2.imread("2.jpg"), (w, h))
merge = cv2.addWeighted(img1, 0.7, img2, 0.3, gamma=.0)
cv2.imwrite("merge.jpg", merge)

输入1

在这里插入图片描述

输入2

在这里插入图片描述

输出

在这里插入图片描述

4、自定义渐变式叠加

Python国庆头像制作

渐变透明度叠加

原图

在这里插入图片描述

在这里插入图片描述

from PIL import Image

flag = Image.open('1.png').convert("RGBA")
avatar = Image.open('2.jpg').convert("RGBA")

flag = flag.resize(avatar.size)

for i in range(flag.size[0]):
    for j in range(flag.size[1]):
        r, g, b, _ = flag.getpixel((i, j))
        alpha = max(0, 255 - i // 5 - j // 7) # 核心代码,左上角到右下角越来越透明
        # 重新填充像素
        flag.putpixel((i, j), (r, g, b, alpha))

avatar.paste(flag, (0, 0), flag)
avatar.save('flag_avatar.png')

叠加后的效果

在这里插入图片描述

5、cv2.bitwise_not / cv2.bitwise_and / cv2.add

可以参考 【python】OpenCV—Paste Mask

A 图

请添加图片描述

A 图的 mask 标签

请添加图片描述
B 图

请添加图片描述
合并的结果
在这里插入图片描述

6、蒙太奇

参考学习来自:imutils基础(5)基于OpenCV与imutils实现蒙太奇

蒙太奇的含义有广狭之分:

  • 狭义的蒙太奇:专指对镜头画面、声音、色彩诸元素编排组合的手段,即在后期制作中,将摄录的素材根据文学剧本和导演的总体构思精心排列,构成一部完整的影视作品。其中最基本的意义是画面的组合

  • 广义的蒙太奇:不仅指镜头画面的组接,也指从影视剧作开始直到作品完成整个过程中艺术家的一种独特的艺术思维方式。

imutils 是一个用于图像处理的Python库,它提供了许多简化图像处理任务的工具,比如图像转换、缩放、旋转等。然而,需要注意的是,imutils 库本身主要关注于图像的处理和转换,而imutils.paths.list_images函数则是这个库中用于处理图像文件路径的一个实用工具。

image_paths = list(paths.list_images(image_folder, ext=[".jpg", ".png"]))
  • dirPath:要搜索的文件夹路径。
  • ext(可选):一个字符串或字符串列表,指定要搜索的图像文件扩展名。如果未指定,则默认搜索所有常见的图像文件扩展名(如.jpg, .jpeg, .png, .bmp, .tiff, .gif, .dib等)。
# 导入包
from imutils import build_montages
from imutils import paths
import argparse
import random
import cv2
import numpy as np

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


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


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

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


    # 循环蒙太奇并显示每个蒙太奇
    for index, montage in enumerate(montages):
        cv2.imwrite(f"Montage_{str(index)}.jpg", montage)
        cv2.imshow("Montage", montage)
        cv2.waitKey(0)

输入图像文件夹

在这里插入图片描述

结果

在这里插入图片描述

  • 25
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
OpenCV中,没有直接封装RGB与HSI之间的转换函数。但是我们可以通过以下方式将BGR转换为HSI: 首先,将BGR图像转换为浮点型数据,并将像素值除以255来将像素值范围从0-255映射到0-1之间。然后,我们可以根据以下公式计算HSI的值: H = arccos(0.5 * ((R - G) + (R - B)) / sqrt((R - G) * (R - G) + (R - B) * (G - B))) [1] S = 1 - 3 * min(R, G, B) / (R + G + B) I = (R + G + B) / 3 其中,R、G、B分别表示每个像素的红色、绿色和蓝色通道的值。 最后,将计算得到的H、S、I值分别乘以255来将像素值范围从0-1映射到0-255之间,并将其转换为整型数据。 以下是Python中使用OpenCV进行BGR到HSI转换的代码示例: ```python import cv2 import numpy as np def bgr_to_hsi(image): # 将BGR图像转换为浮点型数据 image = image.astype(np.float32) / 255.0 # 分离三个通道 b, g, r = cv2.split(image) # 计算H通道 theta = np.arccos(0.5 * ((r - g) + (r - b)) / np.sqrt((r - g) * (r - g) + (r - b) * (g - b))) h = np.copy(theta) h[np.where(b <= g)] = 2 * np.pi - h[np.where(b <= g)] # 计算S通道 s = 1 - 3 * np.minimum(np.minimum(r, g), b) / (r + g + b) # 计算I通道 i = (r + g + b) / 3 # 将H、S、I值映射到0-255并转换为整型数据 h = (h / (2 * np.pi)) * 255 s = s * 255 i = i * 255 # 合并H、S、I通道并转换为BGR图像 hsi_image = cv2.merge([h, s, i]).astype(np.uint8) return hsi_image # 读取BGR图像 bgr_image = cv2.imread('image.jpg') # 将BGR图像转换为HSI图像 hsi_image = bgr_to_hsi(bgr_image) # 显示HSI图像 cv2.imshow('HSI Image', hsi_image) cv2.waitKey(0) cv2.destroyAllWindows() ``` 请注意,上述代码中的`image.jpg`是示例图像的文件路径,你可以根据自己的需求进行替换。此外,代码中使用了NumPy库来进行数组操作,因此需要确保已经正确安装了NumPy库。 希望对你有所帮助!<span class="em">1</span><span class="em">2</span>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值