2017-07-06 23:51:43 liuyuehui110 阅读数 755

pillow

Pillow库为Python解释器添加了图像处理功能。它提供广泛的文件格式支持,高效的内部表示,以及相当强大的图像处理功能。

功能特点

  • 图像存档Pillow库是写图像存档和图像批处理应用程序的理想选择。您可以使用该库创建缩略图,在文件格式之间进行转换,打印图片等。当前版本支持识别和读取大量图像格式,也支持有限格式的写入和格式转换。
  • 图像显示当前版本包括Tk PhotoImage和BitmapImage接口,以及可以与PythonWin和其他基于Windows的工具包一起使用的Windows DIB接口。 对于调试,还有一个show()方法将图像临时保存到磁盘,并调用外部程序显示。
  • 图像处理Pillow包含基本的图像处理功能,包括点操作,内置的卷积内核滤镜和色域转换。该库还支持图像调整大小,旋转和任意映射变换。 还有一个直方图方法允许你从图像中提取一些统计数据。这可以用于自动对比度增强,和用于全局统计分析。

使用示例 

要从文件加载图像,请使用Image模块中的open()函数:

如果成功,此函数将返回一个Image对象。 现在可以检查文件内容:

Image类包含允许你操作图像中某个区域的方法。要从图像中提取子矩形,请使用crop()方法:

简单几何变换:

安装

针对不同系统和外部格式库的安装,请参照完整安装文档

开发资源

官方网站:http://python-pillow.org/
开源地址:https://github.com/python-pillow/Pillow

2019-06-09 18:23:21 zzqaaasss 阅读数 4342

实验环境:windows10,pyCharm

本文在如下博文的基础上进行:

python图像处理 (一).PIL图像处理库学习①

1、自定义创建图片

PIL除了可以从文件中打开一张图片,我们也可以创建一张图片

Image.new(mode,size) ⇒ image
Image.new(mode, size,color) ⇒ image

创建具有给定模式和大小的新图像。Size以(宽、高)-元组的形式给出,单位为像素。对于单通道图像,变量color只给定一个值;对于多通道图像,变量color给定一个元组(每个通道对应一个值),如果省略颜色参数,则图像将填充0(这通常对应于黑色)。如果颜色为None,则不初始化图像。如果你要在图像中粘贴或绘制东西,这是很有用的。

如下创建了一张三通道大小为255*255的红色图像:

from PIL import Image  #导入PIL库中的Image模块
im = Image.new("RGB", (128, 128), "red") #新建图像
im.show()

显示效果如下:

 2、复制图像

im.crop(box) ⇒ image

复制图像。如果您希望将内容粘贴到图像中,但仍保留原始内容,请使用此方法。

如下返回的和原图一样的:

from PIL import Image  #导入PIL库中的Image模块
im = Image.new("RGB", (225, 225), "red")  #新建图像
new_im = im.copy() #复制图像

3、裁剪图像

im.crop(box) ⇒ image

从当前图像返回矩形区域的副本。box是一个定义左、上、右和下像素坐标的4元组。
这是一个延迟操作。对源图像的更改可以反映在裁剪后的图像中,也可以不反映在裁剪后的图像中。要获得单独的副本,请调用裁剪副本上的load方法。

代码如下:

from PIL import Image  #导入PIL库中的Image模块
im = Image.open("images/mm.png")
im.show()  #显示原图
box = (100,100,300,300)  #裁剪区域
new_im = im.crop(box) #裁剪图片
new_im.show()  #显示裁剪区域

效果如下:

4、粘贴图像

im.paste(image, box)

将另一个图像粘贴到此图像中。box参数要么是一个给出左上角的2元组,要么是一个定义左、上、右和下像素坐标的4元组,要么没有(与(0,0)相同)。如果给定一个4元组,则粘贴图像的大小必须与区域的大小匹配。
如果模式不匹配,则将粘贴的图像转换为此图像的模式

如下打开一张图像然后在图像上粘贴一个自己创建的图像:

from PIL import Image  #导入PIL库中的Image模块
im1 = Image.open("images/mm.png")
box = (100,100,300,300)  #粘贴区域
im2 = Image.new('RGB',(200,200),'red')  #创建一张图像
im1.paste(im2,box) #在box区域粘贴im2图像
im1.show()

效果如下:

使用:im1.paste('red',box) 和上面效果相同

5、滤波器

im.filter(filter) ⇒ image

返回由给定过滤器过滤的图像的副本。有关可用过滤器的列表,请参见下表。

filtes

