【图像处理】——图像的灰度化处理(Python实现三种方法——最大值法、平均值法、加权均值法、gamma校正)
目錄
一、什么是圖像的灰度化?
二、灰度化的幾種方法(最大值法、平均值法、加權均值法、gamma校正)
1、直接調用函數:cv2.cvtColor() 圖像顏色空間轉換
2、最大值法
(1)概念
(2)代碼
(3)結果
3、平均值法
(1)概念
(2)“RuntimeWarning: overflow encountered in ubyte_scalars”問題的解決
(3)代碼
(4)結果
4、加權均值法
(1)概念
(2)代碼
(3)結果
5、gamma校正
(1)概念
(2)代碼
(3)結果
三、不同方法之間的比較
四、疑問:怎么利用Python創建一個空的初始化圖像?(np.unit8的應用)
1、關鍵代碼
?2、圖像展示
3、得到灰度圖像矩陣對比
4、利用opencv創建圖像參考代碼(彩色和灰色均有)
?
一、什么是圖像的灰度化?
首先我們知道一張圖片的所有顏色都可以通過RGB值調節進行表示,如果是一張彩色圖片則RBG值不一定相同,將彩色圖片灰度化就是指的是將彩色圖片變成黑白的,這時候的RBG三個通道的值是相同的,就是將一幅色彩圖像轉化為灰度圖像的過程。
彩色圖像分為R,G,B三個分量,分別顯示出紅綠藍等各種顏色,灰度化就是使彩色的R,G,B分量相等的過程。灰度值大的像素點比較亮(像素值最大為255,為白色),反之比較暗(像素最下為0,為黑色)這個過程就是指灰度化,具體可見:《百度百科》
對圖像灰度化便于后續對圖像的特征進行提取,以及得到圖像的灰度曲線圖
?
二、灰度化的幾種方法(最大值法、平均值法、加權均值法、gamma校正)
這里以上述經典圖片為例進行灰度化處理
1、直接調用函數:cv2.cvtColor() 圖像顏色空間轉換
img2 = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY) #灰度化:彩色圖像轉為灰度圖像img3 = cv2.cvtColor(img,cv2.COLOR_GRAY2RGB) #彩色化:灰度圖像轉為彩色圖像# cv2.COLOR_X2Y,其中X,Y = RGB, BGR, GRAY, HSV, YCrCb, XYZ, Lab, Luv, HLSopencv自帶的一個函數可以將彩色轉化為灰色,通過顏色空間的轉換來得到灰度化后的圖片
import cv2def gray_cvt(inputimagepath,windowname,outimagepath):img = cv2.imread(inputimagepath)gray_cvt_image = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)#灰度化cv2.namedWindow(windowname) # 這行沒啥用 控制顯示圖片窗口的名字cv2.imshow(windowname, gray_cvt_image)#顯示灰度化后的圖像cv2.imwrite(outimagepath, gray_cvt_image) # 保存當前灰度值處理過后的文件cv2.waitKey()#等待操作cv2.destroyAllWindows()#關閉顯示圖像的窗口def main():inputimagepath="colorful_lena.jpg"windowname='gray_cvt'outimagepath="gray_cvt.jpg"gray_cvt(inputimagepath,windowname,outimagepath)if __name__ == '__main__':main()返回的是一個(200,200)的圖像,是一個二維數組,這里的元素值就是B=G=R值
直接調用函數cv2.cvt2、最大值法
(1)概念
灰度化后的R,G,B得值等于轉化前3個值中最大的一個,即:
R=G=B=max(R,G,B)
(2)代碼
import cv2def gray_max_rgb(inputimagepath,windowname,outimagepath):img = cv2.imread(inputimagepath)#讀取圖像,返回的是一個裝有每一個像素點的bgr值的三維矩陣gray_max_rgb_image = img.copy()#復制圖像,用于后面保存灰度化后的圖像bgr值矩陣img_shape = img.shape#返回一位數組(高,寬,3)獲得原始圖像的長寬以及顏色通道數,一般彩色的顏色通道為3,黑白為1for i in range(img_shape[0]):#按行讀取圖片的像素bgrfor j in range(img_shape[1]):#對每一行按照列進行每一個像素格子進行讀取gray_max_rgb_image[i,j] = max(img[i,j][0],img[i,j][1],img[i,j][2])#求灰度值print(gray_max_rgb_image)cv2.namedWindow(windowname) #控制顯示圖片窗口的名字cv2.imshow(windowname, gray_max_rgb_image)#顯示灰度化后的圖像cv2.imwrite(outimagepath, gray_max_rgb_image) # 保存當前灰度值處理過后的文件cv2.waitKey()#等待操作cv2.destroyAllWindows()#關閉顯示圖像的窗口def main():inputimagepath = "colorful_lena.jpg"windowname = "gray_max_rgb"outimagepath = "gray_max_rgb.jpg"gray_max_rgb(inputimagepath,windowname,outimagepath)if __name__ == '__main__':main()(3)結果
返回的是一個三維矩陣,只是第三維比較特殊,三個元素都是一樣的,即R=B=G
print(gray_max_rgb_image)#取最后一維的第一組數據作為參考 最大值法3、平均值法
(1)概念
灰度化后R,G,B的值為轉化前R,G,B的平均值。即:
?R=G=B=(R+G+B)/3 ?
(2)“RuntimeWarning: overflow encountered in ubyte_scalars”問題的解決
這個表明像素值在進行加減操作后出現了像素值的溢出現象,即像素值的值為0-255,如果小于0或者大于255就會出現這種錯誤,這種情況也可以得到一個轉換后的圖像但是圖片卻失真了
? RuntimeWarning: overflow encountered in ubyte_scalars gray_mean_rgb_image[i,j] = (img[i,j][0]+img[i,j][1]+img[i,j][2])/3
解決這種方法就是在進行像素的加減操作前將像素進行強制取整操作即可
gray_mean_rgb_image[i,j] = (int(img[i,j][0])+int(img[i,j][1])+int(img[i,j][2]))/3(3)代碼
#平均值法進行圖像灰度化 import cv2def gray_mean_rgb(inputimagepath,windowname,outimagepath):img = cv2.imread(inputimagepath)gray_mean_rgb_image = img.copy()img_shape = img.shapefor i in range(img_shape[0]):for j in range(img_shape[1]):gray_mean_rgb_image[i,j] = (int(img[i,j][0])+int(img[i,j][1])+int(img[i,j][2]))/3print(gray_mean_rgb_image)cv2.namedWindow(windowname) #控制顯示圖片窗口的名字cv2.imshow(windowname, gray_mean_rgb_image)#顯示灰度化后的圖像cv2.imwrite(outimagepath, gray_mean_rgb_image) # 保存當前灰度值處理過后的文件cv2.waitKey()#等待操作cv2.destroyAllWindows()#關閉顯示圖像的窗口def main():inputimagepath = "colorful_lena.jpg"windowname = "gray_mean_rgb"outimagepath = "gray_mean_rgb.jpg"gray_mean_rgb(inputimagepath,windowname,outimagepath)if __name__ == '__main__':main()(4)結果
print(gray_mean_rgb_image)#取最后一維的第一組數據作為參考 平均值法?
4、加權均值法
(1)概念
灰度化后按照一定權值,對R,G,B的值加權平均,即:
分別為R,G,B的權值,取不同的值形成不同的灰度圖像。由于人眼對綠色最為敏感,紅色次之,對藍色的敏感性最低,因此使將得到較易識別的灰度圖像。一般時,得到的灰度圖像效果最好
注:一般權重有兩套值供選擇
Gray= 0.072169B+ 0.715160G+ 0.212671RGray= 0.11B+ 0.59G+ 0.3R前一種是OpenCV開放庫所采用的灰度權值,后一種為從人體生理學角度所提出的一種權值(人眼對綠色的敏感最高,對藍色敏感最低)?
(2)代碼
#加權均值法進行圖像灰度化 import cv2def gray_weightmean_rgb(wr,wg,wb,inputimagepath,windowname,outimagepath):img = cv2.imread(inputimagepath)gray_weightmean_rgb_image = img.copy()img_shape = img.shapefor i in range(img_shape[0]):for j in range(img_shape[1]):gray_weightmean_rgb_image[i,j] = (int(wr*img[i,j][2])+int(wg*img[i,j][1])+int(wb*img[i,j][0]))/3print(gray_weightmean_rgb_image)cv2.namedWindow(windowname) #控制顯示圖片窗口的名字cv2.imshow(windowname, gray_weightmean_rgb_image)#顯示灰度化后的圖像cv2.imwrite(outimagepath, gray_weightmean_rgb_image) # 保存當前灰度值處理過后的文件cv2.waitKey()#等待操作cv2.destroyAllWindows()#關閉顯示圖像的窗口def main():wr = 0.299wg = 0.587wb = 0.114inputimagepath = "colorful_lena.jpg"windowname = "gray_weightmean_rgb"outimagepath = "gray_weightmean_rgb.jpg"gray_weightmean_rgb(wr,wg,wb,inputimagepath,windowname,outimagepath)if __name__ == '__main__':main()(3)結果
print(gray_weightmean_rgb_image)#取最后一維的第一組數據作為參考 加權均值法5、gamma校正
(1)概念
(2)代碼
#gamma校正加權均值進行圖像灰度化 import cv2def gray_gamma_weightmean_rgb(wr,wg,wb,gamma,inputimagepath,windowname,outimagepath):img = cv2.imread(inputimagepath)gray_gamma_weightmean_rgb_image = img.copy()img_shape = img.shapefor i in range(img_shape[0]):for j in range(img_shape[1]):fenzi = int((wr*img[i,j][2])**gamma)+int((wg*img[i,j][1])**gamma)+int((wb*img[i,j][0])**gamma)fenmu = wr**gamma + wg**gamma + wb**gammagray_gamma_weightmean_rgb_image[i,j] = int((fenzi/fenmu)**(1/gamma))print(gray_gamma_weightmean_rgb_image)cv2.namedWindow(windowname) #控制顯示圖片窗口的名字cv2.imshow(windowname, gray_gamma_weightmean_rgb_image)#顯示灰度化后的圖像cv2.imwrite(outimagepath, gray_gamma_weightmean_rgb_image) # 保存當前灰度值處理過后的文件cv2.waitKey()#等待操作cv2.destroyAllWindows()#關閉顯示圖像的窗口def main():wr = 1wg = 1.5wb = 0.6gamma = 2.2inputimagepath = "colorful_lena.jpg"windowname = "gray_gamma_weightmean_rgb"outimagepath = "gray_gamma_weightmean_rgb.jpg"gray_gamma_weightmean_rgb(wr,wg,wb,gamma,inputimagepath,windowname,outimagepath)if __name__ == '__main__':main()(3)結果
print(gray_gamma_weightmean_rgb_image)#取最后一維的第一組數據作為參考 gamma修正法三、不同方法之間的比較
由上圖進行各個灰度化結果比較可以清晰的看出:
1、最大值法灰度化后圖像過于亮,丟失的圖像細節較多,常用于對原本色調較暗的圖像進行處理
2、加權平均值法灰度化后過于暗,不易于進行目標對象與背景區域的區分,常用于對原本色調較亮的圖像進行處理
3、直接調用函數進行灰度化顏色依舊偏暗
4、gamma修正灰度化的效果很好,但是gamma修正法的系數太多,而且設計到了指數以及開方運算,運算時間長,對于大量圖片的處理更是不適用,對設備的要求非常高
5、均值的效果跟gamma修正法差不多,可能不及gamma修正法,但是其方法計算便捷,且結果較佳
因此一般使用均值法進行圖片的灰度處理
四、疑問:怎么利用Python創建一個空的初始化圖像?(np.unit8的應用)
《如何利用numpy創建全0,全1,隨機矩陣》
??????? 在上述的灰度化中,灰度化后得到的圖像矩陣均為三維的矩陣,只是最后一維的3個元素是相同的,但是實際上灰色圖片的像素值矩陣只需要兩個維度就可以進行完全地表達,即只需要裝一個灰度值就可以了,這時候就可以通過numpy先創建一個合適尺寸的數組,然后將灰度化后的值去覆蓋定義的數組即可,注意一點:通過numpy創建數組后,必須要將生成數組的格式轉換為uint8(無符號8位整形)格式,否則應用cv2.imshow時圖像不能顯示,通過np.uint8來指定創建數組的元素的數據類型
gray_max_rgb_image = np.zeros((img_shape[0], img_shape[1]), np.uint8)?????? 這里以最大值法為例:
1、關鍵代碼
# gray_max_rgb_image = img.copy()#復制圖像,用于后面保存灰度化后的圖像bgr值矩陣img_shape = img.shape#返回一位數組(高,寬,3)獲得原始圖像的長寬以及顏色通道數,一般彩色的顏色通道為3,黑白為1gray_max_rgb_image = np.zeros((img_shape[0], img_shape[1]), np.uint8)#創建一個與原始圖像大小一致的圖像,初始值為0,即為黑色cv2.imshow('',gray_max_rgb_image)#這里得到的是一個與原始圖像一樣大小的黑色初始圖像for i in range(img_shape[0]):#按行讀取圖片的像素bgrfor j in range(img_shape[1]):#對每一行按照列進行每一個像素格子進行讀取gray_max_rgb_image[i,j] = max(img[i,j][0],img[i,j][1],img[i,j][2])#求灰度值cv2.imshow('',gray_max_rgb_image)#這里得到的是灰度化后的圖像?2、圖像展示
創建的圖像:
創建的圖像灰度化后的圖像:
最大值法3、得到灰度圖像矩陣對比
??????? 利用原始圖像的矩陣shape進行的灰度化的圖像矩陣,shape為(200,200,3),且可以看到最后一維三個數值是一樣的,即RGB值均相等。
????? 利用創建的數組進行灰度化的圖像矩陣,shape為(200,200),這里只保留了一個灰度值
4、利用opencv創建圖像參考代碼(彩色和灰色均有)
import cv2 as cv import numpy as npdef creat_image():'''#創建RGB圖像image = np.zeros([400,400,3],np.uint8) #初始圖片黑色#修改第一個通道的值image[:,:,0] = np.ones([400,400])*255 #輸出藍色的圖 第一通道是blue# 修改第二個通道的值image[:, :, 1] = np.ones([400, 400]) * 255cv.imshow("new_image",image)'''#創建單通道圖像 灰度圖像image = np.zeros([400, 400,1], np.uint8)image[:,:,0] = np.ones([400,400])*127cv.imshow("new_image", image)import cv2 as cv t1 = cv.getTickCount() #獲取時間 creat_image()t2 = cv.getTickCount() time = (t2-t1)/cv.getTickCount() print("time:%s ms"%(time*1000)) #花了多長時間 mS cv.waitKey(0) #釋放窗口 cv.destroyAllWindows()?
總結
以上是生活随笔為你收集整理的【图像处理】——图像的灰度化处理(Python实现三种方法——最大值法、平均值法、加权均值法、gamma校正)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【图像处理】——opencv常用函数
- 下一篇: 【图像处理】——Python实现图像加噪