python 基于opencv實(shí)現(xiàn)圖像增強(qiáng)
為了得到更加清晰的圖像我們需要通過(guò)技術(shù)對(duì)圖像進(jìn)行處理,比如使用對(duì)比度增強(qiáng)的方法來(lái)處理圖像,對(duì)比度增強(qiáng)就是對(duì)圖像輸出的灰度級(jí)放大到指定的程度,獲得圖像質(zhì)量的提升。本文主要通過(guò)代碼的方式,通過(guò)OpenCV的內(nèi)置函數(shù)將圖像處理到我們理想的結(jié)果。
灰度直方圖
灰度直方圖通過(guò)描述灰度級(jí)在圖像矩陣中的像素個(gè)數(shù)來(lái)展示圖像灰度級(jí)的信息,通過(guò)灰度直方圖的統(tǒng)計(jì)我們可以看到每個(gè)灰度值的占有率。下面是一個(gè)灰度直方圖的實(shí)現(xiàn):
import cv2 import numpy as np import sys import matplotlib.pyplot as plt #計(jì)算灰度直方圖 def calcGrayHist(image): rows,clos = image.shape #創(chuàng)建一個(gè)矩陣用于存儲(chǔ)灰度值 grahHist = np.zeros([256],np.uint64) print('這是初始化矩陣') print(grahHist ) for r in range(rows): for c in range(clos): #通過(guò)圖像矩陣的遍歷來(lái)將灰度值信息放入我們定義的矩陣中 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') #設(shè)置坐標(biāo)軸的范圍 y_maxValue = np.max(grahHist) plt.axis([0,255,0,y_maxValue]) #設(shè)置標(biāo)簽 plt.xlabel('gray Level') plt.ylabel("number of pixels") #顯示灰度直方圖 plt.show()
運(yùn)行結(jié)果
線性變換
線性變換的公式為:
圖像的線性變換無(wú)疑就是利用矩陣的乘法就行線性變換,比如一個(gè)矩陣I ,2I,3I (np.unt8 ndarry類(lèi)型就是unt8類(lèi)型)就是一個(gè)矩陣的變換.
import cv2 import numpy as np import sys if __name__=="__main__": img = cv2.imread("../img/ae.jpg",cv2.IMREAD_GRAYSCALE) a=2 #線性變換 定義float類(lèi)型 O = float(a)*img #數(shù)據(jù)截取 如果大于255 取 255 O[0>255] = 255 #數(shù)據(jù)類(lèi)型的轉(zhuǎn)換 O = np.round(O) O = O.astype(np.uint8) cv2.imshow("img",img) cv2.imshow('enhance',O) cv2.waitKey(0) cv2.destroyAllWindows()
運(yùn)行結(jié)果:
灰度級(jí)范圍越大就代表對(duì)比度越高,反之對(duì)比度越低視覺(jué)上清晰度就越低。我們通過(guò)a=2的線性對(duì)比度拉伸將灰度級(jí)范圍擴(kuò)大到[0,255]之間,如上圖我們改變灰度級(jí)的范圍后圖像變的清晰。
直方圖正規(guī)化
將圖像O中的最小灰度級(jí)記為OminOmin,最大灰度級(jí)記為OmaxOmax,假如輸出的圖像P的灰度級(jí)范圍為[Pmin,PmaxPmin,Pmax],則O 與 P的關(guān)系為:
其中P(r,c)就代表P的第r行第c列的灰度值。這個(gè)過(guò)程就是直方圖的正規(guī)化。我們一般令P的范圍是[0,255],所以直方圖的正規(guī)化是在求a,b變換的值的方法,我們可以得到:
下面我們使用OpenCV來(lái)實(shí)現(xiàn)上面的理論:
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, '-----------') #輸出最小灰度級(jí)和最大灰度級(jí) 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) #利用灰度直方圖進(jìn)行比較 mget為GrayHist中的寫(xiě)方法 mget(img) mget(O) cv2.imshow('img',img) cv2.imshow('enhance',O) cv2.waitKey(0) cv2.destroyAllWindows()
伽瑪變換
將一張圖的灰度值歸至[0,1]后,對(duì)于8位圖來(lái)說(shuō),除以255即可。伽瑪變換就是令O(r,c)=I(r,c)γI(r,c)γ,0≤r<H,0≤≤r<H,0≤c<W.
當(dāng)γγ等于1時(shí)圖像不發(fā)生變換,而當(dāng)γγ大于0且小于1時(shí)就可以增強(qiáng)圖像的對(duì)比度,相反的當(dāng)γγ大于1時(shí)就可以使圖像對(duì)比度降低。 以下是伽瑪變換在OpenCV中的實(shí)現(xiàn):
import cv2 import numpy as np import sys # 伽瑪變換 power函數(shù)實(shí)現(xiàn)冪函數(shù) if __name__ == "__main__": img = cv2.imread("../img/ae.jpg", cv2.IMREAD_GRAYSCALE) # 歸1 Cimg = img / 255 # 伽瑪變換 gamma = 0.5 O = np.power(Cimg,gamma) #效果 cv2.imshow('img',img) cv2.imshow('O',O) cv2.waitKey(0) cv2.destroyAllWindows()
運(yùn)行結(jié)果:
直方圖的均衡化
- 計(jì)算圖像的灰度直方圖
- 計(jì)算灰度直方圖的累加直方圖
- 根據(jù)累加的直方圖和直方圖均衡化的原理得到輸入灰度級(jí)與輸出灰度級(jí)之間的映射關(guān)系
- 使用循環(huán)的方式得到輸出圖像的每一個(gè)像素的灰度級(jí)
import cv2 import numpy as np from enhance.GrayHist import calcGrayHist #直方圖的均衡化 if __name__ == "__main__": image = cv2.imread("../img/ae.jpg", cv2.IMREAD_GRAYSCALE) rows,cols = image.shape #計(jì)算灰度直方圖 grayHist = calcGrayHist(image) #計(jì)算累加灰度直方圖 zeroCumuMoment = np.zeros([256], np.uint32) for p in range(256): if p == 0: zeroCumuMoment[p] = grayHist[0] else: zeroCumuMoment[p] = zeroCumuMoment[p-1] + grayHist[p] #根據(jù)累加的灰度直方圖得到輸入與輸出灰度級(jí)之間的映射關(guān)系 output = np.zeros([256],np.uint8) cofficient = 256.0/(rows*cols) for p in range(256): q = cofficient * float(zeroCumuMoment[p])-1 if q >=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()
運(yùn)行結(jié)果:
以上就是python 基于opencv實(shí)現(xiàn)圖像增強(qiáng)的詳細(xì)內(nèi)容,更多關(guān)于python opencv的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python跨文件調(diào)用函數(shù)以及在一個(gè)文件中執(zhí)行另一個(gè)文件
這篇文章主要給大家介紹了關(guān)于Python跨文件調(diào)用函數(shù)以及在一個(gè)文件中執(zhí)行另一個(gè)文件的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-12-12使用python list 查找所有匹配元素的位置實(shí)例
今天小編就為大家分享一篇使用python list 查找所有匹配元素的位置實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06Python SQLAlchemy簡(jiǎn)介及基本用法
SQLAlchemy是一個(gè)基于Python實(shí)現(xiàn)的ORM對(duì)象關(guān)系映射框架,該框架建立在DB API之上,使用關(guān)系對(duì)象映射進(jìn)行數(shù)據(jù)庫(kù)操作,這篇文章主要介紹了SQLAlchemy簡(jiǎn)介以及基本使用,需要的朋友可以參考下2023-08-08Python+OpenCV實(shí)現(xiàn)黑白老照片上色功能
我們都知道,有很多經(jīng)典的老照片,受限于那個(gè)時(shí)代的技術(shù),只能以黑白的形式傳世。盡管黑白照片別有一番風(fēng)味,但是彩色照片有時(shí)候能給人更強(qiáng)的代入感。本文就來(lái)用Python和OpenCV實(shí)現(xiàn)老照片上色功能,需要的可以參考一下2023-02-02Python使用FastApi發(fā)送Post請(qǐng)求的基本步驟
FastAPI 是一個(gè)現(xiàn)代、快速(高性能)的 Web 框架,用于構(gòu)建 API,它基于 Python 3.6 及以上版本,在 FastAPI 中發(fā)送 POST 請(qǐng)求,通常是指創(chuàng)建一個(gè)接口來(lái)接收客戶端發(fā)送的 POST 請(qǐng)求,以下是使用 FastAPI 處理 POST 請(qǐng)求的基本步驟,需要的朋友可以參考下2024-09-09Python答題卡識(shí)別并給出分?jǐn)?shù)的實(shí)現(xiàn)代碼
本文帶領(lǐng)大家學(xué)習(xí)Python答題卡識(shí)別并給出分?jǐn)?shù)的實(shí)現(xiàn)代碼,代碼實(shí)現(xiàn)思路清晰,簡(jiǎn)單易懂,Python識(shí)別答題卡相關(guān)知識(shí)感興趣的朋友一起看看吧2021-06-06