玩轉Python圖片處理 (OpenCV-Python )

    OpenCV是一個基於BSD許可(開源)發行的跨平臺計算機視覺庫,能夠運行在Linux、Windows、Android和Mac OS操做系統上。它輕量級並且高效——由一系列 C 函數和少許 C++ 類構成,同時提供了Python、Ruby、MATLAB等語言的接口,實現了圖像處理和計算機視覺方面的不少通用算法。python

   OpenCV-Python是OpenCV的Python的API接口,它擁有OpenCV C++ API的功能,同時也擁有Python語言的特性,能夠作到跨平臺使用。但值得注意的是在Python3(目前使用的是Python3.7)裏對OpenCV-Python接口的中文支持並非很友好。算法

 

安裝:app

sudo pip3 install opencv-pythonide

直方圖模塊安裝:函數

pip3 install matplotlib字體

 

簡單的讀取一張圖片:ui

 1 import cv2 #導入opencv庫
 2 
 3 #讀取一張圖片,地址不能帶中文
 4 imgviewx=cv2.imread("imgx/zcy.jpg")
 5 
 6 #建立一個窗口,中文顯示會出亂碼
 7 cv2.namedWindow("東小東標題")
 8 
 9 #顯示圖片,參數:(窗口標識字符串,imread讀入的圖像)
10 cv2.imshow("東小東標題",imgviewx)
11 
12 #窗口等待任意鍵盤按鍵輸入,0爲一直等待,其餘數字爲毫秒數
13 cv2.waitKey(0)
14 
15 #銷燬窗口,退出程序
16 cv2.destroyAllWindows()

其它屬性詳細介紹:spa

  1 import cv2 #導入opencv庫
  2 import numpy as np
  3 
  4 #.........................................................................
  5 #讀取一張圖片,地址不能帶中文
  6 '''
  7 第二個參數,取值可爲:
  8 cv2.IMREAD_COLOR:默認參數,讀入一副彩色圖片,忽略alpha通道 
  9 cv2.IMREAD_GRAYSCALE:讀入灰度圖片 
 10 cv2.IMREAD_UNCHANGED:讀入完整圖片,包括alpha通道(png有,jpg無)
 11 '''
 12 #imgviewx=cv2.imread("imgx/wa.jpg")
 13 imgviewx=cv2.imread("imgx/DONG.jpg",cv2.IMREAD_COLOR)
 14 
 15 #.........................................................................
 16 #獲取圖片信息
 17 #一個像素有三個通道,BGR
 18 print(imgviewx.shape)#輸出:(1080, 1920, 3) 高像素,寬像素,通道數
 19 print(imgviewx.size)# 120000  總通道數=高* 寬* 通道數
 20 print(imgviewx.dtype)# uint8  3個通道每一個通道佔的位數(8位,一個字節)
 21 #print(imgviewx) #輸出效果視乎與下條相同
 22 #print(np.array(imgviewx)) #輸出每一個像素點的參數( B , G , R )
 23 #獲取圖片 B G R 各均值, #(204.46305102040816, 208.50832244897958, 217.29540408163263, 0.0) ,紅色部分最多
 24 print(cv2.mean(imgviewx))
 25 #獲取方差,也會打印均值,可用均值方差都爲零判斷圖片無效
 26 #print(cv2.meanStdDev(imgviewx))
 27 
 28 
 29 
 30 #.........................................................................
 31 #圖片處理
 32 #備份圖片
 33 imgviewx1=imgviewx.copy()
 34 
 35 #均值模糊,主要用於去除圖片噪點
 36 #讀取圖片並實現圖片的模糊效果,參數:(讀取圖片,(X軸方向模糊,Y軸方向模糊))
 37 #imgviewx=cv2.blur(imgviewx,(5,5))
 38 
 39 #中值模糊,主要用於去除椒鹽(燒烤配料)噪點
 40 #參數:(圖片信息,模糊值)
 41 #imgviewx=cv2.medianBlur(imgviewx,9)
 42 
 43 #普通高斯模糊
 44 #參數:(圖片信息,參數1,參數2)參數1和參數2只能設置一個
 45 #imgviewx=cv2.GaussianBlur(imgviewx,(0,0),1)
 46 
 47 #保留邊緣(像素差),高斯模糊
 48 #參數(圖片信息,0,要用怎樣的方式(越大則越細),空間複雜度(越大越複雜))
 49 imgviewx=cv2.bilateralFilter(imgviewx,0,50,6)
 50 
 51 
 52 #美顏,美白效果valuex值越大越白
 53 #valuex=50;
 54 #imgviewx=cv2.bilateralFilter(cv2.imread("imgx/zcy.jpg"),valuex,valuex * 2,valuex / 2)
 55 
 56 #對比度和亮度調整
 57 #duix=0.5 #對比度
 58 #lightx=0  #亮度
 59 #imgviewx=cv2.addWeighted(imgviewx,duix,np.zeros(imgviewx.shape,imgviewx.dtype),1-duix,lightx)
 60 
 61 
 62 
 63 #顯示文字
 64 # 參數:圖像,文字內容, 座標( x , y ) ,字體,大小,顏色( B , G ,R ),字體厚度
 65 #顏色值爲0-255
 66 font = cv2.FONT_HERSHEY_SIMPLEX  # 定義字體
 67 imgviewx = cv2.putText(imgviewx,"DONG XIAO DONG",(10, 50), font, 1.2, (0, 0, 255), 5)
 68 
 69 
 70 #像素取反
 71 #imgviewx=cv2.bitwise_not(imgviewx)
 72 
 73 
 74 
 75 #遍歷圖片,效率低,不推薦使用
 76 def xgtp():
 77    global imgviewx
 78    gx,kx,tx=imgviewx.shape#獲得像素高度,像素寬度,通道數
 79 
 80    for g in range(0,gx):
 81        for k in range(0,kx):  #這裏獲得的是每一個像素點,每一個點由RGB三色構成
 82            if(k>0 and k<100):
 83                imgviewx[g,k,0]=0       # B
 84                imgviewx[g,k,1]=255       #  G
 85                imgviewx[g,k,2]=255        #  R
 86            else:
 87                imgviewx[g, k, 0] = imgviewx[g, k, 0] #獲取到原來的值
 88                imgviewx[g, k, 1] = imgviewx[g, k, 1]
 89                imgviewx[g, k, 2] = imgviewx[g, k, 2]
 90 
 91 #建立一個圖形,使用np,因此效率高
 92 def cjtx():
 93     # 初始化像素點值全爲0 (rgb都爲零,因此是黑色)
 94     #參數:([高,寬,通道數],每一個通道佔的位數(一個字節))
 95     imgx=np.zeros([400,600,3],np.uint8)
 96 
 97     #初始化像素點值爲全爲1
 98     #imgx[110:130,50:70,2]表示一個範圍:[高度起始點:高度結束點,寬度起始點:寬度結束點,哪一個通道],起始點均以左上角
 99     #imgx[:,:,0]=np.ones([400,600],np.uint8)*255  #最終結果爲第一個通道(B)全爲255,因此是藍色
100     imgx[110:130,50:70,1]=np.ones([20,20],np.uint8)*255
101     cv2.imshow("第二個圖形窗口",imgx)
102 
103 #圖片區域處理
104 def pictureArea():
105     global imgviewx
106     #獲得截圖
107     areax=imgviewx[110:529,778:1200]
108     #將圖片由RGB(3通道)轉換爲灰度(2通道)
109     areax=cv2.cvtColor(areax,cv2.COLOR_BGR2GRAY)
110     #將圖片有2通道還原成3通道,但色彩不能還原
111     areax2=cv2.cvtColor(areax,cv2.COLOR_GRAY2RGB)
112     #處理後的區域寫到原圖上
113     imgviewx[110:529, 778:1200]=areax2
114     #顯示截圖
115     cv2.imshow("area",areax)
116 
117 #泛洪填充,類似像素填充
118 def fill_color():
119     global imgviewx
120     h,w,t=imgviewx.shape
121     #必要參數
122     maskx=np.zeros([h+2,w+2],np.uint8)
123     #參數接收:(圖片信息,必要參數,參考點位置座標,填充的顏色,查找範圍:最低像素(參考減所寫),查找範圍:最高像素(參考加所寫),所有填充)
124     cv2.floodFill(imgviewx,maskx,(100,100),(0,255,0),(100,100,100),(50,50,50),cv2.FLOODFILL_FIXED_RANGE)
125 
126 
127 
128 #通道分離與合併
129 def tongdao():
130     global imgviewx
131     b,g,r=cv2.split(imgviewx)#通道分離
132     cv2.imshow("bb",b)#通道圖單獨顯示
133     cv2.imshow("gg",g)
134     cv2.imshow("rr",r)
135 
136     imgviewx[:,:,1]=135 #改變單個通道(0,1,2 => B,G,R)
137     cv2.imshow("chang red ",imgviewx)
138 
139     imgviewx=cv2.merge([b,g,r])#合併通道
140 
141 #像素運算
142 def pixel_operation():
143     #讀入兩張大小和通道相同的圖片
144     img1=cv2.imread("imgx/img1.jpg")
145     img2=cv2.imread("imgx/img2.jpg")
146     print(img1.shape, "=====", img2.shape)
147     # 建立一個大小可調整的窗口
148     cv2.namedWindow("operation", cv2.WINDOW_NORMAL)
149     cv2.imshow("img111", img1)
150     cv2.imshow("img222",img2)
151     #處理圖片
152     #像素點相加,如0(黑色),255(白色),0+255=255(白色),超過255仍是白色
153     #imgoperation=cv2.add(img1,img2)
154     #像素相減,如0(黑色),255(白色),0-255=-255=0(黑色)
155     #imgoperation=cv2.subtract(img1,img2)
156     #像素相乘,255(白色),0/255=0(黑色)
157     #imgoperation=cv2.divide(img1,img2)
158     #像素相乘,255(白色),0*255=0(黑色)
159     #imgoperation=cv2.multiply(img2,img1)
160     #像素與,二進制與,如0與255爲00000000&11111111=00000000
161     imgoperation=cv2.bitwise_and(img1,img2)
162     #像素或
163     imgoperation=cv2.bitwise_or(img1,img2)
164 
165     #顯示處理後的圖片
166     cv2.imshow("operation", imgoperation)
167 
168 
169 
170 #.......................................................................
171 #視頻處理,視頻無聲音
172 def vediox():
173     ved=cv2.VideoCapture("imgx/vv.mp4")#打開視頻
174     while True:
175         ret,tux=ved.read()
176         if ret== False:#判斷視頻是否播放完畢
177             break
178         else:
179             cv2.imshow("wideo1111",tux)#每幀顯示
180             hsv=cv2.cvtColor(tux,cv2.COLOR_BGR2HSV)#轉換成HSV圖片格式,對顏色敏感
181             lowx=np.array([37,43,46])#表格在後面給出
182             uppx=np.array([77,255,255])
183             # 播放此輸出的目標是白色
184             tux2=cv2.inRange(hsv,lowx,uppx)#利用低指和高指匹配延時,所匹配的是綠色
185             #播放此輸出的目標是原色
186             tux3 = cv2.bitwise_and(tux,tux, mask=tux2)
187 
188             cv2.imshow("video222",tux3)
189 
190             if 27==cv2.waitKey(20):#按鍵退出播放
191                 break
192 
193 
194 #.........................................................................
195 #建立一個窗口,中文顯示會出亂碼,第一個參數爲窗口惟一標識字符串
196 #窗口大小可調整,默認參數爲c v2.WINDOW_AUTOSIZE 根據圖像大小自動建立大小
197 #可建多個
198 cv2.namedWindow("東小東標題",cv2.WINDOW_NORMAL)
199 
200 
201 #.........................................................................
202 #建立鼠標點擊事件回調函數,(事件,x軸位置,y軸位置,標記,屬性)
203 def drawxxx(event,x,y,flags,param):
204     if event==cv2.EVENT_LBUTTONDOWN:
205         print("鼠標按下",x,y)
206     #elif event==cv2.EVENT_MOUSEMOVE:
207        # print("鼠標滑動")
208     elif event==cv2.EVENT_LBUTTONUP:
209         print("鼠標擡起")
210 
211 #註冊鼠標監聽事件(窗口,回調函數)
212 cv2.setMouseCallback("東小東標題",drawxxx)
213 
214 #.........................................................................
215 t1=cv2.getTickCount()#利用cpu時間......
216 #xgtp()#調用圖片像素遍歷函數
217 #cjtx()#調用建立圖形函數
218 #vediox()#調用視頻處理函數
219 #tongdao()#通道處理
220 #pixel_operation()#像素點的加減乘除等處理
221 #pictureArea()#圖片區域處理
222 #fill_color()#泛洪填充,類似像素填充
223 t2=cv2.getTickCount()
224 timesx=(t2-t1)/cv2.getTickFrequency()
225 print("花費時間:%s 毫秒"%(timesx*1000))
226 
227 
228 #顯示圖片,參數:(窗口惟一標識字符串,imread讀入的圖像)
229 #能夠不基於窗口,可建多個
230 cv2.imshow("東小東標題",imgviewx)
231 
232 
233 #.........................................................................
234 #將圖片保存,寫入到文件
235 cv2.imwrite("2.jpg",imgviewx)
236 
237 
238 
239 #.........................................................................
240 #窗口退出
241 #窗口等待任意鍵盤按鍵輸入,0爲一直等待,其餘數字爲毫秒數
242 #等待時間到則返回-1,若有鍵盤按鍵按下則返回按鍵的ASCII碼
243 #可以使用print(cv2.waitKey(0))獲取該按鍵值
244 keyx=cv2.waitKey(0)
245 print(keyx)
246 if keyx==27:
247     print("你按下了鍵盤的:ESC鍵")
248 
249 #.........................................................................
250 #銷燬窗口,退出程序
251 cv2.destroyAllWindows()

