python 读取、保存、二值化、灰度化图片+opencv处理图片的方法

https://blog.csdn.net/johinieli/article/details/69389980

 

笔者小白在神经网络训练好然后进行手写数字的图片预测的时候碰到了这样的问题。

利用python如何读取、保存、二值化、灰度化图片呢?如何利用opencv来处理图片呢?

先说说处理图片有三种方式
一、matplotlib
二、PIL
三、opencv
下面来依次描述。

一、matplotlib
# 1、显示图片
import matplotlib.pyplot as plt #plt 用于显示图片
import matplotlib.image as mpimg #mpimg 用于读取图片
import numpy as np
lena = mpimg.imread('lena.png') #读取和代码处于同一目录下的lena.png
# 此时 lena 就已经是一个 np.array 了,可以对它进行任意处理
lena.shape #(512, 512, 3)
plt.imshow(lena) # 显示图片
plt.axis('off') # 不显示坐标轴
plt.show()
1
2
3
4
5
6
7
8
9
10
# 2、显示图片的第一个通道
lena_1 = lena[:,:,0]
plt.imshow('lena_1')
plt.show()

# 此时会发现显示的是热量图,不是我们预想的灰度图,可以添加 cmap 参数,有如下几种添加方法:
#方法一
plt.imshow('lena_1', cmap='Greys_r')
plt.show()

#方法二
img = plt.imshow('lena_1')
img.set_cmap('gray') # 'hot' 是热量图
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#3、将 RGB 转为灰度图
def rgb2gray(rgb):
return np.dot(rgb[...,:3], [0.299, 0.587, 0.114])

gray = rgb2gray(lena)
# 也可以用 plt.imshow(gray, cmap = plt.get_cmap('gray'))
plt.imshow(gray, cmap='Greys_r')
plt.axis('off')
plt.show()
1
2
3
4
5
6
7
8
9
#4、对图像进行放缩
from scipy import misc
lena_new_sz = misc.imresize(lena, 0.5) # 第二个参数如果是整数,则为百分比,如果是tuple,则为输出图像的尺寸
plt.imshow(lena_new_sz)
plt.axis('off')
plt.show()

附上imresize的用法
功能:改变图像的大小。
用法:
B = imresize(A,m)
B = imresize(A,m,method)
B = imresize(A,[mrows ncols],method)
B = imresize(...,method,n)
B = imresize(...,method,h)

imrersize函数使用由参数method指定的插值运算来改变图像的大小。
method的几种可选值:
'nearest'(默认值)最近邻插值
'bilinear'双线性插值
'bicubic'双三次插值
B = imresize(A,m)表示把图像A放大m倍
B = imresize(...,method,h)中的h可以是任意一个FIR滤波器(h通常由函数ftrans2、fwind1、fwind2、或fsamp2等生成的二维FIR滤波器)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#5、保存 matplotlib 画出的图像
plt.savefig('lena_new_sz.png')

#5、将 array 保存为图像
from scipy import misc
misc.imsave('lena_new_sz.png', lena_new_sz)

#5、直接保存 array
#读取之后还是可以按照前面显示数组的方法对图像进行显示,这种方法完全不会对图像质量造成损失
np.save('lena_new_sz', lena_new_sz) # 会在保存的名字后面自动加上.npy
img = np.load('lena_new_sz.npy') # 读取前面保存的数组
1
2
3
4
5
6
7
8
9
10
11
二、PIL
#1、显示图片
from PIL import Image
im = Image.open('lena.png')
im.show()
1
2
3
4
#2、将 PIL Image 图片转换为 numpy 数组
im_array = np.array(im)
# 也可以用 np.asarray(im) 区别是 np.array() 是深拷贝,np.asarray() 是浅拷贝
1
2
3
#3、保存 PIL 图片
#直接调用 Image 类的 save 方法

