如何用Python实现图像拼接画(把一堆小图拼成大图)

诸神缄默不语-个人CSDN博文目录

在这里的图像拼接画指的是一张大图由很多小图组成,效果就像这样:
在这里插入图片描述

原理:将大图拆成很多小块,每一块计算平均颜色,用平均颜色最相近的小图来替代,就可以。
直接遍历就可以,也就跑几个小时。如果想要加速的话可以考虑研究一下用多线程或者多进程来实现。

注意本博文中涉及的实验都是在Windows平台上实现的,如果要转成其他系统需要尤其注意文件路径格式。

文章目录

  • 1. 预处理小图:计算每张图的平均颜色,并放到一个新的文件夹中
  • 2. 用小图拼大图

1. 预处理小图:计算每张图的平均颜色,并放到一个新的文件夹中

jupyter notebook格式的代码文件:https://github.com/PolarisRisingWar/all-notes-in-one/blob/main/小图拼大图1-计算小图平均RGB颜色.ipynb

我是直接用CIFAR10的图片来作为小图了。

CIFAR10我是之前做PyTorch 60分钟速成的时候就下载过。这个教程我写过笔记:60分钟闪击速成PyTorch(Deep Learning with PyTorch: A 60 Minute Blitz)学习笔记
下载的核心代码是:

trainset = torchvision.datasets.CIFAR10(root='./data', train=True,  download=True, transform=transform)
testset = torchvision.datasets.CIFAR10(root='./data', train=False,  download=True, transform=transform)

代码:
调包→设置参数和工具函数→展示示例图片

import pickle

import numpy as np
import matplotlib.pyplot as plt

def unpickle(file):
    """cifar10数据官方提供的导入代码"""
    with open(file, 'rb') as fo:
        dict = pickle.load(fo, encoding='bytes')
    return dict

#设置参数
cifar10_path=r'data\cifar-10-batches-py'
cifar10_file_name=[r'\data_batch_'+str(i) for i in range(1,6)]
cifar10_file_name.append(r'\test_batch')

cifa10_avgcolor_folder=r"data\cifar10-avgcolor"

#展示一张示例图
p='data\cifar-10-batches-py\data_batch_1'
d=unpickle(p)
 
e=d[b'data']
for i in range(100):
    image=e[i]
    red_image=image[:1024].reshape(32,32)
    green_image=image[1024:2048].reshape(32,32)
    blue_image=image[2048:].reshape(32,32)
    result_img=np.ones((32, 32, 3), dtype=np.uint8)
    result_img[:,:,0]=red_image
    result_img[:,:,1]=green_image
    result_img[:,:,2]=blue_image
    plt.imshow(result_img)
    break

在这里插入图片描述

%%time
#遍历所有图片,计算其平均RGB颜色,将其分别存储至对应文件中
for file_name in cifar10_file_name:  #遍历所有batch
    cifar10_batch=cifar10_path+file_name  #该batch对应的路径
    cifar10_batch_unpickle=unpickle(cifar10_batch)
    file_r=open(cifa10_avgcolor_folder+"\\"+file_name+'_r',mode='w')
    file_g=open(cifa10_avgcolor_folder+"\\"+file_name+'_g',mode='w')
    file_b=open(cifa10_avgcolor_folder+"\\"+file_name+'_b',mode='w')
    for picture in cifar10_batch_unpickle[b'data']:
        file_r.write(str(np.mean(picture[:1024]))+'\n')
        file_g.write(str(np.mean(picture[1024:2048]))+'\n')
        file_b.write(str(np.mean(picture[2048:]))+'\n')
    file_r.close()
    file_g.close()
    file_b.close()

2. 用小图拼大图

jupyter notebook格式的代码文件:https://github.com/PolarisRisingWar/all-notes-in-one/blob/main/小图拼大图2.ipynb

大图原始图像是我从网上随便找的一张刘亦菲的写真:
在这里插入图片描述
代码:
调包→设置参数和功能函数→展示大图原图

#导包
import pickle

from PIL import Image

import numpy as np
import matplotlib.pyplot as plt

