Python 实现将大图切片成小图,将小图组合成大图的例子


Posted in Python onMarch 14, 2020

训练keras时遇到了一个问题,就是内存不足,将 .fit 改成 .fit_generator以后还是放不下一张图(我的图片是8192×8192的大图==64M)。于是解决方法是将大图切成小图,把小图扔去训练,跑出来的图再拼成一个大图

实验发现我的keras(win10 - 16G内存)只放得下最多4副小图(2048×2048×4==16M),

再多就会报错exit :

Allocation of 4831838208 exceeds 10% of system memory.

原因大概是除了numpy本身要存这些图,keras训练中也会对应有额外的消耗

一、大图切片成小图

'''
读入一个图片0.bmp,切成指定数目个小图片(16个)
文件夹名out
'''
from PIL import Image
import sys,os
cut_num = 4 # 4*4=16个图片
#将图片填充为正方形
def fill_image(image):
  width, height = image.size  
  #选取长和宽中较大值作为新图片的
  new_image_length = width if width > height else height  
  #生成新图片[白底]
  #new_image = Image.new(image.mode, (new_image_length, new_image_length), color='white')  
  new_image = Image.new(image.mode, (new_image_length, new_image_length))
  #将之前的图粘贴在新图上,居中 
  if width > height:#原图宽大于高,则填充图片的竖直维度
  #(x,y)二元组表示粘贴上图相对下图的起始位置
    new_image.paste(image, (0, int((new_image_length - height) / 2)))
  else:
    new_image.paste(image, (int((new_image_length - width) / 2),0))  
  return new_image
#切图
def cut_image(image):
  width, height = image.size
  item_width = int(width / cut_num)
  box_list = []  
  # (left, upper, right, lower) 
  for i in range(0,cut_num):#两重循环,生成图片基于原图的位置 
    for j in range(0,cut_num):      
      #print((i*item_width,j*item_width,(i+1)*item_width,(j+1)*item_width))
      box = (j*item_width,i*item_width,(j+1)*item_width,(i+1)*item_width)
      box_list.append(box)

  image_list = [image.crop(box) for box in box_list]  
  return image_list
#保存
def save_images(image_list):
  index = 1 
  for image in image_list:
    image.save('out/'+str(index) + '.bmp', 'BMP')
    index += 1

if __name__ == '__main__':
  file_path = "0.bmp"
  os.mkdir("out")
  image = Image.open(file_path)  
  #image.show()
  image = fill_image(image)
  image_list = cut_image(image)
  save_images(image_list)

二、随机截取指定大小的图

'''
随即截取指定大小的图片
'''
import os
import cv2
import random
 
#读取图片
img1=cv2.imread('0.bmp')
img2=cv2.imread('1.bmp')
 
#h、w为想要截取的图片大小
h=2048
w=2048
 
save_dir1 = "pic_train/"
save_dir2 = "pic_noise/"
if os.path.exists(save_dir1) is False:
  os.makedirs(save_dir1)
if os.path.exists(save_dir2) is False:
  os.makedirs(save_dir2)
count=0
while 1:
  #随机产生x,y 此为像素内范围产生
  y = random.randint(0, 6144)
  x = random.randint(0, 6144)
  #随机截图
  cropImg1 = img1[(y):(y + h), (x):(x + w)]
  cropImg2 = img2[(y):(y + h), (x):(x + w)]
  cv2.imwrite(save_dir1 + str(count) + '.bmp', cropImg1)
  cv2.imwrite(save_dir2 + str(count) + '.bmp', cropImg2)
  count+=1
 
  if count==100:
    break

三、小图组合成大图

'''
将指定文件夹里面的图片拼接成一个大图片
'''
import PIL.Image as Image
import os
 
IMAGES_PATH = 'out\\' # 图片集地址
IMAGES_FORMAT = ['.bmp', '.BMP'] # 图片格式
IMAGE_SIZE = 2048 # 每张小图片的大小
IMAGE_ROW = 4 # 图片间隔,也就是合并成一张图后,一共有几行
IMAGE_COLUMN = 4 # 图片间隔,也就是合并成一张图后,一共有几列
IMAGE_SAVE_PATH = 'final.bmp' # 图片转换后的地址
 
# 获取图片集地址下的所有图片名称
image_names = [name for name in os.listdir(IMAGES_PATH) for item in IMAGES_FORMAT if
        os.path.splitext(name)[1] == item]
 
# 简单的对于参数的设定和实际图片集的大小进行数量判断
if len(image_names) != IMAGE_ROW * IMAGE_COLUMN:
  raise ValueError("合成图片的参数和要求的数量不能匹配!")
 
