浅谈python下tiff图像的读取和保存方法

对比测试 scipy.misc PIL.Image libtiff.TIFF 三个库

输入:

1. (读取矩阵) 读入uint8、uint16、float32的lena.tif

2. (生成矩阵) 使用numpy产生随机矩阵,float64的mat

import numpy as np
from scipy import misc
from PIL import Image
from libtiff import TIFF
#
# 读入已有图像,数据类型和原图像一致
tif32 = misc.imread('.\test\lena32.tif') #<class 'numpy.float32'>
tif16 = misc.imread('.\test\lena16.tif') #<class 'numpy.uint16'>
tif8 = misc.imread('.\test\lena8.tif') #<class 'numpy.uint8'>
# 产生随机矩阵,数据类型float64
np.random.seed(12345)
flt = np.random.randn(512, 512)   #<class 'numpy.float64'>
# 转换float64矩阵type,为后面作测试
z8 = (flt.astype(np.uint8))    #<class 'numpy.uint8'>
z16 = (flt.astype(np.uint16))   #<class 'numpy.uint16'>
z32 = (flt.astype(np.float32))   #<class 'numpy.float32'> 

①对读取图像和随机矩阵的存储

# scipy.misc『不论输入数据是何类型,输出图像均为uint8』
misc.imsave('.\test\lena32_scipy.tif', tif32) #--> 8bit(tif16和tif8同)

misc.imsave('.\test\\randmat64_scipy.tif', flt) #--> 8bit
misc.imsave('.\test\\randmat8_scipy.tif', z8) #--> 8bit(z16和z32同)

# PIL.Image『8位16位输出图像与输入数据类型保持一致,64位会存成32位』
Image.fromarray(tif32).save('.\test\lena32_Image.tif') #--> 32bit
Image.fromarray(tif16).save('.\test\lena16_Image.tif') #--> 16bit
Image.fromarray(tif8).save('.\test\lena8_Image.tif') #--> 8bit

Image.fromarray(flt).save('.\test\\randmat_Image.tif') #--> 32bit(flt.min~flt.max)
im = Image.fromarray(flt.astype(np.float32))
im.save('.\test\\randmat32_Image.tif')     #--> 32bit(灰度值范围同上)
#『uint8和uint16类型转换,会使输出图像灰度变换到255和65535』
im = Image.frombytes('I;16', (512, 512), flt.tostring())
im.save('.\test\\randmat16_Image1.tif')    #--> 16bit(0~65535)
im = Image.fromarray(flt.astype(np.uint16))
im.save('.\test\\randmat16_Image2.tif')    #--> 16bit(0~65535)
im = Image.fromarray(flt.astype(np.uint8))
im.save('.\test\\randmat8_Image.tif')     #--> 8bit(0~255)

# libtiff.TIFF『输出图像与输入数据类型保持一致』
tif = TIFF.open('.\test\\randmat_TIFF.tif', mode='w')
tif.write_image(flt, compression=None)
tif.close() #float64可以存储,但因BitsPerSample=64,一些图像软件不识别
tif = TIFF.open('.\test\\randmat32_TIFF.tif', mode='w')
tif.write_image(flt.astype(np.float32), compression=None)
tif.close() #--> 32bit(flt.min~flt.max)
#『uint8和uint16类型转换,会使输出图像灰度变换到255和65535』
tif = TIFF.open('.\test\\randmat16_TIFF.tif', mode='w')
tif.write_image(flt.astype(np.uint16), compression=None)
tif.close() #--> 16bit(0~65535,8位则0~255)

②图像或矩阵归一化对存储的影响

# 『使用scipy,只能存成uint8』
z16Norm = (z16-np.min(z16))/(np.max(z16)-np.min(z16)) #<class 'numpy.float64'>
z32Norm = (z32-np.min(z32))/(np.max(z32)-np.min(z32))
scipy.misc.imsave('.\test\\randmat16_norm_scipy.tif', z16Norm) #--> 8bit(0~255)

# 『使用Image,归一化后变成np.float64 直接转8bit或16bit都会超出阈值,要*255或*65535』
# 『如果没有astype的位数设置,float64会直接存成32bit』
im = Image.fromarray(z16Norm)
im.save('.\test\\randmat16_norm_Image.tif')  #--> 32bit(0~1)
im = Image.fromarray(z16Norm.astype(np.float32))
im.save('.\test\\randmat16_norm_to32_Image.tif') #--> 32bit(灰度范围值同上)
im = Image.fromarray(z16Norm.astype(np.uint16))
im.save('.\test\\randmat16_norm_to16_Image.tif') #--> 16bit(0~1)超出阈值
im = Image.fromarray(z16Norm.astype(np.uint8))
im.save('.\test\\randmat16_norm_to8_Image.tif') #--> 8bit(0~1)超出阈值

im = Image.fromarray((z16Norm*65535).astype(np.uint16))
im.save('.\test\\randmat16_norm_to16_Image1.tif') #--> 16bit(0~65535)
im = Image.fromarray((z16Norm*255).astype(np.uint16))
im.save('.\test\\randmat16_norm_to16_Image2.tif') #--> 16bit(0~255)
im = Image.fromarray((z16Norm*255).astype(np.uint8))
im.save('.\test\\randmat16_norm_to8_Image2.tif') #--> 8bit(0~255)
# 『使用TIFF结果同Image』

③TIFF读取和存储多帧tiff图像

#tiff文件解析成图像序列:读取tiff图像
def tiff_to_read(tiff_image_name):
 tif = TIFF.open(tiff_image_name, mode = "r")
 im_stack = list()
 for im in list(tif.iter_images()):
  im_stack.append(im)
 return
 #根据文档,应该是这样实现,但测试中不管是tif.read_image还是tif.iter_images读入的矩阵数值都有问题

#图像序列保存成tiff文件:保存tiff图像
def write_to_tiff(tiff_image_name, im_array, image_num):
 tif = TIFF.open(tiff_image_name, mode = 'w')
 for i in range(0, image_num):
  im = Image.fromarray(im_array[i])
  #缩放成统一尺寸
  im = im.resize((480, 480), Image.ANTIALIAS)
  tif.write_image(im, compression = None)
 out_tiff.close()
 return

补充:libtiff读取多帧tiff图像

因为TIFF.open().read_image()和TIFF.open().iter_images()有问题,则换一种方式读

from libtiff import TIFFfile
tif = TIFFfile('.\test\lena32-3.tif')
samples, _ = tif.get_samples()