def unpickle(file):
    """cifar10数据官方提供的导入代码"""
    with open(file, 'rb') as fo:
        dict = pickle.load(fo, encoding='bytes')
    return dict

#参数配置
portrait_path=r'liuyifei.jpeg'

block=5  #5*5为一个色块

#小图
cifar10_path=r'data\cifar-10-batches-py'
cifar10_file_names=[r'\data_batch_'+str(i) for i in range(1,6)]
cifar10_file_names.append(r'\test_batch')

cifa10_avgcolor_folder=r"data\cifar10-avgcolor"

#展示原图
portrait_picture=Image.open(portrait_path)
plt.imshow(portrait_picture)

在这里插入图片描述

将图片加载到内存中→设置图像拼接的功能函数

#将图片转换为np.ndarray
portrait_matrix=portrait_picture.convert("RGB")
portrait_ndarray = np.array(portrait_matrix)

#将小图的RGB加载到内存中
little_rgbs={}
for file_name in cifar10_file_names:
    with open(cifa10_avgcolor_folder+"\\"+file_name+'_r') as f:
        little_rgbs[file_name+'_r']=f.readlines()
    with open(cifa10_avgcolor_folder+"\\"+file_name+'_g') as f:
        little_rgbs[file_name+'_g']=f.readlines()
    with open(cifa10_avgcolor_folder+"\\"+file_name+'_b') as f:
        little_rgbs[file_name+'_b']=f.readlines()

#将小图的batch加载到内存中
cifar10_batches=[]
for file_name in cifar10_file_names:  #遍历所有batch
    cifar10_batch=cifar10_path+file_name  #该batch对应的路径
    cifar10_batches.append(unpickle(cifar10_batch)[b'data'])

def convert_smalls_to_big(block_dim:int):
    """
    将一堆小图转换为大图,入参为大图色块的维度,返回新图
    """
    old_shape=portrait_ndarray.shape
    heng_dim=int(old_shape[0]/block_dim)
    zong_dim=int(old_shape[1]/block_dim)
    new_picture=np.ndarray(shape=(heng_dim*32,zong_dim*32,3),dtype=np.int16)
    for i in range(heng_dim):
        for j in range(zong_dim):
            old_matrix=portrait_ndarray[i*block_dim:(i+1)*block_dim,j*block_dim:(j+1)*block_dim,:]
            r=np.mean(old_matrix[:,:,0])
            g=np.mean(old_matrix[:,:,1])
            b=np.mean(old_matrix[:,:,2])
            
            least_distance=450  #理论最大值应该是np.sqrt(255*255+255*255+255*255)≈442
            least_distance_batch_index=0
            least_distance_picture_index=0
            
            for index in range(6):
                #遍历每一个batch
                for picture_index in range(len(cifar10_batches[index])):
                    #遍历每一张小图,找到平均RGB跟色块RGB最相近的小图,用这个小图来顶替大图的对应色块
                    little_r=float(little_rgbs[cifar10_file_names[index]+'_r'][picture_index])
                    little_g=float(little_rgbs[cifar10_file_names[index]+'_g'][picture_index])
                    little_b=float(little_rgbs[cifar10_file_names[index]+'_b'][picture_index])
                    distance=np.sqrt((little_r-r)**2+(little_g-g)**2+(little_b-b)**2)
                    if distance<least_distance:
                        least_distance=distance
                        least_distance_batch_index=index
                        least_distance_picture_index=picture_index
            little_picture=cifar10_batches[least_distance_batch_index][least_distance_picture_index]
            new_picture[i*32:(i+1)*32,j*32:(j+1)*32,0]=np.reshape(little_picture[:1024],(32,32)).copy()
            new_picture[i*32:(i+1)*32,j*32:(j+1)*32,1]=little_picture[1024:2048].reshape(32,32)
            new_picture[i*32:(i+1)*32,j*32:(j+1)*32,2]=little_picture[2048:].reshape(32,32)
    plt.imshow(new_picture)
    plt.savefig("picture1.png")

拼接图像:

%%time
convert_smalls_to_big(block)

