将切割后的小图片还原为大图片

本文可以看作是我的这篇博客(切割过程)的续集。

一、数据说明:

  (1)原始大图片:6000*6000

   (2)小图片:512*512,且相邻小图片之间的重叠率为50%

   (3)根据切割的要求,原图共被分割为140个小图片,即10行14列。

二、还原思路

  (1)先将每一行的小图片还原为一条完整的图片,如下图:

     第一行分割得到的14个小图片:

   第一行还原得到的完整图片:

 

(2)按照上述方法,将10行小图片全部还原成完整的图片:

第一行:

第二行:

 第三行:

……

……

……

第十行:

 

 

(3)再将第一行到第十行的条状图片拼接为一个完整的大图片。

三、上代码

  代码中的注释写的很清晰明了,希望可以帮助到小伙伴们!

import os
import sys
import re
import math
from shutil import copyfile
from PIL import Image
result="F:/Practice/merge.png"#用于存放最终合并生成的图像
#将image.png切块得到的140个小块,按着每一行为一个文件夹划分,也就是把每一行的14个小图片单独放在一个文件夹里
origin_path = 'F:/Practice/test02/Images_01_res/'       
result_path= 'F:/Practice/merge_res/'
filelist = os.listdir(origin_path)

for i in range(len(filelist)):
    fileName = filelist[i] # '1.png'
    name=re.split('_',fileName)
    f_cls=int(name[4])
    fileClass = "image_row"+str(f_cls) 
    filePath = result_path + fileClass + '/' 
    src_fileName = origin_path + fileName
    tar_fileName = filePath + fileName
    if not os.path.exists(filePath):
        os.makedirs(filePath)
    copyfile(src_fileName,tar_fileName)

#定义水平连接函数
def join_horizontal(i,png1, png2, size):
    img1, img2 = Image.open(png1), Image.open(png2)
    size1, size2 = img1.size, img2.size  # 获取两张图片的大小
    loc1, loc2 = (0, 0), (size1[0]-size,0)
    a=size1[0]+size2[0]-size
    if a > 6000:
        a=6000
        loc1, loc2 = (0, 0), (5488,0)
    joint = Image.new('RGB', (a, size1[1]))
    joint.paste(img2, loc2)
    joint.paste(img1, loc1)
    
    joint.save('F:/Practice/rows/row{}.png'.format(i))
    
    
#定义竖直连接函数    
def join_vertical(png1, png2, size):
    
    
    img1, img2 = Image.open(png1), Image.open(png2)
    size1, size2 = img1.size, img2.size  # 获取两张图片的大小
    loc1, loc2 = (0, 0), (0,size1[1]-size)
    a=size1[1]+size2[1]-size
    if a > 6000:
        a=6000
        loc1, loc2 = (0, 0), (0,5488)  
        
    joint = Image.new('RGB', (size1[0],a))
    joint.paste(img2, loc2)
    joint.paste(img1, loc1)
    joint.save(result)


    
#定义开始执行水平连接的函数    
def start(i,items, size, first_path=None):
        
     # 当first为None时,默认将第一张图片设置为图片列表的第一张图片,第二张图片设置为图片列表的第二张
     # 当这两张图片合成后,将图片列表的已经合成的图片元素移除
     # 然后将合成的图片设置为第一张图片,将剩余的没有合成的图片列表继续操作
     # 当first_path不为None,将第一张图片设置为first_path,第二张图片设置为传进来的列表的第一个元素
     # 合成之后,将刚刚使用的列表的元素删除
     # 最后递归函数,直到列表为空
    try:
        if not first_path:
            path1, path2 = items[0], items[1]
            join_horizontal(i,path1, path2, size)
            items.remove(path1)
            items.remove(path2)           
            return start(i,items, size, first_path='F:/Practice/rows/row{}.png'.format(i))
        
        else:
            path2 = items[0]
            join_horizontal(i,first_path, path2, size)
            items.remove(path2)
            return start(i,items, size, first_path='F:/Practice/rows/row{}.png'.format(i))
        
    except:
         pass
        
#定义开始执行竖直连接的函数    
def ver_start(items, size, first_path=None):
  
    try:
        if not first_path:
            path1, path2 = items[0], items[1]
            join_vertical(path1, path2, size)
            items.remove(path1)
            items.remove(path2)
            return ver_start(items, size, first_path=result)
        else:
            path2 = items[0]
            join_vertical(first_path, path2, size)
            items.remove(path2)
            return ver_start(items, size, first_path=result)
    except:
         pass
        
#定义抓取path路径下所有文件的函数        
def getAllImg(path):
         
    result = []
    filelist = os.listdir(path)
    for file in filelist:
        if os.path.isfile(os.path.join(path, file)):
            if file.split('.')[1] in ('jpg', 'png'):
                result.append(os.path.join(path, file))
    return result

#在result文件夹下,创建一个image_rows文件夹,用于存放合并生成的每一行图片
rows_path= 'F:/Practice/rows'
if not os.path.exists(rows_path):
        os.makedirs(rows_path)

# #在result文件夹下,创建一个label_rows文件夹,用于存放合并生成的每一行图片
# rows_path= 'F:/Practice/test_01/result/label_rows'
# if not os.path.exists(rows_path):
#         os.makedirs(rows_path)
#将每一个row[i]文件夹下的小块水平合并成完整的一行图片,合并的结果存放在上一步创建的image_rows文件夹下
if __name__ == '__main__':

    for i in range(1,13):
        path='F:/Practice/row_dirs/image_row{}/'.format(i)    
        s = getAllImg(path)
#         print(s)
        s.sort(key=lambda x:int(x[51:-4]))
        start(i,s, 0)
#将rows文件夹下存放的合成得到的每一行图片,竖直合并成完整的图像
if __name__ == '__main__':
    path1="F:/Practice/rows/"
    s1=getAllImg(path1)
    s1.sort(key=lambda x:int(x[20:-4]))
#     print(s1)

    ver_start(s1, 0)
    print('最后图片尺寸--->', Image.open(result).size)

四、总结

相信各位小伙伴在了解了合并的思路之后,能够很轻松的看懂代码。我的做法并不是按照小图片的文件名所对应的位置来进行的,我的思路比较简单粗暴。如果小伙伴们有什么问题,欢迎私信交流!

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小郭学地信

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值