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获取某一天是星期几的方法示例
Jan 17 Python
Python正则表达式分组概念与用法详解
Jun 24 Python
Python解决N阶台阶走法问题的方法分析
Dec 28 Python
python socket网络编程之粘包问题详解
Apr 28 Python
在python中利用KNN实现对iris进行分类的方法
Dec 11 Python
python实现弹跳小球
May 13 Python
python反编译学习之字节码详解
May 19 Python
解决Python计算矩阵乘向量,矩阵乘实数的一些小错误
Aug 26 Python
详解python中各种文件打开模式
Jan 19 Python
Python max函数中key的用法及原理解析
Jun 26 Python
分享几种python 变量合并方法
Mar 20 Python
python 离散点图画法的实现
Apr 01 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
DOTA2 6.87版本后新眼位详解攻略
2020/04/20 DOTA
详细介绍:Apache+PHP+MySQL配置攻略
2006/09/05 PHP
PHP字符转义相关函数小结(php下的转义字符串)
2007/04/12 PHP
PHP fopen 读取带中文URL地址的一点见解
2012/09/25 PHP
PHP上传图片、删除图片简单实例
2016/11/12 PHP
JavaScript Object的extend是一个常用的功能
2009/12/02 Javascript
JavaScript isPrototypeOf和hasOwnProperty使用区别
2010/03/04 Javascript
基于Jquery与WebMethod投票功能实现代码
2011/01/19 Javascript
javascript截取字符串(通过substring实现并支持中英文混合)
2013/06/24 Javascript
同域jQuery(跨)iframe操作DOM(实例讲解)
2013/12/19 Javascript
jquery删除数据记录时的弹出提示效果
2014/05/06 Javascript
Node.js 实现简单小说爬虫实例
2016/11/18 Javascript
通过Ajax使用FormData对象无刷新上传文件方法
2016/12/08 Javascript
用jquery的attr方法实现图片切换效果
2017/02/05 Javascript
vue2.0 子组件改变props值,并向父组件传值的方法
2018/03/01 Javascript
vue中$nextTick的用法讲解
2019/01/17 Javascript
layer.msg()去掉默认时间,实现手动关闭的方法
2019/09/12 Javascript
vue输入节流,避免实时请求接口的实例代码
2019/10/30 Javascript
vue 使用鼠标滚动加载数据的例子
2019/10/31 Javascript
JavaScript中数组去重的5种方法
2020/07/04 Javascript
vue实现移动端触屏拖拽功能
2020/08/21 Javascript
浅析JavaScript 函数柯里化
2020/09/08 Javascript
[51:53]DOTA2-DPC中国联赛 正赛 RNG vs Dragon BO3 第二场 1月24日
2021/03/11 DOTA
Django查找网站项目根目录和对正则表达式的支持
2015/07/15 Python
浅谈pandas用groupby后对层级索引levels的处理方法
2018/11/06 Python
Python 单例设计模式用法实例分析
2019/09/23 Python
Python编程快速上手——正则表达式查找功能案例分析
2020/02/28 Python
终于搞懂了Keras中multiloss的对应关系介绍
2020/06/22 Python
python3 循环读取excel文件并写入json操作
2020/07/14 Python
Python约瑟夫生者死者小游戏实例讲解
2021/01/04 Python
浅谈css3新单位vw、vh、vmin、vmax的使用详解
2017/12/01 HTML / CSS
JAVA程序设计笔试题面试题一套
2015/07/28 面试题
如何在Shell脚本中使用函数
2015/09/06 面试题
高中自我评价分享
2013/12/05 职场文书
保密工作实施方案
2014/02/24 职场文书
土木工程生产实习心得体会
2016/01/22 职场文书