描述
BLUR 模糊滤镜
CONTOUR 轮廓滤镜
DETAIL 细节滤镜
EDGE_ENHANCE 边界增强滤镜
EDGE_ENHANCE_MORE 边界增强加强版滤镜
 EMBOSS 浮雕滤镜
FUND_EDGES 寻找边界滤镜
SMOOTH 平滑滤镜
SOOTH_MORE 平滑滤镜加强版
SHARPEN 锐化滤镜

如下举个小列子:

from PIL import Image  #导入PIL库中的Image模块
from PIL import ImageFilter  #导入PIL库中的ImageFilter模块
im = Image.open("images/mm.png").resize((255,255))
im.show()
BLUR_im = im.filter(ImageFilter.BLUR)
CONTOUR_im = im.filter(ImageFilter.CONTOUR)
DETAIL_im = im.filter(ImageFilter.DETAIL)
EMBOSS_im = im.filter(ImageFilter.EMBOSS)
DETAIL_im.show()
EMBOSS_im.show()
BLUR_im.show()
CONTOUR_im.show()

效果如下:

 

剩下的自己试下。

6、混合图像

Image.blend(image1, image2, alpha) ⇒ image

使用给定的两张图像及透明度变量alpha,插值出一张新的图像。这两张图像必须有一样的尺寸和模式。混合公式如下:

混合公式为:out = image1 (1.0 - alpha) + image2 alpha

若变量alpha为0.0,返回第一张图像的拷贝。若变量alpha为1.0,将返回第二张图像的拷贝。对变量alpha的值无限制。

例子如下:

from PIL import Image  #导入PIL库中的Image模块
from PIL import ImageFilter  #导入PIL库中的ImageFilter模块
im1 = Image.open("images/mm.png").resize((255,255)).convert('RGB') #为了和图像2的大小和模式一样重置大小和模式
im2 = Image.open("images/rb.jpg").resize((255,255))  ##为了和图像1的大小和模式一样重置大小和模式
#im1和im2按照第一张60%的透明度,第二张40%的透明度,合成为一张。
new_im = Image.blend(im1,im2,0.6) #混合图像
new_im.show()

效果如下:

 7、分离图像

im.split() ⇒ sequence

 返回当前图像各个通道组成的一个元组。例如,分离一个“RGB”图像将产生三个新的图像,分别对应原始图像的每个通道(红,绿,蓝)

测试代码如下:

from PIL import Image  #导入PIL库中的Image模块
im = Image.open("images/mm.png").resize((128,128)).convert('RGB')
r,g,b = im.split()
r.show()
g.show()
b.show()

 效果如下:

 差别不是很大,但还是有差别的。

 

 

 

 

2019-02-13 17:25:05 weixin_42514606 阅读数 383


在Pyhton图像库「Python Imaging Library」支持大量的图片格式,是图像处理和批处理的最佳选择,可以用这个来创建缩略图、文件格式之间的转换、打印图片、大小转换、颜色转换、还有对图片加滤镜「模糊、磨皮」等操作。功能非常简单,但是API调用非常简单


安装

安装的仍然使用pip安装,非常简单快捷。对于国内用户来说,不能访问python官网的时候,可以替换python源为阿里源或者其他国内源;其二对于其他的内网用户来说,可以在安装的时候加上代理地址。

$ pip install Pillow # python2
$ pip3 install Pillow # python3 如果没有添加pip3软连接,用python3的pip一样的

$ pip install Pillow --proxy=10.10.10.10:80 # 代理

验证是否安装成功,没有报错就是安装成功了。