模擬實現一個簡單的拍照程序:操作系統

 1 import cv2            #導入opencv庫
 2 import numpy as np
 3 
 4 #調用攝像頭
 5 def videox():
 6     vix=cv2.VideoCapture(0) #打開攝像頭
 7     while True:
 8         ret,tu=vix.read()    # ret爲返回值,tu爲當前幀
 9         tu1=cv2.flip(tu,1)   #圖像反轉,1爲左右對換,-1爲上下對換
10         cv2.imshow("東小東標題",tu1)  #顯示圖片在窗口上
11         if 65==cv2.waitKey(10):        #等待大寫 A 鍵盤按鍵按下
12             cv2.imwrite("DONG.jpg",tu1)#保存中止幀圖片
13             break
14 
15 cv2.namedWindow("東小東標題")#建立一個窗口,中文顯示會出亂碼問題
16 
17 videox()  #調用攝像頭函數
18 
19 print(cv2.waitKey(0))#等待任意鍵按下,並輸出該按鍵的值
20 
21 cv2.destroyAllWindows()#銷燬窗口

直方圖基本:code

 1 import cv2 #導入opencv庫
 2 import numpy
 3 #直方圖均衡化,對比度改變
 4 def equalization_rgb(imgtu):
 5     #只能使用灰度圖片
 6     imgx=cv2.cvtColor(imgtu,cv2.COLOR_RGB2GRAY)#轉換爲灰度
 7 
 8     #默認參數,自接使用
 9     #imgtu=cv2.equalizeHist(imgx)#均衡化
