对分辨率较高图片切割后并拼接成完整图片

对分辨率较高图片切割后并拼接成完整图片

网上代码一般都是对图片切割成等份,但是对不是固定大小的分辨率图片,一般都是丢弃剩余部分,但是我这边需求需要最后拼接成完整图片,所以参考https://blog.csdn.net/qq_40608730/article/details/109190493 这篇博客改写了一下,感谢这位大哥的代码.
话不多说直接上代码:

import cv2
import numpy as np
import os
import math
from ultralytics import YOLO
import shutil
def split_img(pic_path, pic_target):

    if not os.path.exists(pic_target):  # 判断是否存在文件夹如果不存在则创建为文件夹
        os.makedirs(pic_target)
    else:
        shutil.rmtree(pic_target)
        os.makedirs(pic_target)

    # 要分割后的尺寸
    cut_width = 512
    cut_length = 512
    # 读取要分割的图片,以及其尺寸等数据
    picture = cv2.imread(pic_path)
    (width, length, depth) = picture.shape
    # 预处理生成0矩阵
    pic = np.zeros((cut_width, cut_length, depth))
    # 计算可以划分的横纵的个数
    num_width = math.ceil(width / cut_width)
    num_length = math.ceil(length / cut_length)
    # for循环迭代生成
    for i in range(0, num_width):
        if (i + 1) * cut_width <= width:
            for j in range(0, num_length):
                if (j + 1) * cut_length <= length:
                    pic = picture[i * cut_width: (i + 1) * cut_width, j * cut_length: (j + 1) * cut_length, :]
                    result_path = pic_target + '{}_{}.jpg'.format(i + 1, j + 1)
                    cv2.imwrite(result_path, pic)
                else:
                    ic = picture[i * cut_width: (i + 1) * cut_width, j * cut_length:length, :]
                    result_path = pic_target + '{}_{}.jpg'.format(i + 1, j + 1)
                    cv2.imwrite(result_path, ic)
        else:
            for j in range(0, num_length):
                if (j + 1) * cut_length <= length:
                    pic1 = picture[i * cut_width:width, j * cut_length: (j + 1) * cut_length, :]
                    result_path = pic_target + '{}_{}.jpg'.format(i + 1, j + 1)
                    cv2.imwrite(result_path, pic1)
                else:
                    ic1 = picture[i * cut_width:width, j * cut_length:, :]
                    result_path = pic_target + '{}_{}.jpg'.format(i + 1, j + 1)
                    cv2.imwrite(result_path, ic1)
    print("done!!!")
    return width, length

def splic_img(width, length, pic_target, output_path, model, file):

    # 数组保存分割后图片的列数和行数,注意分割后图片的格式为x_x.jpg,x从1开始
    num_width_list = []
    num_lenght_list = []
    # 读取文件夹下所有图片的名称
    picture_names = os.listdir(pic_target)
    if len(picture_names) == 0:
        print("文件不存在!")
    else:
        # 分割名字获得行数和列数,通过数组保存分割后图片的列数和行数
        for picture_name in picture_names:
            num_width_list.append(int(picture_name.split("_")[0]))
            num_lenght_list.append(int((picture_name.split("_")[-1]).split(".")[0]))
        # 取其中的最大值
        num_width = max(num_width_list)
        num_length = max(num_lenght_list)
        # 预生成拼接后的图片
        splicing_pic = np.zeros((width, length, 3))
        # 循环复制
        width_tem = 0 # 存储正常图片大小的总宽度
        height_tem = 0 # 存储正常图片大小的总长度
        for i in range(1, num_width + 1):
            if i != num_width:
                for j in range(1, num_length + 1):
                    if j != num_length:
                        img_part = cv2.imread(pic_target + '{}_{}.jpg'.format(i, j))
                        results = model.predict(img_part, save_txt=True)
                        frame = results[0].plot()
                        (width1, length1, depth1) = img_part.shape
                        splicing_pic[width1 * (i - 1): width1 * i, length1 * (j - 1): length1 * j, :] = frame
                        height_tem = length1*j
                    elif j == num_length:
                        img_part = cv2.imread(pic_target + '{}_{}.jpg'.format(i, j))
                        results = model(img_part, save_txt=True)
                        frame = results[0].plot()
                        (width1, length1, depth1) = img_part.shape
                        splicing_pic[width1 * (i - 1): width1 * i, height_tem: height_tem+length1, :] = frame
                width_tem = width1 * i
            elif i == num_width:
                for j in range(1, num_length + 1):
                    if j != num_length:
                        img_part = cv2.imread(pic_target + '{}_{}.jpg'.format(i, j))
                        results = model(img_part, save_txt=True)
                        frame = results[0].plot()
                        (width1, length1, depth1) = img_part.shape
                        splicing_pic[width_tem:width_tem+width1, length1 * (j - 1): length1 * j, :] = frame
                        height_tem = length1*j
                    elif j == num_length:
                        img_part = cv2.imread(pic_target + '{}_{}.jpg'.format(i, j))
                        results = model(img_part, save_txt=True)
                        frame = results[0].plot()
                        (width1, length1, depth1) = img_part.shape
                        splicing_pic[width_tem: width_tem+width1, height_tem: height_tem+length1, :] = frame
        # 保存图片
        if not os.path.exists(output_path):  # 判断是否存在文件夹如果不存在则创建为文件夹
            os.makedirs(output_path)
        op_path = os.path.join(output_path, file)
        cv2.imwrite(op_path, splicing_pic)
        print("----done!!!")


def main(pic_path, pic_target, output_path, file):
    model = YOLO('yolov8n-seg.pt')  # load an official model
    width, height = split_img(pic_path, pic_target)
    splic_img(width, height, pic_target, output_path, model, file)

if __name__ == "__main__":
    file_path = './pic'
    files = os.listdir(file_path)
    pic_target = './result/'  # 分割后的图片保存的文件夹
    output_path = './output'  # 保存最终的拼接图片路径
    for file in files:
        # output_path_tem = os.path.join(output_path, file)
        pic_path = os.path.join(file_path, file)  # 分割的图片的位置
        main(pic_path, pic_target, output_path, file)

以上代码最后会拼接成完整的图片,测试我用的是yolov8的segmentation模型对切割的图片进行segment,测试图片使用的是官方自带的bus.jpg.
有问题欢迎大家评论区指出.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值