Wall time: 1h 23min 27s
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/139356.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FFmpeg开发简介1

适逢FFmpeg6.1发布&#xff0c;准备深入学习下FFmpeg&#xff0c;将会写下系列学习记录。 在此列出主要学习资料&#xff0c;后续再不列&#xff0c;感谢这些大神的探路和分享&#xff0c;特别是雷神&#xff0c;致敬&#xff01; 《FFmpeg从入门到精通》 《深入理解FFmpeg》 …

使用Nginx和uwsgi在自己的服务器上部署python的flask项目

Nginx 是一个高性能的 HTTP 和反向代理服务。其特点是占有内存少&#xff0c;并发能力强&#xff0c;事实上nginx的并发能力在同类型的网页服务器中表现较好。 Nginx 专为性能优化而开发&#xff0c;性能是其最重要的考量指标&#xff0c;实现上非常注重效率&#xff0c;能经受…

Structure-Inferred Bi-level Model for Underwater Image Enhancement论文小结

背景 随着水下机器人的发展&#xff0c;水下图像增强引起了计算机视觉界越来越多的关注。然而&#xff0c;由于光线在水中传播时会被散射和吸收&#xff0c;水下捕捉到的图像往往存在偏色和能见度低的问题。现有的方法依赖于特定的先验知识和训练数据&#xff0c;在缺乏结构信…

无人地磅称重系统|自助过磅 料仓联动 自助卸料

上海思伟无人地磅系统 自助过磅、 自助卸料 、料仓联动 智能、省人、安全 无人监管过磅 对地磅及其相关的所有硬件进行配置和管理&#xff1b; 支持红外、道闸、车牌识别、AI分析、拍照存档、LED语音播报一体机等设备&#xff1b; 实现稳定可靠的无人监管称重功能&#xf…

安防监控系统EasyCVR v3.4.0版本首页界面更新调整功能大汇总

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台可拓展性强、…

C# 智慧医学实验室LIS系统源码,支持预制条码和即时打印条码;支持单工/双工数据采集;支持TAT监测与分析;具备检验智能审核功能,支持自定义多级审核规则

C#医院检验信息管理系统源码&#xff0c;智慧医学实验室LIS系统源码&#xff0c;云LIS系统源码 医院检验信息管理系统&#xff0c;利用计算机网络技术、数据存储技术、快速处理技术&#xff0c;对检验科进行全方位信息化管理&#xff0c;使检验科达到自动化运行&#xff0c;信息…

vscode使用flake8设置单行最长字符限制设置失败的问题

vscode使用flake8设置单行最长字符限制设置失败的问题 问题描述解决方案 问题描述 如图所示&#xff0c;使用flake8单行字数过长&#xff0c;就会有有红色底的波浪线 一般情况下很多教程都会让你在setting.json里面设置 但是我打开我的setting.json&#xff0c;发现我已经进…

体验家XMPlus收购NPSMeter,稳固体验管理行业“领头羊”地位

2023年9月30日&#xff0c;体验家XMPlus&#xff08;以下简称“体验家”&#xff09;成功完成了对NPSMeter的收购。此次收购是中国客户体验管理&#xff08;CEM&#xff09;赛道进入快速发展以来的首单收购&#xff0c;标志着体验家在CEM领域的进一步扩张&#xff0c;旨在继续完…

智慧工地管理云平台源码,Spring Cloud +Vue+UniApp

智慧工地源码 智慧工地云平台源码 智慧建筑源码支持私有化部署&#xff0c;提供SaaS硬件设备运维全套服务。 互联网建筑工地&#xff0c;是将互联网的理念和技术引入建筑工地&#xff0c;从施工现场源头抓起&#xff0c;最大程度的收集人员、安全、环境、材料等关键业务数据&am…

【教3妹学编程-算法题】给小朋友们分糖果 II

3妹&#xff1a;1 8得8&#xff0c;2 816&#xff0c; 3 8妇女节… 2哥 : 3妹&#xff0c;在干嘛呢 3妹&#xff1a;双11不是过了嘛&#xff0c; 我看看我这个双十一买了多少钱&#xff0c; 省了多少钱。 2哥 : 我可是一分钱没买。 3妹&#xff1a;我买了不少东西&#xff0c; …