10 
11     #可修改參數clipLimit的值獲得不同效果
12     chanlx=cv2.createCLAHE(clipLimit=30.0,tileGridSize=(8,8))
13     imgtu=chanlx.apply(imgx)
14 
15     cv2.imshow("equalization",imgtu)#顯示
16 
17 
18 #直方圖比較,圖片類似度比較,遍歷像素點,速度慢慢
19 def create_compara(imgtu):
20     h,w,t=imgtu.shape
21     rgbx=numpy.zeros([16*16*16,1],numpy.float32)
22     bsize=256/16
23     for row in range(h):
24         for col in range(w):
25             b=imgtu[row,col,0]
26             g=imgtu[row,col,1]
27             r=imgtu[row,col,2]
28             index=numpy.int(b/bsize)*16*16+numpy.int(g/bsize)*16+numpy.int(r/bsize)
29             rgbx[numpy.int(index),0]=rgbx[numpy.int(index),0]+1
30     return rgbx
31 
32 def compare_ing():
33     img1=cv2.imread("imgx/xxG.png")
34     img2=cv2.imread("imgx/xxR.png")
35     hist1=create_compara(img1)
36     hist2=create_compara(img2)
37     cv2.imshow("img1111",img1)
38     cv2.imshow("img2222",img2)
39     va1=cv2.compareHist(hist1,hist2,cv2.HISTCMP_BHATTACHARYYA)
40     va2=cv2.compareHist(hist1,hist2,cv2.HISTCMP_CORREL)
41     va3=cv2.compareHist(hist1,hist2,cv2.HISTCMP_CHISQR)
42     print("巴氏距離,越小越類似(0,1):",va1)
43     print("相關性,越接近於1,越類似:",va2)
44     print("卡方,越小越類似:",va3)
45 
46 
47 #讀取一張圖片,地址不能帶中文
48 imgviewx=cv2.imread("imgx/zcy.jpg")
49 
50 #建立一個窗口,中文顯示會出亂碼
51 cv2.namedWindow("東小東標題")
52 
53 #顯示圖片,參數:(窗口標識字符串,imread讀入的圖像)
54 cv2.imshow("東小東標題",imgviewx)
55 
56 #------------------
57 #equalization_rgb(imgviewx)#直方圖均衡化,提升對比度
58 compare_ing()#直方圖比較,圖片類似度
59 
60 #-------------------
61 
62 #窗口等待任意鍵盤按鍵輸入,0爲一直等待,其餘數字爲毫秒數
63 cv2.waitKey(0)
64 
65 #銷燬窗口,退出程序
66 cv2.destroyAllWindows()

