您的位置:首页 > 编程语言 > Python开发

基于python-tensorflow的机器视觉学习手札 (1.1)图像处理篇-表示方法、文件格式、像素运算

2018-08-03 09:16 501 查看

声明:以下都只是我在学习过程中的一些记录、思考与猜测,肯定会有很多不对的地方,欢迎大家批评指正!

一、图像处理基础知识篇

由于最早接触图像处理是在matlab上做毕业设计,所以入门书籍是《MATLAB图像处理实例详解》与冈萨雷斯的《数字图像处理(第二版)》。这两本书的pdf放在如下百度网盘链接里,需要可以自取:
链接:https://pan.baidu.com/s/1mQIgv9_62ABONo4zrdyVRA 密码:jd52
首先在第一篇里汇总一下数字图像处理中的一些基础知识,可能会分多p,希望自己能坚持下去。
编译环境:
本系列(如果能坚持下去)将都是由matlab来实现所有代码,原因是我个人觉得matlab更加具有数学可视化的特质,更容易阐述数学原理,当然也会用python-opencv来重复代码。前面一部分对实战无帮助,仅在此阐述概要。

1. 图像的表示方法

目前图像的传统表示方法分为五种,分别为二进制图像,索引图像,灰度图像,RGB图像,多帧图像。这些图像的表示方法网上很多详细解读,不在此赘述。

2. 图像文件格式

matlab中(很多其他语言也一样)有成熟的调用图片的子函数,这里只简要的提一下不同图像文件格式的区别:
BMP图像文件由四部分组成:1、BMP文件头数据(文件大小、图像类型、显示内容、从头到图像数据的偏移字符数、保留字);2、BMP信息头数据(图像宽度、高度、颜色位数、压缩方法、字节数、目标设备的分辨率、定义颜色、信息头数据长度等);3、colormap(RGB、灰度图不需要);4、位图数据。
BMP文件不采用任何压缩,占用空间大,不受web支持。
GIF图像文件由5部分组成:1、文件标识块:识别标识符和版本号;2、逻辑屏幕描述块(尺寸、显示区域大小、颜色深浅、是否有索引表、背景颜色信息);3、索引表;4、图像数据块;5、尾块(表示数据流的结束)。
GIF最多支持256种色彩,故通常用索引图,解码较快,文件较小。
JPEG格式较复杂,分为8块:1、SOI标记(数值0xD8,表示图像开始);2、APP0(数值0xE0,JFIF应用数据块,包含本块长度、标识符、版本号、XY的dpi值、XY像素数、缩略图位图等);3、APPn(其中n=1-15,数值0xE1-0XEF,其他应用数据块,包含本块长度与其他信息);4、量化表DQT;5、帧图像开始、6、霍夫曼表、7、扫描开始、8、扫描结束。
JPEG采用霍夫曼编码(后面可能会详细讲),因为是有损文件,所以重新保存下载会使图片质量下降(比如贴吧图被盗绿这种情况)。
TIFF格式包括三个部分:1、文件头(指出标识信息存储地址,解释所需必要信息);2、标识信息(包含了所有信息,具体和上面的头差不多);3、图像数据。
TIFF格式应用指针的功能,只规定文件头在文件最开始,其他都由指针决定,可分开存档、并定义了很多扩展,比较好用。

3. 图像的像素运算

3.1 点运算

点运算主要是对灰度图中(RGB图中不同通道)的灰度值(单个颜色的值)进行线性、非线性、分段改变,做加减法等操作,主要目的是突出想要的部分或者体现细节,图像对比度增强,通常用于图像的预处理。
matlab中操作很简单,就是对矩阵重新计算(点乘),用for循环嵌套if判断来分段,当然也可以用

imadjust()
直接计算(可以调gamma值,这个后面再讲)。
在python中也只是对矩阵中的元素来进行for循环遍历,或者用迭代器
iterator
也ok。具体代码比较简单,就不放啦。

3.2 代数运算

代数运算主要是加减乘除运算来得到输出图像的方法,需要注意的是图像的灰度阶数有限,不要产生属性溢出。
加法运算,在matlab中用

imadd()
实现,也可以用遍历的方法,能想到的作用就是自身重复叠加取均值来去随机噪声,其他后面再补;
减法运算,通常用来检测两幅图像之间的变化,是检测图像变化和对运动物体识别的重要办法,但通常放在三方包内,让人容易对这方面关注不够。在matlab中,通常用
imsubstract()

乘法运算,可以用作蒙版操作,或者乘常数改变图像亮度。在matlab中通常用
immulitply()

除法运算,常用于校正成像设备的非线性影响,在matlab中通常用
imdivide()

此外,还有一些matlab中的代数运算,如:
imabsdiff()
是求绝对值差的函数;
imcomplement()
是求补函数;
还有一些线性组合函数,等用到的时候再说吧= =。

3.3 逻辑运算

逻辑运算主要是针对二值图像,以像素对像素为基础进行的两幅或多幅图像间的操作。常用的有与或非,或非与非异或这些。在matlab中,可以对二值图像这样操作得到兴趣区域,之后再用原图蒙版,进行下一步操作(人脸识别等都可以这样搞,当然对于大多数领域早就有更成熟的技术了= =,这里只是讨论基础)。
在matlab中,与或非分别用

&
|
~
来表示,异或用
xor()
来表示。

在python-opencv中(python3.6),这些运算如下:

# 加
dst = cv2.Add(im, im2) #Add every pixels together (black is 0 so low change and white overload anyway)
cv2.inshow("Add", dst)

# 减
dst = cv2.AbsDiff(im, im2) # Like minus for each pixel im(i) - im2(i)
cv2.inshow("AbsDiff", dst)

# 乘
dst = cv2.Mul(im, im2) #Multiplie each pixels (almost white)
cv2.inshow("Mult", dst)

# 除
dst = cv2.Div(im, im2) #Values will be low so the image will likely to be almost black
cv2.inshow("Div", dst)

# 与
dst = cv2.And(im, im2) #Bit and for every pixels
cv2.inshow("And", dst)

# 或
dst = cv2.Or(im, im2) # Bit or for every pixels
cv2.inshow("Or", dst)

# 非
dst = cv2.Not(im) # Bit not of an image
cv2.inshow("Not", dst)

# 异或
dst = cv2.Xor(im, im2) #Bit Xor
cv2.inshow("Xor", dst)

一些其他的基础操作:

img = cv2.imread('image.jpg',0)
cv2.imshow('image',img)
k = cv2.waitKey(0)
if k == 27:         # wait for ESC key to exit
cv2.destroyAllWindows()
elif k == ord('s'): # wait for 's' key to save and exit
cv2.imwrite('image_gray.png',img)
cv2.destroyAllWindows()

获取图像属性,一般用

img.shape
,
img.size
,
img.dtype
来得到图像的形状,大小和元素类型。
顺便把python的两种遍历方法给出来,免得后面忘了= =
第一种是for in循环,第二种是iterator,如下:

#1
for i in range(im.height):
for j in range(im.width):
pass
#2
all_pixel = cv.InitLineIterator(im, (0, 0), (im.rows, im.cols))
for (r, g, b) in all_pixel:
pass #cv2中好像没有了

那大概就先这么多,后面再补啦,以上都只是我在学习过程中的一些记录、思考与猜测,肯定会有很多不对的地方,欢迎大家批评指正!

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