天津火爆python培训机构从哪里入手?

Python不仅被应用在职场办公中&#xff0c;还被大型互联网公司应用于大型后端开发&#xff0c;随着大数据领域的高速发展&#xff0c;这门高效的编程语言逐渐成为处理数据的最佳编程语言之一。 Python培训班优势 系统性学习&#xff1a;Python培训班会提供结构化的课程体系&a…

期中之后老师的福音

老师在期中考试后总是会有一大堆事情要做&#xff0c;批改试卷、统计分数、通知学生成绩等等。今天我就要给大家介绍一个能够减轻老师工作负担、提高工作效率的方法——查询系统 简单来说&#xff0c;成绩查询系统就是能够让学生方便的查询成绩&#xff0c;让老师快捷发布成绩的…

腾讯云优惠券如何领取?腾讯云服务器怎么买便宜?

腾讯云深知用户对价格的重视&#xff0c;因此在每年的618、双11、双12等大型促销活动中推出了大量优惠活动。这些优惠活动包括打折、满减、买赠等形式&#xff0c;让用户在购买腾讯云主机服务器时能够享受到更多的实惠。特别是在这些促销活动期间&#xff0c;用户可以通过领取优…

OpenAI发布会,看看GPT又有哪些大动作!2023.11.7【浓缩精华】

ChatGPT GPT-4 Turbo其它applications 北京时间11月7日OpenAI首届开发者大会 GPT-4 Turbo Context length 支持12.8万个上下文contextMore control JSON模式 可复制输出 未来&#xff1a;在API中查看日志Better knowledge 平台启动检索 拥有截至2023年3月的知识New modaliti…

2023年11月最新视频号下载提取工具?

视频号下载提取器教程&#xff1a; 1. 首先&#xff0c;在微信客户端中搜索并添加"下载小助手儿"并关注获取推送的消息。然后添加视频下载助手为好友&#xff0c;可以帮助你解析视频号链接。 2. 打开微信&#xff0c;并找到你想要提取链接的视频号。进入该视频页面后…

终端训练模型日志重定向

在终端中要执行模型的训练时&#xff0c;我们有时候既需要把模型执行的日志输出到终端展示&#xff0c;又想把训练日志保存到日志文件中: 假设执行的代码时trian.py python -u train.py | tee -a ./train.log-u&#xff1a;这是 Python 解释器的一个选项&#xff0c;用于强制标…

List中的迭代器实现【C++】

List中的迭代器实现【C】 一. list的结构二. 迭代器的区别三. 迭代器的实现i. 类的设计ii. 重载iii. !重载iiii. begin()iiiii. end()iiiii. operator* 四.测试五. const迭代器的实现i. 实现5.2 优化实现 一. list的结构 其实按照习惯来说&#xff0c;应该要专门出一篇博客来写…

2.1 Windows驱动开发:内核链表与结构体

在Windows内核中&#xff0c;为了实现高效的数据结构操作&#xff0c;通常会使用链表和结构体相结合的方式进行数据存储和操作。内核提供了一个专门用于链表操作的数据结构LIST_ENTRY&#xff0c;可以用来描述一个链表中的每一个节点。 使用链表来存储结构体时&#xff0c;需要…

微信小程序:仅前端实现对象数组的模糊查询

效果 核心代码 //对数组进行过滤&#xff0c;返回数组中每一想满足name值包括变量query的 let result array.filter(item > { return item.name.includes(query); }); 完整代码 wxml <input type"text" placeholder"请输入名称" placeholder-styl…

【华为OD题库-015】报文重排序-Java

题目 对报文进行重传和重排序是常用的可靠性机制&#xff0c;重传缓冲区内有一定数量的子报文&#xff0c;每个子报文在原始报文中的顺序已知&#xff0c;现在需要恢复出原始报文。 输入描述 输入第一行为N,表示子报文的个数&#xff0c;0<N < 1000。 输入第二行为N个子报…