练习 | 02 | 把多张图片合并成放到一张画布上

1 三行四列

1.1 第一种方案

# -*- coding: utf-8 -*-
import cv2
import os
import numpy as np

def cv_show(name, img, k=0, width=512, height=512):
    cv2.namedWindow(name, cv2.WINDOW_NORMAL)
    cv2.resizeWindow(name, width, height)
    cv2.imshow(name, img)
    cv2.waitKey(k)

def letter_box(image, dim, interval=0):
    h, w = dim
    h -= interval * 2
    w -= interval * 2
    height, width = image.shape[0], image.shape[1]
    ratio = min(w/width, h/height)
    nw = int(width * ratio)
    nh = int(height * ratio)
    dh = (h-nh)//2
    dw = (w-nw)//2
    resized_image = cv2.resize(image, (nw, nh))
    output = np.zeros((dim[0], dim[1], 3), dtype=np.uint8)
    output[dh+interval:dh+interval+nh, dw+interval:dw+interval+nw, :] = resized_image

    return output, ratio, dh, dw

if __name__ == '__main__':
    root_path = 'F:\workplace2\image'
    names = os.listdir(root_path)
    imgs = [cv2.imread(os.path.join(root_path, name)) for name in names]

    merge_size = (2048, 2048)   # 背景图尺寸
    rows = 4                    # 行数设定
    columns = 4                 # 列数设定
    interval = 20               # 图片间的最小间隔
    # 计算子图需要resize的尺寸
    assert merge_size[0] % columns == 0 and merge_size[1] % rows == 0, '%s or %s is not multiples of %s' % (rows, columns, merge_size)
    h = merge_size[0] // columns
    w = merge_size[1] // rows
    # 计算需要几张背景图
    if len(names) <= rows*columns:
        num = 1
    else:
        if len(names) % (rows*columns) == 0:
            num = len(names)//(rows*columns)
        else:
            num = len(names)//(rows*columns)+1
    canvas = np.zeros((num, merge_size[0], merge_size[1], 3), dtype=np.uint8)
    # 合并图片
    cnt = 0
    for n in range(len(names)):
        for k in range(num):
            for j in range(columns):
                for i in range(rows):
                    if cnt == len(names):
                        break
                    canvas[k][j*h:(j+1)*h, i*w:(i+1)*w, :], ratio, dh, dw = letter_box(imgs[cnt+n//(rows*columns)], (h, w), interval=interval)
                    # TODO: 读入json数据,通过ratio, dw, dh, interval计算合并后的新位置
                    # cv_show('black', canvas[k])
                    cnt += 1
            cv2.imwrite('merge_%s.jpg' % k, canvas[k])
    print('cnt: ', cnt)

执行结果:
在这里插入图片描述

2 八行八列

2.1 第一种方案

# -*- coding: utf-8 -*-
import cv2
import os
import numpy as np

def cv_show(name, img, k=0, width=512, height=512):
    cv2.namedWindow(name, cv2.WINDOW_NORMAL)
    cv2.resizeWindow(name, width, height)
    cv2.imshow(name, img)
    cv2.waitKey(k)

def letter_box(image, dim, interval=0):
    h, w = dim
    h -= interval * 2
    w -= interval * 2
    height, width = image.shape[0], image.shape[1]
    ratio = min(w/width, h/height)
    nw = int(width * ratio)
    nh = int(height * ratio)
    dh = (h-nh)//2
    dw = (w-nw)//2
    resized_image = cv2.resize(image, (nw, nh))
    output = np.zeros((dim[0], dim[1], 3), dtype=np.uint8)
    output[dh+interval:dh+interval+nh, dw+interval:dw+interval+nw, :] = resized_image

    return output, ratio, dh, dw

if __name__ == '__main__':
    root_path = 'F:\workplace2\image'
    names = os.listdir(root_path)
    imgs = [cv2.imread(os.path.join(root_path, name)) for name in names]

    merge_size = (8192, 8192)   # 背景图尺寸
    rows = 8                  # 行数设定
    columns = 8                # 列数设定
    interval = 20              # 图片间的最小间隔
    # 计算子图需要resize的尺寸
    assert merge_size[0] % columns == 0 and merge_size[1] % rows == 0, '%s or %s is not multiples of %s' % (rows, columns, merge_size)
    h = merge_size[0] // columns
    w = merge_size[1] // rows
    # 计算需要几张背景图
    if len(names) <= rows*columns:
        num = 1
    else:
        if len(names) % (rows*columns) == 0:
            num = len(names)//(rows*columns)
        else:
            num = len(names)//(rows*columns)+1
    canvas = np.zeros((num, merge_size[0], merge_size[1], 3), dtype=np.uint8)
    # 合并图片
    cnt = 0
    for n in range(len(names)):
        for k in range(num):
            for j in range(columns):
                for i in range(rows):
                    if cnt == len(names):
                        break
                    canvas[k][j*h:(j+1)*h, i*w:(i+1)*w, :], ratio, dh, dw = letter_box(imgs[cnt+n//(rows*columns)], (h, w), interval=interval)
                    # TODO: 读入json数据,通过ratio, dw, dh, interval计算合并后的新位置
                    # cv_show('black', canvas[k])
                    cnt += 1
            cv2.imwrite('merge_%s.jpg' % k, canvas[k])
    print('cnt: ', cnt)

在这里插入图片描述

3 十六行十六列

3.1 第一种方案

# -*- coding: utf-8 -*-
import cv2
import os
import numpy as np

def cv_show(name, img, k=0, width=512, height=512):
    cv2.namedWindow(name, cv2.WINDOW_NORMAL)
    cv2.resizeWindow(name, width, height)
    cv2.imshow(name, img)
    cv2.waitKey(k)

def letter_box(image, dim, interval=0):
    h, w = dim
    h -= interval * 2
    w -= interval * 2
    height, width = image.shape[0], image.shape[1]
    ratio = min(w/width, h/height)
    nw = int(width * ratio)
    nh = int(height * ratio)
    dh = (h-nh)//2
    dw = (w-nw)//2
    resized_image = cv2.resize(image, (nw, nh))
    output = np.zeros((dim[0], dim[1], 3), dtype=np.uint8)
    output[dh+interval:dh+interval+nh, dw+interval:dw+interval+nw, :] = resized_image

    return output, ratio, dh, dw

if __name__ == '__main__':
    root_path = 'F:\workplace2\image'
    names = os.listdir(root_path)
    imgs = [cv2.imread(os.path.join(root_path, name)) for name in names]

    merge_size = (8192, 8192)   # 背景图尺寸
    rows = 16                  # 行数设定
    columns =16                 # 列数设定
    interval = 10              # 图片间的最小间隔
    # 计算子图需要resize的尺寸
    assert merge_size[0] % columns == 0 and merge_size[1] % rows == 0, '%s or %s is not multiples of %s' % (rows, columns, merge_size)
    h = merge_size[0] // columns
    w = merge_size[1] // rows
    # 计算需要几张背景图
    if len(names) <= rows*columns:
        num = 1
    else:
        if len(names) % (rows*columns) == 0:
            num = len(names)//(rows*columns)
        else:
            num = len(names)//(rows*columns)+1
    canvas = np.zeros((num, merge_size[0], merge_size[1], 3), dtype=np.uint8)
    # 合并图片
    cnt = 0
    for n in range(len(names)):
        for k in range(num):
            for j in range(columns):
                for i in range(rows):
                    if cnt == len(names):
                        break
                    canvas[k][j*h:(j+1)*h, i*w:(i+1)*w, :], ratio, dh, dw = letter_box(imgs[cnt+n//(rows*columns)], (h, w), interval=interval)
                    # TODO: 读入json数据,通过ratio, dw, dh, interval计算合并后的新位置
                    # cv_show('black', canvas[k])
                    cnt += 1
            cv2.imwrite('merge_%s.jpg' % k, canvas[k])
    print('cnt: ', cnt)

调试结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值