玩轉Python圖片處理 (OpenCV-Python )
阿新 • • 發佈:2018-12-19
OpenCV是一個基於BSD許可(開源)發行的跨平臺計算機視覺庫,可以執行在Linux、Windows、Android和Mac OS作業系統上。它輕量級而且高效——由一系列 C 函式和少量 C++ 類構成,同時提供了Python、Ruby、MATLAB等語言的介面,實現了影象處理和計算機視覺方面的很多通用演算法。
OpenCV-Python是OpenCV的python的API介面,它擁有OpenCV C++ API的功能,同時也擁有Python語言的特性,可以做到跨平臺使用。
安裝:
sudo pip3 install opencv-python
直方圖模組安裝:
pip3 install matplotlib
簡單的讀取一張圖片:
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()
其它屬性詳細介紹:
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()#銷燬視窗
直方圖基本:
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()
樹莓派(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