以上这篇浅谈python下tiff图像的读取和保存方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • python实现猜拳小游戏

    用python实现猜拳小游戏,供大家参考,具体内容如下 本练习旨在养成良好的编码习惯和练习逻辑思考. 1.使用python版本: 3.7.3: 2.代码内容实现如下 #!/usr/bin/env python # -*- coding: utf-8 -*- """ 简单实现猜拳小游戏,默认每回合 五局 Version: 0.1 Author: smartbabble Date: 2018-03-12 """ from random import

  • Python利用字典破解WIFI密码的方法

    最近看到网上的一些作品,然后进行一些完善.只是用于学习,不要去干坏事哦.程序来源于网,我只是做了一些优化.当然这种方法破解还是有点慢哦.我用的python 3.6.5 既然要破解wifi,那么连接wifi的模块首先要有的,我们要导入pywifi模块. 有些同学可能没有这个,如果直接通过pip安装的话,可能不能用,听说这个wifi模块被停用了,所以大家如果通过pip安装的不行,那么就下载我提供的. 链接:https://pan.baidu.com/s/1rn-5F1CS5UXOTcLh3QAMhg

  • python使用if语句实现一个猜拳游戏详解

    任务要求 在控制台中提示输入石头.剪刀.布,按回车键,然后给出游戏结果. 分析 我们知道在游戏规则中,石头克剪刀,剪刀克布,布克石头.但是这在计算机中并不是很好直接的表示,因此我们分别用0.1.2分别代表游戏中的石头剪刀布. 那么电脑该如何出拳呢?那就该用到python中的一个模块random中的一个方法random.randint()在0~2范围内产生一个随机整数,就表电脑出拳了. random.randint()的用法如下: # 首先导入模块 import random # 调用时传入两个整

  • 对python中数据集划分函数StratifiedShuffleSplit的使用详解

    文章开始先讲下交叉验证,这个概念同样适用于这个划分函数 1.交叉验证(Cross-validation) 交叉验证是指在给定的建模样本中,拿出其中的大部分样本进行模型训练,生成模型,留小部分样本用刚建立的模型进行预测,并求这小部分样本的预测误差,记录它们的平方加和.这个过程一直进行,直到所有的样本都被预测了一次而且仅被预测一次,比较每组的预测误差,选取误差最小的那一组作为训练模型. 下图所示 2.StratifiedShuffleSplit函数的使用 官方文档 用法: from sklearn.

  • 正确理解Python中if __name__ == '__main__'

    在Python,我们经常会编写 if __name__ == '__main__' 这么一段代码,这段代码该怎么来理解? 这段代码的功能理解如下: 一个python的文件有两种使用的方法: 作用一,直接作为脚本执行. 作用二,import到其他的python脚本中被调用(模块重用)执行. if __name__ == '__main__': 的作用就是控制这两种情况执行代码的过程,在if __name__ == '__main__': 下的代码只有在第一种情况下(即文件作为脚本直接执行)才会被执

  • 如何用Python破解wifi密码过程详解

    前言 Python真的是无所不能,原因就是因为Python有数目庞大的库,无数的现成的轮子,让你做很多很多应用都非常方便.wifi跟我们的生活息息相关,无处不在.今天从WiFi连接的原理,再结合代码为大家详细的出一期关于Python破译wifi密码的Python学习教程! 01.如何连接wifi 首先我们的电脑是如何连接wifi的呢?就拿我们的笔记本电脑来说,我们的笔记本电脑都有无线网卡,如下图所示: 当我们连接WiFi时,无线网卡会自动帮助我们扫描附近的WiFi信号,并且会返回WiFi信号的一

  • Python基础教程之if判断,while循环,循环嵌套

    if判断 判断的定义 如果条件满足,就做一件事:条件不满足,就做另一件事:  判断语句又被称为分支语句,有判断,才有分支: if判断语句基本语法 if语句格式: if 判断的条件:     条件成立后做的事     ... ... 代码缩进为一个tab键,或者四个空格,官方建议使用空格:但应注意,在python开发中,tab和空格不能混用! 判断年龄示例: # 判断是否成年,成年则可以进网吧 age = 19 if age>=18: print("你满了18岁,可以进网吧") i

  • 浅谈python下tiff图像的读取和保存方法

    对比测试 scipy.misc 和 PIL.Image 和 libtiff.TIFF 三个库 输入: 1. (读取矩阵) 读入uint8.uint16.float32的lena.tif 2. (生成矩阵) 使用numpy产生随机矩阵,float64的mat import numpy as np from scipy import misc from PIL import Image from libtiff import TIFF # # 读入已有图像,数据类型和原图像一致 tif32 = mi

  • 浅谈python下含中文字符串正则表达式的编码问题

    前言 Python文件默认的编码格式是ascii ,无法识别汉字,因为ascii码中没有中文. 所以py文件中要写中文字符时,一般在开头加 # -*- coding: utf-8 -*- 或者 #coding=utf-8. 这是指定一种编码格式,意味着用该编码存储中文字符(也可以是gbk.gb2312等). 关于测试的几点注意 -------------------------------------------- 注1:代码中有中文,就要在头部指定编码方式,如果用编辑器写代码,还要注意IDE的

  • 利用Python裁切tiff图像且读取tiff,shp文件的实例

    我就废话不多说了,还是直接看代码吧! from osgeo import gdal, gdalnumeric, ogr from PIL import Image, ImageDraw from osgeo import gdal_array import os import operator from functools import reduce gdal.UseExceptions() def readTif(fileName): dataset = gdal.Open(fileName)

  • 浅谈python opencv对图像颜色通道进行加减操作溢出

    由于opencv读入图片数据类型是uint8类型,直接加减会导致数据溢出现象 (1)用Numpy操作 可以先将图片数据类型转换成int类型进行计算, data=np.array(image,dtype='int') 经过处理后(如:遍历,将大于255的置为255,小于0的置为0) 再将图片还原成uint8类型 data=np.array(image,dtype='uint8') 注意: (1)如果直接相加,那么 当像素值 > 255时,结果为对256取模的结果,例如:(240+66) % 256

  • 浅谈Linux下修改/设置环境变量JAVA_HOME的方法

    1. 永久修改,对所有用户有效 # vi /etc/profile //按键盘[Shift + g], 在profile文件最后添加下面的内容: JAVA_HOME=/usr/local/java/jdk1.7.0_25 JRE_HOME=$JAVA_HOME/jre CLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar PATH=$JAVA_HOME/bin:$PATH export PATH JAVA_HOME JRE_HOME C

  • 浅谈Visual C#进行图像处理(读取、保存以及对像素的访问)

    这里之所以说"浅谈"是因为我这里只是简单的介绍如何使用Visual C#进行图像的读入.保存以及对像素的访问.而不涉及太多的算法. 一.读取图像 在Visual C#中我们可以使用一个Picture Box控件来显示图片,如下: 复制代码 代码如下: private void btnOpenImage_Click(object sender, EventArgs e) {     OpenFileDialog ofd = new OpenFileDialog();     ofd.Fi

  • 浅谈python中的__init__、__new__和__call__方法

    前言 本文主要给大家介绍关于python中__init__.__new__和__call__方法的相关内容,分享出来供大家参考学习,下面话不多说,来一起看看详细的介绍: 任何事物都有一个从创建,被使用,再到消亡的过程,在程序语言面向对象编程模型中,对象也有相似的命运:创建.初始化.使用.垃圾回收,不同的阶段由不同的方法(角色)负责执行. 定义一个类时,大家用得最多的就是 __init__ 方法,而 __new__ 和 __call__ 使用得比较少,这篇文章试图帮助大家把这3个方法的正确使用方式

  • 浅谈Python Pygame图像的基本使用

    笛卡尔坐标系 游戏离不开坐标,我们来康康pygame中坐标是如何设立的吧~ 窗口左上角坐标(0,0),横轴正向向右,纵轴正向向下 实际效果 碰到边框就返回(其实是小球碰撞实验,我不爱用正经的小球,所以-) 代码 import pygame,sys pygame.init() size = width, height = 600, 400 speed = [1,1] BLACK = 0, 0, 0 s = pygame.display.set_mode(size) pygame.display.s

  • 浅谈python import引入不同路径下的模块

    python 包含子目录中的模块方法比较简单,关键是能够在sys.path里面找到通向模块文件的路径. 下面将具体介绍几种常用情况: (1)主程序与模块程序在同一目录下: 如下面程序结构: `-- src     |-- mod1.py     `-- test1.py 若在程序test1.py中导入模块mod1, 则直接使用 import  mod1或from mod1 import *; (2)主程序所在目录是模块所在目录的父(或祖辈)目录 如下面程序结构: `-- src     |--

  • 浅谈python在提示符下使用open打开文件失败的原因及解决方法

    题目:在提示符下使用open打开一个文件 刚开始网上看了下打开的方式,结果一直实现不了,报错是没找到这个文件,而且和我输入的文件名不一样. 错误如下: >>>open('d:\456.txt') Traceback (most recent call last): File "<pyshell#0>", line 1, in <module> open('d:\456.txt') IOError: [Errno 2] No such file

随机推荐