# 定义图像拼接函数
def image_compose():
  to_image = Image.new('RGB', (IMAGE_COLUMN * IMAGE_SIZE, IMAGE_ROW * IMAGE_SIZE)) #创建一个新图
  # 循环遍历,把每张图片按顺序粘贴到对应位置上
  for y in range(1, IMAGE_ROW + 1):
    for x in range(1, IMAGE_COLUMN + 1):
      from_image = Image.open(IMAGES_PATH + image_names[IMAGE_COLUMN * (y - 1) + x - 1]).resize(
        (IMAGE_SIZE, IMAGE_SIZE),Image.ANTIALIAS)
      to_image.paste(from_image, ((x - 1) * IMAGE_SIZE, (y - 1) * IMAGE_SIZE))
  to_image = to_image.convert('L')
  return to_image.save(IMAGE_SAVE_PATH) # 保存新图
image_compose() #调用函数

注意文件名的数字顺序,00 01 02 ...11 12 13 ....这样

以上这篇Python 实现将大图切片成小图,将小图组合成大图的例子就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中删除文件的程序代码
Mar 13 Python
详解Python的Django框架中的通用视图
May 04 Python
Python闭包实现计数器的方法
May 05 Python
Python中turtle作图示例
Nov 15 Python
Python实现的维尼吉亚密码算法示例
Apr 12 Python
python实现比较文件内容异同
Jun 22 Python
Pandas 同元素多列去重的实例
Jul 03 Python
Python图像滤波处理操作示例【基于ImageFilter类】
Jan 03 Python
python简单贪吃蛇开发
Jan 28 Python
python将数组n等分的实例
Dec 02 Python
如何使用pandas读取txt文件中指定的列(有无标题)
Mar 05 Python
Django扫码抽奖平台的配置过程详解
Jan 14 Python
python numpy实现多次循环读取文件 等间隔过滤数据示例
Mar 14 #Python
python matplotlib 绘图 和 dpi对应关系详解
Mar 14 #Python
python 工具 字符串转numpy浮点数组的实现
Mar 14 #Python
python tkinter GUI绘制,以及点击更新显示图片代码
Mar 14 #Python
使用Python爬取弹出窗口信息的实例
Mar 14 #Python
解决django中form表单设置action后无法回到原页面的问题
Mar 13 #Python
浅谈在django中使用redirect重定向数据传输的问题
Mar 13 #Python
You might like
ThinkPHP自动验证失败的解决方法
2011/06/09 PHP
php 搜索框提示(自动完成)实例代码
2012/02/05 PHP
基于preg_match_all采集后数据处理的一点心得笔记(编码转换和正则匹配)
2014/01/31 PHP
PHP使用pcntl_fork实现多进程下载图片的方法
2014/12/16 PHP
php workerman定时任务的实现代码
2018/12/23 PHP
详解PHP 7.4 中数组延展操作符语法知识点
2019/07/19 PHP
laravel model 两表联查示例
2019/10/24 PHP
thinkphp5 框架结合plupload实现图片批量上传功能示例
2020/04/04 PHP
js活用事件触发对象动作
2008/08/10 Javascript
JS解决ie6下png透明的方法实例
2013/08/02 Javascript
JavaScript获取网页中第一个图片id的方法
2015/04/03 Javascript
把Node.js程序加入服务实现随机启动
2015/06/25 Javascript
Jquery $when done then的用法详解
2016/05/20 Javascript
AngularJS 面试题集锦
2016/09/06 Javascript
JS无缝滚动效果实现方法分析
2016/12/21 Javascript
Javascript 对cookie操作详解及实例
2016/12/29 Javascript
详解使用nvm安装node.js
2017/07/18 Javascript
vue+node+webpack环境搭建教程
2017/11/05 Javascript
解决Mac安装thrift因bison报错的问题
2018/05/17 Javascript
微信小程序实现之手势锁功能实例代码
2018/07/19 Javascript
vuex直接赋值的三种方法总结
2018/09/16 Javascript
微信小程序人脸识别功能代码实例
2019/05/07 Javascript
js中!和!!的区别与用法
2020/05/09 Javascript
Python使用wget实现下载网络文件功能示例
2018/05/31 Python
python numpy数组复制使用实例解析
2020/01/10 Python
Python Websocket服务端通信的使用示例
2020/02/25 Python
Python基于paramunittest模块实现excl参数化
2020/04/26 Python
用pip给python安装matplotlib库的详细教程
2021/02/24 Python
泰国王权免税店官方网站:KingPower
2019/03/11 全球购物
Vector, ArrayList, HashTable, HashMap哪些是线程安全的,哪些不是
2015/10/12 面试题
物流司机岗位职责
2013/12/28 职场文书
有趣的广告词
2014/03/18 职场文书
《草原的早晨》教学反思
2014/04/08 职场文书
普通党员个人对照检查材料
2014/09/18 职场文书
2015年银行柜员工作总结报告
2015/04/01 职场文书
golang 生成对应的数据表struct定义操作
2021/04/28 Golang