>>> import PIL
>>> dir(PIL)
['PILLOW_VERSION', 'VERSION', '__builtins__', '__cached__', '__doc__.......

访问文件

用「open」方法打开指定文件即可,可以看到文件的一些详细参数,比如大小、高度、长度、格式、模式等。

from PIL import Image
try:
    im= Image.open("1.png")
    print(im.format, im.size, im.mode)
except Exception as e:
        print(e)
# output: PNG (736, 458) RGB

加载图像

获取到Image实例之后,可以用这个类的方法来处理和操作图像。这个是把图片保存位临时文件,然后用系统默认的图片查看工具来显示图片的,方便调试和测试。也可以用save()方法来保存文件。

>>> im.show()
>>> im.save("test.png") #

读写图像

对图像的几何变换、颜色变换、图像增强、以及剪切等操作。

图像过滤器

图像增强处理里面有个,包含了一个过滤器ImageFilter模块,可以模糊图片等操作,下面是一个模糊操作的Demo。

# Import the modules
from PIL import Image, ImageFilter

try:
    # Load an image from the hard drive
    original = Image.open("1.png")

    # Blur the image
    blurred = original.filter(ImageFilter.BLUR)

    # Display both images
    original.show()
    blurred.show()

    # save the new image
    blurred.save("blurred.png")

except:
    print "Unable to load image"

效果如下:在这里插入图片描述
除了BLUR,还有其他的参数。

BLUR
CONTOUR
DETAIL
EDGE_ENHANCE
EDGE_ENHANCE_MORE
EMBOSS
FIND_EDGES
SMOOTH
SMOOTH_MORE
SHARPEN

创建缩略图

也是同样使用实例的thumbnail方法即可,非常简单。

from PIL import Image
size = (128, 128)
thumbnail= "thumbnail.jpeg"
try:
    im =  Image.open("1.png")
except Exception as e:
    print(e)
im.thumbnail(size)
im.save(thumbnail)

缩略图

剪切、粘贴

剪切使用crop方法即可,指定 2 个坐标,需要说明的是左上角是(0 ,0);

box = (10, 10, 200, 200) # 对应: 左 上 右 下
region = im.crop(box) # 剪切

region = region.transpose(Image.ROTATE_180)
im.paste(region, box) # 粘贴

小结

python 图像处理「PIL」对图像处理非常容易,加上完善的API文档手册,对于新手也是非常友好的。

更多阅读

  1. Pillow 官方文档
2018-01-31 21:19:55 bjbz_cxy 阅读数 380

这一系列的文章都将以BMP格式图像为主做处理,主要是为了让大家能对图像处理有一个良好的认知,后面会教大家写一个能支持BMP,JPG,JPEG,PNG等格式的图像处理库。

首先你要对图像处理以及图像理论有一个基本的认识,如果没有任何基本的图像知识的话我建议先看一下博主的这篇文章:Opencv学习笔记_计算机视觉是什么?Opencv的起源 虽然说这篇文章是介绍计算机视觉和opencv的但是其中包含了很多图像理论知识。

首先第一步要对BMP图像文件格式要有一个基本的认识:

BMP图像格式详解

一.简介
BMP(Bitmap-File)图形文件是Windows采用的图形文件格式,在Windows环境下运行的所有图象处理软件都支持BMP图象文件格式。Windows系统内部各图像绘制操作都是以BMP为基础的。Windows 3.0以前的BMP图文件格式与显示设备有关,因此把这种BMP图象文件格式称为设备相关位图DDB(device-dependent bitmap)文件格式。Windows 3.0以后的BMP图象文件与显示设备无关,因此把这种BMP图象文件格式称为设备无关位图DIB(device-independent bitmap)格式(注:Windows 3.0以后,在系统中仍然存在DDB位图,象BitBlt()这种函数就是基于DDB位图的,只不过如果你想将图像以BMP格式保存到磁盘文件中时,微软极力推荐你以DIB格式保存),目的是为了让Windows能够在任何类型的显示设备上显示所存储的图象。BMP位图文件默认的文件扩展名是BMP或者bmp(有时它也会以.DIB或.RLE作扩展名)。
 
二.BMP格式结构
BMP文件的数据按照从文件头开始的先后顺序分为四个部分:
◆ 位图文件头(bmp file header):  提供文件的格式、大小等信息
◆ 位图信息头(bitmap information):提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息
◆ 调色板(color palette):可选,如使用索引来表示图像,调色板就是索引与其对应的颜色的映射表
◆ 位图数据(bitmap data):图像数据区
 
BMP图片文件数据表如下:

 

数据段名称大小(byte)开始地址结束地址
位图文件头(bitmap-file header)
140000h000Dh
位图信息头(bitmap-information header)
40000Eh0035h
调色板(color table)
由biBitCount决定0036h未知
图片点阵数据(bitmap data)
由图片大小和颜色定未知未知

 

 
 
 
三.BMP文件头
BMP文件头结构体定义如下:
typedef struct tagBITMAPFILEHEADER
UINT16 bfType;        //2Bytes,必须为"BM",即0x424D 才是Windows位图文件
DWORD bfSize;         //4Bytes,整个BMP文件的大小
UINT16 bfReserved1;  //2Bytes,保留,为0
UINT16 bfReserved2;  //2Bytes,保留,为0
DWORD bfOffBits;     //4Bytes,文件起始位置到图像像素数据的字节偏移量
BITMAPFILEHEADER;
 
BMP文件头数据表如下:

 

变量名地址偏移大小作用说明
bfType0000h2Bytes
文件标识符,必须为"BM",即0x424D 才是Windows位图文件
‘BM’:Windows 3.1x, 95, NT,…  ‘BA’:OS/2 Bitmap Array  ‘CI’:OS/2 Color Icon   
‘CP’:OS/2 Color Pointer   ‘IC’:OS/2 Icon   
‘PT’:OS/2 Pointer
因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识“BM”就行
bfSize0002h4Bytes整个BMP文件的大小(以位B为单位)
bfReserved10006h2Bytes保留,必须设置为0
bfReserved20008h2Bytes保留,必须设置为0
bfOffBits000Ah4Bytes说明从文件头0000h开始到图像像素数据的字节偏移量(以字节Bytes为单位),以为位图的调色板长度根据位图格式不同而变化,可以用这个偏移量快速从文件中读取图像数据

 

 
 
四.BMP信息头
BMP信息头结构体定义如下:
typedef struct _tagBMP_INFOHEADER
{
DWORD  biSize;    //4Bytes,INFOHEADER结构体大小,存在其他版本I NFOHEADER,用作区分
LONG   biWidth;    //4Bytes,图像宽度(以像素为单位)
LONG   biHeight;    //4Bytes,图像高度,+:图像存储顺序为Bottom2Top,-:Top2Bottom
WORD   biPlanes;    //2Bytes,图像数据平面,BMP存储RGB数据,因此总为1
WORD   biBitCount;         //2Bytes,图像像素位数
DWORD  biCompression;     //4Bytes,0:不压缩,1:RLE8,2:RLE4
DWORD  biSizeImage;       //4Bytes,4字节对齐的图像数据大小
LONG   biXPelsPerMeter;   //4 Bytes,用象素/米表示的水平分辨率
LONG   biYPelsPerMeter;   //4 Bytes,用象素/米表示的垂直分辨率
DWORD  biClrUsed;          //4 Bytes,实际使用的调色板索引数,0:使用所有的调色板索引
DWORD biClrImportant;     //4 Bytes,重要的调色板索引数,0:所有的调色板索引都重要
}BMP_INFOHEADER;
 
BMP信息头数据表如下:

 

变量名
地址偏移
大小
作用说明
biSize
000Eh
4Bytes
BNP信息头即BMP_INFOHEADER结构体所需要的字节数(以字节为单位)
biWidth
0012h
4Bytes
说明图像的宽度(以像素为单位)
biHeight
0016h
4Bytes
说明图像的高度(以像素为单位)。这个值还有一个用处,指明图像是正向的位图还是倒向的位图,该值是正数说明图像是倒向的即图像存储是由下到上;该值是负数说明图像是倒向的即图像存储是由上到下。大多数BMP位图是倒向的位图,所以此值是正值。
biPlanes
001Ah
2Bytes
为目标设备说明位面数,其值总设置为1
biBitCount
001Ch
2Bytes
说明一个像素点占几位(以比特位/像素位单位),其值可为1,4,8,16,24或32
biCompression
001Eh
4Bytes
说明图像数据的压缩类型,取值范围为:
0         BI_RGB 不压缩(最常用)
1         BI_RLE8 8比特游程编码(BLE),只用于8位位图
2         BI_RLE4 4比特游程编码(BLE),只用于4位位图
3         BI_BITFIELDS比特域(BLE),只用于16/32位位图
4          
biSizeImage
0022h
4Bytes
说明图像的大小,以字节为单位。当用BI_RGB格式时,总设置为0
biXPelsPerMeter
0026h
4Bytes
说明水平分辨率,用像素/米表示,有符号整数
biYPelsPerMeter
002Ah
4Bytes
说明垂直分辨率,用像素/米表示,有符号整数
biClrUsed002Eh4Bytes说明位图实际使用的调色板索引数,0:使用所有的调色板索引
biClrImportant0032h4Bytes说明对图像显示有重要影响的颜色索引的数目,如果是0,表示都重要。

 

 
五.BMP调色板
BMP调色板结构体定义如下:
typedef struct _tagRGBQUAD
{
BYTE  rgbBlue;       //指定蓝色强度
BYTE  rgbGreen;      //指定绿色强度
BYTE  rgbRed;        //指定红色强度
 BYTE  rgbReserved;  //保留,设置为0
RGBQUAD;
 
1,4,8位图像才会使用调色板数据,16,24,32位图像不需要调色板数据,即调色板最多只需要256项(索引0 - 255)。
颜色表的大小根据所使用的颜色模式而定:2色图像为8字节;16色图像位64字节;256色图像为1024字节。其中,每4字节表示一种颜色,并以B(蓝色)、G(绿色)、R(红色)、alpha(32位位图的透明度值,一般不需要)。即首先4字节表示颜色号1的颜色,接下来表示颜色号2的颜色,依此类推。
颜色表中RGBQUAD结构数据的个数有biBitCount来确定,当biBitCount=1,4,8时,分别有2,16,256个表项。
当biBitCount=1时,为2色图像,BMP位图中有2个数据结构RGBQUAD,一个调色板占用4字节数据,所以2色图像的调色板长度为2*4为8字节。
当biBitCount=4时,为16色图像,BMP位图中有16个数据结构RGBQUAD,一个调色板占用4字节数据,所以16像的调色板长度为16*4为64字节。
当biBitCount=8时,为256色图像,BMP位图中有256个数据结构RGBQUAD,一个调色板占用4字节数据,所以256色图像的调色板长度为256*4为1024字节。
当biBitCount=16,24或32时,没有颜色表。
 
五.BMP图像数据区
位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数:
当biBitCount=1时,8个像素占1个字节;
当biBitCount=4时,2个像素占1个字节;
当biBitCount=8时,1个像素占1个字节;
当biBitCount=24时,1个像素占3个字节;
Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充,
一个扫描行所占的字节数计算方法:
DataSizePerLine= (biWidth* biBitCount+31)/8;
// 一个扫描行所占的字节数
DataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数
位图数据的大小(不压缩情况下):
DataSize= DataSizePerLine* biHeight;
 
颜色表接下来位为位图文件的图像数据区,在此部分记录着每点像素对应的颜色号,其记录方式也随颜色模式而定,既2色图像每点占1位(8位为1字节);16色图像每点占4位(半字节);256色图像每点占8位(1字节);真彩色图像每点占24位(3字节)。所以,整个数据区的大小也会随之变化。究其规律而言,可的出如下计算公式:图像数据信息大小=(图像宽度*图像高度*记录像素的位数)/8。

通过上面的描述,我们基本上对BMP图像文件格式有一个基本的认识了,那么我们可以通过c语言的结构体的内存对齐机制来依次读取这些头文件信息,并转化成可识别的十进制信息!

首先第一步,对c语言的基本类型定义别名,方便维护。

//8bit
typedef char UINT_8;
//16bit
typedef char UINT_16[2];
//22bit
typedef char UINT_22[3];
//256bit
typedef char UINT_256[256];
//32bit
typedef int  UINT_32;
//data
typedef char* DATA;
//64 fbit
typedef double FUINT_64;
//16bit int
typedef short SUINT_16;

然后根据头信息在文件中的字节偏移地址来定义结构体:

变量名地址偏移大小作用说明
bfType0000h2Bytes
文件标识符,必须为"BM",即0x424D 才是Windows位图文件
‘BM’:Windows 3.1x, 95, NT,…  ‘BA’:OS/2 Bitmap Array  ‘CI’:OS/2 Color Icon   
‘CP’:OS/2 Color Pointer   ‘IC’:OS/2 Icon   
‘PT’:OS/2 Pointer
因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识“BM”就行
bfSize0002h4Bytes整个BMP文件的大小(以位B为单位)
bfReserved10006h2Bytes保留,必须设置为0
bfReserved20008h2Bytes保留,必须设置为0
bfOffBits000Ah4Bytes说明从文件头0000h开始到图像像素数据的字节偏移量(以字节Bytes为单位),以为位图的调色板长度根据位图格式不同而变化,可以用这个偏移量快速从文件中读取图像数据



变量名
地址偏移
大小
作用说明
biSize
000Eh
4Bytes
BNP信息头即BMP_INFOHEADER结构体所需要的字节数(以字节为单位)
biWidth
0012h
4Bytes
说明图像的宽度(以像素为单位)
biHeight
0016h
4Bytes
说明图像的高度(以像素为单位)。这个值还有一个用处,指明图像是正向的位图还是倒向的位图,该值是正数说明图像是倒向的即图像存储是由下到上;该值是负数说明图像是倒向的即图像存储是由上到下。大多数BMP位图是倒向的位图,所以此值是正值。
biPlanes
001Ah
2Bytes
为目标设备说明位面数,其值总设置为1
biBitCount
001Ch
2Bytes
说明一个像素点占几位(以比特位/像素位单位),其值可为1,4,8,16,24或32
biCompression
001Eh
4Bytes
说明图像数据的压缩类型,取值范围为:
0         BI_RGB 不压缩(最常用)
1         BI_RLE8 8比特游程编码(BLE),只用于8位位图
2         BI_RLE4 4比特游程编码(BLE),只用于4位位图
3         BI_BITFIELDS比特域(BLE),只用于16/32位位图
4          
biSizeImage
0022h
4Bytes
说明图像的大小,以字节为单位。当用BI_RGB格式时,总设置为0
biXPelsPerMeter
0026h
4Bytes
说明水平分辨率,用像素/米表示,有符号整数
biYPelsPerMeter
002Ah
4Bytes
说明垂直分辨率,用像素/米表示,有符号整数
biClrUsed002Eh4Bytes说明位图实际使用的调色板索引数,0:使用所有的调色板索引
biClrImportant0032h4Bytes说明对图像显示有重要影响的颜色索引的数目,如果是0,表示都重要。

注意这里一定要使用#pragma pack(1)告诉编译器结构体按1字节对齐(详细:详解C语言内存对齐)否则在读入文件流数据时会出现数据混淆的原因
//结构体
//图像结构体,防止结构体对齐否则读取文件流时出错,所以用pragma命令强制对齐
#pragma pack(1)  
typedef struct image_struct{
	UINT_16   image_pil;                //文件标识符  
	UINT_32   image_Size;               //文件大小  
	UINT_16   image_Reserved1;          //无需过问  
	UINT_16   image_Reserved2;          //无需过问  
	UINT_32   image_Offbits;            //头文件到图像数据偏移量  
	UINT_32   image_Stsize;             //结构体所需大小  
	UINT_32   image_Width;              //图像宽度  
	UINT_32   image_Height;             //图像高度  
	UINT_16   image_Planes;             //目标设备位面数  
	SUINT_16  image_Bitcount;           //像素点占用多少bit位  
	UINT_32   image_Compression;        //图像压缩类型  
	UINT_32   image_Sizeimage;          //图像的大小  
	UINT_32   image_Xpelspermeter;      //水平分辨率  
	UINT_32   image_Ypelspermeter;      //垂直分辨率  
	UINT_32   image_ClrUsed;            //调色板索引数  
	UINT_32   image_Clrlmportant;       //图像显示重要颜色索引数目  
	DATA      image_Data;               //图像数据 
	UINT_32   image_Data_Size;			//图像数据大小
}image; 
#pragma pack()  
下面开始写我们的第一个函数:image_load,加载图像文件
注意如果不使用c语言的内存对齐方式读取数据的话需要考虑大小端的问题,我们直接使用结构体来读取这样就不用考虑大小端的问题了,因为内存中的存储大小端与文件中是对应的!我们只需要直接读取到内存当中就行了!
//函数
//加载图像 
int image_load(struct image_struct** im, char *path){
	FILE *image_path_fp;
	image_path_fp = fopen(path, "rb");
	if (image_path_fp == NULL){
		return -1;
	}
	//取文件大小
	fseek(image_path_fp, 0, SEEK_END); //定位到文件末 
	int nFileLen = ftell(image_path_fp); //文件长度
	fseek(image_path_fp, 0, SEEK_SET);	//恢复到文件头,防止从文件尾读取数据
	//读取头信息
	if (fread((*im), (sizeof(struct image_struct) - ((sizeof(DATA/*image_Data*/)+(sizeof(UINT_32)/*image_Data_Size*/)))/*暂不读取数据,无法从头文件中获取数据偏移量,防止数据混乱*/), 1, image_path_fp) == 0){
		return -2;
	}
	//给data变量分配内存
	(*im)->image_Data = (DATA)malloc(nFileLen-(*im)->image_Offbits/*完整的数据大小*/);
	//判断是否分配成功
	if ((*im)->image_Data == NULL){	//如果没有可用堆内存则malloc返回NULL
		return -3;
	}
	//读取数据
	//读取前将文件指针挪移到文件头信息后,找到正确的数据存储区
	fseek(image_path_fp, 0, SEEK_SET);	//恢复到文件头,因为已经fread一次了,所以数据文件指针发生变更
	fseek(image_path_fp, (*im)->image_Offbits, SEEK_CUR);	//忽略头数据
	if (fread((*im)->image_Data, (nFileLen - (*im)->image_Offbits/*file - off = 实际大小*/), 1, image_path_fp) == 0){
		return -4;
	}
	//保存文件大小,方便读写操作
	(*im)->image_Data_Size = (nFileLen - (*im)->image_Offbits/*file - off = 实际大小*/);
	//文件指针释放,防止占用文件内核的临界资源
	fclose(image_path_fp);
	image_path_fp == NULL;
	return 0;
}
图像加载函数写完了,我们可能在使用结构体时会定义指针,所以为了方便我们在写一个用于分配内存的函数
//给图像数据分配内存
int image_malloc(struct image_struct** im){
	*im = (struct image_struct*)malloc(sizeof(struct image_struct));
	if (*im == NULL){
		return -1;
	}
	return 0;
}
还需要一个图像保存函数:
//保存图像数据到文件
int image_save_file(struct image_struct** im, char *path){
	FILE* file_fp = fopen(path, "wb+");	//以二进制可读写方式打开
	if (file_fp == NULL){	//判断文件指针是否为空
		return -1;
	}
	//写入头信息
	fwrite((*im), (*im)->image_Offbits/*直接写入头文件到数据的偏移量大小即可*/, 1, file_fp);
	//写入文件数据
	fwrite((*im)->image_Data, (*im)->image_Data_Size, 1, file_fp);
	return 0;

}
基本函数编写完成了,那么来做一个测试吧:
int main(){
	image *imga;
	image_malloc(&imga);
	image_load(&imga, "test.bmp");
	printf("图像宽度:%d\n", imga->image_Width); 
	printf("图像高度:%d\n", imga->image_Height);
	printf("图像文件占用字节:%d\n", imga->image_Size);
	printf("图像每个像素占用bit位:%d\n", imga->image_Bitcount);
	getchar();
}
完整代码:
/*Robust图像处理库
*版本:v1.0
*作者:周志豪
*4.17 19:09
*/
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
//类型定义
//8bit  
typedef char UINT_8;
//16bit  
typedef char UINT_16[2];
//22bit  
typedef char UINT_22[3];
//256bit  
typedef char UINT_256[256];
//32bit  
typedef int  UINT_32;
//data  
typedef char* DATA;
//64 fbit  
typedef double FUINT_64;
//16bit int  
typedef short SUINT_16;
//结构体
//图像结构体,防止结构体对齐否则读取文件流时出错,所以用pragma命令强制对齐
#pragma pack(1)  
typedef struct image_struct{
	UINT_16   image_pil;                //文件标识符  
	UINT_32   image_Size;               //文件大小  
	UINT_16   image_Reserved1;          //无需过问  
	UINT_16   image_Reserved2;          //无需过问  
	UINT_32   image_Offbits;            //头文件到图像数据偏移量  
	UINT_32   image_Stsize;             //结构体所需大小  
	UINT_32   image_Width;              //图像宽度  
	UINT_32   image_Height;             //图像高度  
	UINT_16   image_Planes;             //目标设备位面数  
	SUINT_16  image_Bitcount;           //像素点占用多少bit位  
	UINT_32   image_Compression;        //图像压缩类型  
	UINT_32   image_Sizeimage;          //图像的大小  
	UINT_32   image_Xpelspermeter;      //水平分辨率  
	UINT_32   image_Ypelspermeter;      //垂直分辨率  
	UINT_32   image_ClrUsed;            //调色板索引数  
	UINT_32   image_Clrlmportant;       //图像显示重要颜色索引数目  
	DATA      image_Data;               //图像数据 
	UINT_32   image_Data_Size;			//图像数据大小
}image; 
#pragma pack()  
//函数
//加载图像 
int image_load(struct image_struct** im, char *path){
	FILE *image_path_fp;
	image_path_fp = fopen(path, "rb");
	if (image_path_fp == NULL){
		return -1;
	}
	//取文件大小
	fseek(image_path_fp, 0, SEEK_END); //定位到文件末 
	int nFileLen = ftell(image_path_fp); //文件长度
	fseek(image_path_fp, 0, SEEK_SET);	//恢复到文件头,防止从文件尾读取数据
	//读取头信息
	if (fread((*im), (sizeof(struct image_struct) - ((sizeof(DATA/*image_Data*/)+(sizeof(UINT_32)/*image_Data_Size*/)))/*暂不读取数据,无法从头文件中获取数据偏移量,防止数据混乱*/), 1, image_path_fp) == 0){
		return -2;
	}
	//给data变量分配内存
	(*im)->image_Data = (DATA)malloc(nFileLen-(*im)->image_Offbits/*完整的数据大小*/);
	//判断是否分配成功
	if ((*im)->image_Data == NULL){	//如果没有可用堆内存则malloc返回NULL
		return -3;
	}
	//读取数据
	//读取前将文件指针挪移到文件头信息后,找到正确的数据存储区
	fseek(image_path_fp, 0, SEEK_SET);	//恢复到文件头,因为已经fread一次了,所以数据文件指针发生变更
	fseek(image_path_fp, (*im)->image_Offbits, SEEK_CUR);	//忽略头数据
	if (fread((*im)->image_Data, (nFileLen - (*im)->image_Offbits/*file - off = 实际大小*/), 1, image_path_fp) == 0){
		return -4;
	}
	//保存文件大小,方便读写操作
	(*im)->image_Data_Size = (nFileLen - (*im)->image_Offbits/*file - off = 实际大小*/);
	//文件指针释放,防止占用文件内核的临界资源
	fclose(image_path_fp);
	image_path_fp == NULL;
	return 0;
}
//给图像数据分配内存
int image_malloc(struct image_struct** im){
	*im = (struct image_struct*)malloc(sizeof(struct image_struct));
	if (*im == NULL){
		return -1;
	}
	return 0;
}
//将图像转换成反向图_该方法只能用于真彩图
int image_reverse_rgb(struct image_struct** im){
	if ((*im) == NULL){	//判断传递进来的图像指针是否为空
		return -1;
	}
	//转换成反向图很简单只需要将每个图像里的像素点转换成负的就可以了,注意在一个24位的图像文件中一个字节对应一个颜色值三个字节则为一个完整的像素点,所以我们一个一个像素点的转换就可以了
	//算法公式为:S=-R-G-B
	for (int i = 0; i < (*im)->image_Data_Size; ++i){
			if ((*im)->image_Data[i] == (int)0){	//如果等于0则不处理
				continue;	//开始下一次循环
			}//i*(*im)->image_Width + j
			(*im)->image_Data[i] = -(*im)->image_Data[i];	//调用宏函数转换
	}
	return 0;
}
//保存图像数据到文件
int image_save_file(struct image_struct** im, char *path){
	FILE* file_fp = fopen(path, "wb+");	//以二进制可读写方式打开
	if (file_fp == NULL){	//判断文件指针是否为空
		return -1;
	}
	//写入头信息
	fwrite((*im), (*im)->image_Offbits/*直接写入头文件到数据的偏移量大小即可*/, 1, file_fp);
	//写入文件数据
	fwrite((*im)->image_Data, (*im)->image_Data_Size, 1, file_fp);
	return 0;

}
int main(){
	image *imga;
	image_malloc(&imga);
	image_load(&imga, "test.bmp");
	printf("图像宽度:%d\n", imga->image_Width); 
	printf("图像高度:%d\n", imga->image_Height);
	printf("图像文件占用字节:%d\n", imga->image_Size);
	printf("图像每个像素占用bit位:%d\n", imga->image_Bitcount);
	getchar();
}

运行结果:

本篇先让大家对BMP格式有一个基本的认知,和读取图像头信息中较为重要的信息
2018-11-14 18:23:42 qq_43678660 阅读数 284

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

                原文地址:http://blog.sina.com.cn/s/blog_53c74fa1010002pn.html

做数字图像处理的,怎能没有一个图库?虽说自己可以建立,可是如果是比较知名的图库,做出来的实验结果才能比较让人信服。coral是很有名,可他要收费。我寻寻觅觅,还是找到了一些图库,有的是纯texture图库,比如著名的vistex,有的是faceimages,有的也有RGB真彩色图的。下面罗列了一些url,可以找到对应的。
 
1、http://vismod.media.mit.edu/
这是美国麻省media实验室的一个网页,该实验室在数字图像处理方面还是很有成就的。在download里面会有很多有用的东西。比如vistex or faceimages and others
 
2、http://www.dice.ucl.ac.be/mlg/index.php?page=DataBases
这是ucl的machine learning group的database
 
3、http://sipi.usc.edu/services/database/index.html
这是著名的美国南加州大学的USI-SIPI image database,有纹理图和真彩图
 
4、http://www.cs.washington.edu/research/imagedatabase/
这是华盛顿大学的Ground truth Database。这个图库我用的最多,因为目前做真彩色图作的比较多,而作单纯的纹理不是很多。该database里的图片都是RGB,jpeg格式的,对于matlab来说是很方便处理的。
 
所有图库我都下载过,链接均有效。当然我也不知道何时会失效,一般来说保留的时间应该比较长吧,因为都是大学在做的研究,前人学完了后人还需要。所以,基本上从我开始作发现这些图库开始,到现在已经半年了。依然保留着呢。

有需要的或者近期有需要的还是尽快下载吧。


http://decsai.ugr.es/cvg/dbimagenes/

Olivetti Research Laboratory in Cambridge人脸库


http://www.opencv.org.cn/opencvdoc/2.3.2/html/index.html


           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述

canvas图像处理

阅读数 702

canvas图像处理

博文 来自: weixin_37972723

OpenCV图像处理

阅读数 48

没有更多推荐了,返回首页