圖像加強目的使得模糊圖片變得更加清晰、圖片模糊的緣由是由於像素灰度差值變化不大,圖片各區域產生視覺效果彷佛都是同樣的, 沒有較爲突出的地方,看起來不清晰的感受web
解決這個問題的最直接簡單辦法,放大像素灰度值差值、使圖像中的細節更加清晰。數組
目前較爲經常使用的幾個方法:伽馬變換、線性變換、分段線性變換、直方圖均衡化,對於圖像對比度加強,都能取得不錯的效果!微信
本文將對每種方法 簡單介紹一下,並藉助於 Python 、OpenCV 進行代碼實現,提早說一下哈,下面處理的圖像對象都是單通道灰度圖,不是三通道彩色圖!函數
1,線性變換
線性變換的原理是對全部像素值乘上一個擴張因子 ,像素值大的變得越大,像素值小的變得越小,從而達到圖像加強的效果,這裏利用 Numpy 的數組進行操做;
ui
須要注意的是,像素值最大爲255,所以在數組相乘以後須要進行數值截斷操做,最終代碼以下:this
def line_trans_img(img,coffient):
if len(img.shape) == 3:
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
out = 2*img
#像素截斷;;;
out[out>255] = 255
out = np.around(out)
return out
這裏 設置爲 2 ,變換結果以下,會看到強光處出現失真效果spa
![line.png](http://static.javashuo.com/static/loading.gif)
(這裏對排列圖片作一下說明,從左到右依次爲 原圖灰度圖、原圖灰度直方圖、處理以後的灰度圖、處理以後的灰度直方圖,如下的圖片排列方式相同).net
2,伽馬變換
伽馬變換對像素值作的是冪次方變換,主要是圖像的灰度級發生改變,轉換的原理公式爲:
參數 的設定 能夠參照下面:3d
![Snipaste_2020-05-26_20-18-17.png](http://static.javashuo.com/static/loading.gif)
當>1 時,會減少灰度級較高的地方,增大灰度級較低的地方;code
當 <1 時,會增大灰度級較高的地方,減少灰度級較低的地方;
def gama_transfer(img,power1):
if len(img.shape) == 3:
img= cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
img = 255*np.power(img/255,power1)
img = np.around(img)
img[img>255] = 255
out_img = img.astype(np.uint8)
return out_img
這裏 Gamma 分別取 1.5,0.5,結果以下:
![gamma1.5.png](http://static.javashuo.com/static/loading.gif)
![gamma0.5.png](http://static.javashuo.com/static/loading.gif)
結果來看,相對來講 對圖像加強的結果會更好一點
3,分段線性分割
分段線性分割,提早把圖像的灰度級分爲幾部分,而後對每一部分的像素值作不一樣的線性變換,像素值基本變換原理:
這裏寫的代碼總感受效率特別慢(逐像素改變),知道改進方法的小夥伴們望告知:
def seg_augment_img(img,start,c1,end,c2,b2,c3,b3):
if len(img.shape) == 3:
img= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
out_img = np.zeros(img.shape)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
if img[i][j] <start:
out_img[i][j] = img[i][j]*c1
elif img[i][j] < end:
out_img[i][j] = img[i][j] *c2 + b2
else:
out_img[i][j] = img[i][j] * c3 +b3
out_img[out_img>255] = 255
out = np.around(out_img)
out = out.astype(np.uint8)
return out
函數中的參數分別爲 50,0.5,150,3.6,-310,0.238,194,結果以下:
![seg_line.png](http://static.javashuo.com/static/loading.gif)
4,直方圖均衡化
每一個灰度圖像都有本身的灰度直方圖,均衡化的原理是,先根據灰度直方圖計算累加灰度直方圖,根據灰度圖與累加灰度圖的映射關係關聯輸入圖像與輸出圖圖像的映射關係
映射關係原理以下:
所以,這裏幾個重要部分:1,計算出灰度直方圖;2,計算累加灰度直方圖;3,根據 1 和 2 獲得映射關係,最終輸出灰度像素值;
def get_imghist(img):
# 判斷圖像是否爲三通道;
if len(img.shape) == 3:
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 無 Mask,256個bins,取值範圍爲[0,255]
hist = cv2.calcHist([img],[0],None,[256],[0,255])
return hist
def cal_equalhist(img):
if len(img.shape) == 3:
img= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
h,w = img.shape[:2]
grathist = get_imghist(img)
zerosumMoment = np.zeros([256],np.uint32)
for p in range(256):
if p ==0:
zerosumMoment[p] = grathist[0]
else:
zerosumMoment[p] = zerosumMoment[p-1] +grathist[p]
output_q = np.zeros([256],np.uint8)
cofficient = 256.0/(h*w)
for p in range(256):
q = cofficient *float(zerosumMoment[p]) - 1
if q >= 0:
output_q[p] = math.floor(q)
else:
output_q[p] = 0
equalhistimage = np.zeros(img.shape,np.uint8)
for i in range(h):
for j in range(w):
equalhistimage[i][j] = output_q[img[i][j]]
# 第二種方法,opencv 庫函數自帶一種:
#equalhistimage = cv2.equalizeHist(img)
return equalhistimage
結果以下,看起來仍是不錯的!(這裏圖片失真是由於燈光的緣由)
![equalhist.png](http://static.javashuo.com/static/loading.gif)
5,小總結
根據以上幾個加強方法來看,針對於本案例選取的圖像,線性加強方法相對效果並不太好,可能會適用於其它的種類圖像,而 Gamma轉換 和直方圖均衡化取得相對不錯的結果
但圖像加強、銳化沒有最優方法,每種方法都有本身的特色,須要根據本身選擇合適的
最後仍是要提醒一下感興趣的小夥伴們,記得跟着敲一下代碼,加深一下應用原理!
推薦閱讀
本文分享自微信公衆號 - Z先生點記(gh_683d048a482a)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。