from PIL import Image
I = Image.open('lena.png')
I.save('new_lena.png')
1
2
3
4
5
6
#4、将 numpy 数组转换为 PIL 图片
#这里采用 matplotlib.image 读入图片数组,注意这里读入的数组是 float32 型的,范围是 0-1,而 PIL.Image 数据是 uinit8 型的,范围是0-255,所以要进行转换:
import matplotlib.image as mpimg
from PIL import Image
lena = mpimg.imread('lena.png') # 这里读入的数据是 float32 型的,范围是0-1
im = Image.fromarray(np.uinit8(lena*255))
im.show()
1
2
3
4
5
6
7
#5、RGB 转换为灰度图、二值化图
from PIL import Image
I = Image.open('lena.png')
I.show()
L = I.convert('L') #转化为灰度图
L = I.convert('1') #转化为二值化图
L.show()

附:PIL可以对图像的颜色进行转换,并支持诸如24位彩色、8位灰度图和二值图等模式,简单的转换可以通过Image.convert(mode)函数完 成,其中mode表示输出的颜色模式,例如''L''表示灰度,''1''表示二值图模式等。但是利用convert函数将灰度图转换为二值图时,是采用 固定的阈 值127来实现的,即灰度高于127的像素值为1,而灰度低于127的像素值为0。
1
2
3
4
5
6
7
8
9
三、opencv
首先需要安装opencv,接下来演示在windows平台下python安装opencv,即实现import cv2功能。

在官网:http://opencv.org/上找到OpenCV windows版下载下来。然后安装opencv,配置环境变量。这里就不多说了,请参考文献7。

这里是python安装opencv的步骤:
(1)在opencv的安装目录”
\opencv\build\python\2.7\x64”或”\opencv\build\python\2.7\x86”(根据python版本)文件夹中找到cv2.pyd;
(2)复制到Python安装目录的”\Python27\Lib\site-packages”文件夹中。
然后在python的环境下测试import cv2 是否成功导入就好了。

附上寻找python安装路径的方法:
在python的环境下键入
python -c “import os; print os.file”
就可以看到根目录的位置,这里可以参考文献8。

接下来开始描述如何利用opencv简单地处理图像

#1、读取图像,并把图像转换为灰度图像并显示
import cv2
im = imread("./image.jpg") #读取图片
im_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) #转换了灰度化
cv2.axis("off")
cv2.title("Input Image")
cv2.imshow(im_gray, cmap="gray") #显示图片
cv2.show()
1
2
3
4
5
6
7
8
#2、固定阈值二值化
retval, im_at_fixed = cv2.threshold(im_gray, 50, 255, cv2.THRESH_BINARY)
#将阈值设置为50,阈值类型为cv2.THRESH_BINARY,则灰度在大于50的像素其值将设置为255,其它像素设置为0
cv2.axis("off")
cv2.title("Fixed Thresholding")
cv2.imshow(im_at_fixed, cmap = 'gray')
cv2.show()

 

#附:固定阈值二值化处理利用cv2.threshold函数,此函数的原型为:
cv2.threshold(src, thresh, maxval, type[, dst]) -> retval, dst
其中:
1、src 为输入图像;
2、thresh 为阈值;
3、maxval 为输出图像的最大值;
4、type 为阈值的类型;
5、dst 为目标图像。


#附cv2.threshold函数的常用参数
1、cv2.THRESH_BINARY(黑白二值)
2、cv2.THRESH_BINARY_INV(黑白二值反转)
3、cv2.THRESH_TRUNC (得到的图像为多像素值)
4、cv2.THRESH_TOZERO
5、cv2.THRESH_TOZERO_INV
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#3、算术平法的自适应二值化
im_at_mean = cv2.adaptiveThreshold(im_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 10)
#上面我们将b设置为5,常数设置为10。
cv2.axis("off")
cv2.title("Adaptive Thresholding with mean weighted average")
cv2.imshow(im_at_mean, cmap = 'gray')
cv2.show()


