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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM