1. 程式人生 > >OpenCV影象增強(python)

OpenCV影象增強(python)

為了得到更加清晰的影象我們需要通過技術對影象進行處理,比如使用對比度增強的方法來處理影象,對比度增強就是對影象輸出的灰度級放大到指定的程度,獲得影象質量的提升。本文主要通過程式碼的方式,通過OpenCV的內建函式將影象處理到我們理想的結果。 ###灰度直方圖### 灰度直方圖通過描述灰度級在影象矩陣中的畫素個數來展示影象灰度級的資訊,通過灰度直方圖的統計我們可以看到每個灰度值的佔有率。下面是一個灰度直方圖的實現: ``` import cv2 import numpy as np import sys import matplotlib.pyplot as plt #計算灰度直方圖 def calcGrayHist(image): rows,clos = image.shape #建立一個矩陣用於儲存灰度值 grahHist = np.zeros([256],np.uint64) print('這是初始化矩陣') print(grahHist ) for r in range(rows): for c in range(clos): #通過影象矩陣的遍歷來將灰度值資訊放入我們定義的矩陣中 grahHist[image[r][c]] +=1 print('這是賦值後的矩陣') print(grahHist) return grahHist if __name__=="__main__": image = cv2.imread("../img/aa.jpg",cv2.IMREAD_GRAYSCALE) grahHist = calcGrayHist(image) x_range = range(256) plt.plot(x_range,grahHist,'-',linewidth= 3,c='k') #設定座標軸的範圍 y_maxValue = np.max(grahHist) plt.axis([0,255,0,y_maxValue]) #設定標籤 plt.xlabel('gray Level') plt.ylabel("number of pixels") #顯示灰度直方圖 plt.show() ``` 執行結果 ![](https://img2020.cnblogs.com/blog/989555/202003/989555-20200307171031631-234859868.png) ![](https://img2020.cnblogs.com/blog/989555/202003/989555-20200307171131231-121563880.png) ###線性變換### 線性變換的公式為: $$ O(r,c)=a*I(r,c)+b,0\leq r255] = 255 #資料型別的轉換 O = np.round(O) O = O.astype(np.uint8) cv2.imshow("img",img) cv2.imshow('enhance',O) cv2.waitKey(0) cv2.destroyAllWindows() ``` 執行結果: ![](https://img2020.cnblogs.com/blog/989555/202003/989555-20200307175259544-1644710083.png) 灰度級範圍越大就代表對比度越高,反之對比度越低視覺上清晰度就越低。我們通過a=2的線性對比度拉伸將灰度級範圍擴大到[0,255]之間,如上圖我們改變灰度級的範圍後圖像變的清晰。 ###直方圖正規化### 將影象O中的最小灰度級記為$O_{min}$,最大灰度級記為$O_{max}$,假如輸出的影象P的灰度級範圍為[$P_{min},P_{max}$],則O 與 P的關係為: $$ O(r,c)=\cfrac{P_{max}-P_{min}}{O_{max}-O_{min}}(O(r,c)-O_{min})+P_{min}$$ 其中P(r,c)就代表P的第r行第c列的灰度值。這個過程就是直方圖的正規化。我們一般令P的範圍是[0,255],所以直方圖的正規化是在求a,b變換的值的方法,我們可以得到: $$ a=\cfrac{P_{max}-P_{min}}{O_{max}-O_{min}} , b=P_{min}-\cfrac{P_{max}-P_{min}}{O_{max}-O_{min}} *O_{min}$$ 下面我們使用OpenCV來實現上面的理論: ``` import cv2 import numpy as np import sys from enhance.GrayHist import mget if __name__=="__main__": img = cv2.imread("../img/o3.jpg",cv2.IMREAD_GRAYSCALE) #求出img 的最大最小值 Maximg = np.max(img) Minimg = np.min(img) print(Maximg, Minimg, '-----------') #輸出最小灰度級和最大灰度級 Omin,Omax = 0,255 #求 a, b a = float(Omax - Omin)/(Maximg - Minimg) b = Omin - a*Minimg print(a,b,'-----------') #線性變換 O = a*img + b O = O.astype(np.uint8) #利用灰度直方圖進行比較 mget為GrayHist中的寫方法 mget(img) mget(O) cv2.imshow('img',img) cv2.imshow('enhance',O) cv2.waitKey(0) cv2.destroyAllWindows() ``` ![](https://img2020.cnblogs.com/blog/989555/202003/989555-20200307190548030-1740133044.png) ![](https://img2020.cnblogs.com/blog/989555/202003/989555-20200307190622835-1858485442.png) ###伽瑪變換### 將一張圖的灰度值歸至[0,1]後,對於8點陣圖來說,除以255即可。伽瑪變換就是令O(r,c)=$I(r,c)^\gamma$,0$\leq r
=0: output[p] = np.math.floor(q) else: output[p] = 0 #得出均衡化影象 equalHistimg = np.zeros(image.shape,np.uint8) for r in range(rows): for c in range(cols): equalHistimg[r][c] = output[image[r][c]] cv2.imshow('image',image) cv2.imshow('histimage',equalHistimg) cv2.waitKey(0) cv2.destroyAllWindows() ``` 執行結果: ![](https://img2020.cnblogs.com/blog/989555/202003/989555-20200307194430499-20012984