模板匹配:

 1 import cv2 #導入opencv庫
 2 
 3 #參數:(要尋找的目標,原圖片)
 4 def templatex(img_target,img_root):
 5 
 6     #模板匹配方法
 7     #toolx=cv2.TM_SQDIFF_NORMED
 8     toolx=cv2.TM_CCORR_NORMED
 9     #toolx=cv2.TM_CCOEFF_NORMED
10 
11     h,w=img_target.shape[:2]#獲取目標圖像的高和寬
12     #操做匹配
13     result=cv2.matchTemplate(img_root,img_target,toolx)
14     #獲得區域
15     min_x,max_x,min_y,max_y=cv2.minMaxLoc(result)
16 
17     #獲取起始點座標
18     if toolx==cv2.TM_SQDIFF_NORMED:
19         tl=min_y
20     else:
21         tl=max_y
22     #獲取結束點座標,其中tl[0]表示起始點x軸值,tl[1]表示y
23     br=(tl[0]+w,tl[1]+h)
24     #建立一個矩形框,參數(要寫到的圖片,起始點座標,結束點座標,顏色值,厚度)
25     cv2.rectangle(img_root,tl,br,(0,0,255),5)
26     #顯示圖片
27     cv2.imshow("img_rootxx",img_root)
28 
29 
30 
31 #讀取一張圖片,地址不能帶中文
32 imgviewx=cv2.imread("imgx/wa.jpg")
33 
34 #建立一個窗口,中文顯示會出亂碼
35 cv2.namedWindow("東小東標題",cv2.WINDOW_NORMAL)
36 
37 #獲取原圖片截圖
38 areax = imgviewx[110:529, 778:1200]
39 cv2.imshow("jjjttt",areax)
40 
41 templatex(areax,imgviewx)
42 
43 
44 #顯示圖片,參數:(窗口標識字符串,imread讀入的圖像)
45 cv2.imshow("東小東標題",imgviewx)
46 
47 #窗口等待任意鍵盤按鍵輸入,0爲一直等待,其餘數字爲毫秒數
48 cv2.waitKey(0)
49 
50 #銷燬窗口,退出程序
51 cv2.destroyAllWindows()

二值化,黑白圖片:

 1 import cv2 #導入opencv庫
 2 
 3 #讀取一張圖片,地址不能帶中文
 4 imgviewx=cv2.imread("imgx/wa.jpg")
 5 
 6 #建立一個窗口,中文顯示會出亂碼
 7 cv2.namedWindow("東小東標題")
 8 
 9 imgviewx2=imgviewx.copy()
10 #獲得灰度圖片
11 imgviewx2=cv2.cvtColor(imgviewx2,cv2.COLOR_BGR2GRAY)
12 #二值化圖像,黑白圖像,只有0和1,0爲0,1爲255
13 ret,imgviewx2=cv2.threshold(imgviewx2,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)
14 #二值化方法2
15 imgviewx2=cv2.adaptiveThreshold(imgviewx2,200,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,25,5)
16 
17 
18 #顯示圖片,參數:(窗口標識字符串,imread讀入的圖像)
19 cv2.imshow("img222222",imgviewx2)
20 cv2.imshow("東小東標題",imgviewx)
21 
22 #窗口等待任意鍵盤按鍵輸入,0爲一直等待,其餘數字爲毫秒數
23 cv2.waitKey(0)
24 
25 #銷燬窗口,退出程序
26 cv2.destroyAllWindows()

 


 附錄:

 

HSV取值對應表:

 

樹莓派(2018-06-27-raspbian-stretch.img)安裝須要的依賴包:

sudo apt-get install libatlas-base-dev

sudo apt-get install libjasper-runtime

sudo pip3 install opencv-contrib-python

sudo apt-get install libhdf5-dev

sudo apt-get install libhdf5-serial-dev

sudo apt install libqtgui4

sudo apt install libqt4-test

sudo apt-get install libcv-dev

相關文章
相關標籤/搜索