#附:算术平均法的自适应二值化利用cv2.adaptiveThreshold实现,此函数的原型为:
cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]) -> dst
其中:
1、src 为输入图像;
2、maxval 为输出图像的最大值;
3、adaptiveMethod 设置为cv2.ADAPTIVE_THRESH_MEAN_C表示利用算术均值法,设置为cv2.ADAPTIVE_THRESH_GAUSSIAN_C表示用高斯权重均值法;
4、thresholdType: 阈值的类型;
5、blockSize: b的值;
6、C 为从均值中减去的常数,用于得到阈值;
7、dst 为目标图像。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#4、高斯加权均值法自适应二值化
im_at_mean = cv2.adaptiveThreshold(im_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 5, 7)
cv2.axis("off")
cv2.title("Adaptive Thresholding with gaussian weighted average")
cv2.imshow(im_at_mean, cmap = 'gray')
cv2.show()

 

#附:高斯加权均值法自适应二值化也是利用cv2.adaptiveThreshold, 此函数的原型与上述相同:
cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]) -> dst
其中:
1、src 为输入图像;
2、maxval 为输出图像的最大值;
3、adaptiveMethod 设置为cv2.ADAPTIVE_THRESH_MEAN_C表示利用算术均值法,设置为cv2.ADAPTIVE_THRESH_GAUSSIAN_C表示用高斯权重均值法;
4、thresholdType: 阈值的类型;
5、blockSize: b的值;
6、C 为从均值中减去的常数,用于得到阈值;
7、dst 为目标图像。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#5、保存图片
#直接用cv2.imwrite
import cv2
cv2.imwrite("./new_img.jpg", img)
cv2.imwrite("./new_img.jpg", img,[int(cv2.IMWRITE_JPEG_QUALITY), 5])
#第一个参数是保存的路径及文件名,第二个是图像矩阵。
#第三个参数针对特定的格式:
#对于JPEG,其表示的是图像的质量,用0-100的整数表示,默认为95。
#对于PNG,第三个参数表示的是压缩级别。cv2.IMWRITE_PNG_COMPRESSION,从0到9,压缩级别越高,图像尺寸越小。默认级别为3
#注意cv2.IMWRITE_JPEG_QUALITY类型为Long,必须转换成int。
1
2
3
4
5
6
7
8
9
10
#6、创建于复制图片
#如果要创建图像,需要使用numpy的函数
#创建空的图片
emptyImage = np.zeros(img.shape, np.uint8)

#复制原有的图片
emptyImage2 = img.copy();

#用cvtColor获得原图像的副本
emptyImage3=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#emptyImage3[...]=0
#后面的emptyImage3[...]=0是将其转成空白的黑色图像。
1
2
3
4
5
6
7
8
9
10
11
12
参考文献:
1、http://www.cnblogs.com/yinxiangnan-charles/p/5928689.html 2017.4.6
2、http://blog.csdn.net/colddie/article/details/7683492 2017.4.6
3、http://baike.baidu.com/link?url=OwMX6Isz30GnW7c7oouG3y48eYg6vhHMeHoiK9f38ZVNGeW8EOaH3fY-4k2k96dZZK8BZKd_O-Esl2tUgPFmPWonrv7WQjEDPcpCv_TPSJO 2017.4.6
4、http://blog.csdn.net/vange/article/details/5395771 2017.4.6
5、http://www.jb51.net/article/62315.htm 2017.4.6
6、http://blog.csdn.net/lyj_viviani/article/details/59482602 2017.4.6
7、http://blog.csdn.net/poem_qianmo/article/details/19809337/ 2017.4.6
8、http://www.jb51.net/article/65036.htm 2017.4.6
9、http://blog.csdn.net/deerlux/article/details/48477219 2017.4.6
10、http://www.mamicode.com/info-detail-907204.html 2017.4.6
11、http://blog.csdn.net/sunny2038/article/details/9057415 2017.4.6
————————————————
版权声明:本文为CSDN博主「JohnieLi」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/johinieli/article/details/69389980

posted @ 2021-12-16 12:33  了不起的奥特曼  阅读(3588)  评论(0编辑  收藏  举报