python之數(shù)字圖像處理方式
基本概念
- 數(shù)字圖像定義
對于一幅圖像,我們可以將其放入坐標系中,這里取圖像左上定點為坐標原點,x 軸向右,和笛卡爾坐標系x軸相同;y 軸向下,和笛卡爾坐標系y軸相反。
這樣我們可將一幅圖像定義為一個二維函數(shù) f(x,y),圖像中的每個像素就可以用 (x,y) 坐標表示,而在任何一對空間坐標 (x,y) 處的幅值 f 稱為圖像在該點的強度或灰度,當 x,y 和灰度值 f 是有限離散數(shù)值時,便稱該圖像為 數(shù)字圖像
注:f的取值為區(qū)間[Lmin,Lmax],也將其稱為圖像的灰度級,實際情況下常常令該區(qū)間為[0,L-1],其中f=0時為黑色,f=1時在灰度級中為白色,所有中間值是從黑色到白色之間變化的灰度色調(diào),而圖像最高和最低灰度級之間的灰度差便為對比度
注:圖像亮度、對比度、飽和度和銳化之間并不是彼此獨立的,改變其中一個特征可能會同時引起圖像其他特征的變化,至于變化的程度取決于圖像本身的特性。
- 亮度
圖像亮度通俗理解便是圖像的明暗程度,如果灰度值在[0,255]之間,則 f 值越接近0亮度越低,f 值越接近255亮度越高。
- 對比度
指的是圖像暗和亮的落差值,即圖像最大灰度級和最小灰度級之間的差值
- 飽和度
飽和度指的是圖像顏色種類的多少, 上面提到圖像的灰度級是[Lmin,Lmax],則在Lmin、Lmax 的中間值越多,便代表圖像的顏色種類多,飽和度也就更高,外觀上看起來圖像會更鮮艷,調(diào)整飽和度可以修正過度曝光或者未充分曝光的圖片。使圖像看上去更加自然
- 銳化
圖像銳化是補償圖像的輪廓,增強圖像的邊緣及灰度跳變的部分,使圖像變得清晰。圖像銳化在實際圖像處理中經(jīng)常用到,因為在做圖像平滑,圖像濾波處理的時候經(jīng)過會把丟失圖像的邊緣信息,通過圖像銳化便能夠增強突出圖像的邊緣、輪廓
- 分辨率
就是每英寸圖像內(nèi)有多少個像素點
圖像增強
概述:主要分為空間域增強和頻率域增強,本文主要介紹空間域增強方法:也就是直接對圖片像素進行處理。
整體代碼
import math import cv2 import numpy as np import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['FangSong'] # 設置字體以便正確顯示漢字 plt.rcParams['axes.unicode_minus'] = False # 正確顯示連字符 MEDTH_ID=8 # 計算圖片清晰度 def getImageVar(img): img2gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 轉(zhuǎn)化成灰度圖 # 對圖片用 3x3 拉普拉斯算子做卷積得到邊緣 計算出方差,并最后返回。 # 函數(shù)求完導數(shù)后會有負值,還有會大于255的值。而原圖像是uint8,即8位無符號數(shù),所以建立的圖像位數(shù)不夠,會有截斷。因此要使用64位有符號的數(shù)據(jù)類型,即 cv2.CV_64F。 # 再用var函數(shù)求方差 imageVar = cv2.Laplacian(img2gray, cv2.CV_64F).var() return imageVar # 轉(zhuǎn)接器 def handle(idx, img): if idx == 1: return handle_specific(img, linear) # 線性變化 if idx == 2: return handle_specific(img, linear_up) # 分段線性變化 if idx == 3: return handle_specific(img, Logarithmic) # 對數(shù)變換 if idx == 4: return handle_specific(img, power) # 冪指變換 if idx == 5: return handle_specific(img, cv2.equalizeHist) # 直方圖均衡化 if idx == 6: return handle_specific(img, auto_equalizeHist) # 自適應直方圖均衡化 if idx == 7: return handle_specific(img, laplacian) # laplacian算子圖像銳化 if idx == 8: return handle_specific(img, non_sharpening) # 非銳化掩蔽 # 處理函數(shù) def handle_specific(img, func): img_list = [func(i) for i in cv2.split(img)] result = cv2.merge((img_list[0], img_list[1], img_list[2])) return result # 線性變化 def linear(img): a, b = 1.5, 0 for i in range(img.shape[0]): for j in range(img.shape[1]): if img[i][j] * a + b > 255: img[i][j] = 255 else: img[i][j] = img[i][j] * a + b return img # 分段線性變換-線性對比度拉伸,增強感興趣區(qū)域 def linear_up(img): # 灰度值的最大最小值 r_min, r_max = 255, 0 for i in range(img.shape[0]): for j in range(img.shape[1]): if img[i, j] > r_max: r_max = img[i, j] if img[i, j] < r_min: r_min = img[i, j] r1, s1 = r_min, 0 r2, s2 = r_max, 255 k = (s2 - s1) / (r2 - r1) for i in range(img.shape[0]): for j in range(img.shape[1]): if r1 <= img[i, j] <= r2: img[i, j] = k * (img[i, j] - r1) return img # 對數(shù)變換 def Logarithmic(img): for i in range(img.shape[0]): for j in range(img.shape[1]): img[i][j] = math.log(1+img[i][j]) cv2.normalize(img, img, 0, 255, cv2.NORM_MINMAX) img = cv2.convertScaleAbs(img) return img # 對數(shù)變換 def power(img): for i in range(img.shape[0]): for j in range(img.shape[1]): img[i][j] = math.pow(img[i][j],1.2) cv2.normalize(img, img, 0, 255, cv2.NORM_MINMAX) img = cv2.convertScaleAbs(img) return img # 自適應的直方圖均衡化-非線性的對比度拉伸,增強感興趣區(qū)域 def auto_equalizeHist(img): clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) img = clahe.apply(img) return img def laplacian(img): kernel = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]]) # laplacian卷積核的一個模板 lapkernel_img = cv2.filter2D(img, -1, kernel) # 做卷積 img = img - lapkernel_img return img def non_sharpening(img): blur_img = cv2.blur(img, (5, 5)) mask_img = img - blur_img img = img + mask_img return img img = cv2.imread(filename='img/CB.61.20211203152034_crop_0.jpg', flags=1) result = handle(MEDTH_ID, img) print('原圖的清晰度:', getImageVar(img)) print('處理之后的清晰度', getImageVar(result)) fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100) axes[0].imshow(img) axes[0].set_title("原圖") axes[1].imshow(result) axes[1].set_title("處理之后的圖片") plt.show()
線性變換
- 用處
線性變換主要可以對圖像的對比度和亮度進行調(diào)整(但是比較暴力),線性變換公式如下: f ( x , y ) = f ( x , y ) ∗ a + b f(x,y)=f(x,y)*a+b f(x,y)=f(x,y)∗a+b,參數(shù) a 影響圖像的對比度,參數(shù) b 影響圖像的亮度,具體分為可分為以下幾種情況:
- a>1:增強圖像的對比度,圖像看起來更加清晰
- a<1: 減小了圖像的對比度, 圖像看起來變暗,
- b>0:增加圖像的亮度,圖像變亮,
- b<0:減少圖像的亮度,圖像變暗
- a=-1 and b=255:圖像翻轉(zhuǎn)
a=1.5,b=0的結(jié)果:
分段線性變換
- 對比度拉伸
將原圖的灰度范圍限制為自定義范圍,增強感興趣區(qū)域。如將原來的 [ l m i n , l m a x ] [l_{min},l_{max}] [lmin?,lmax?]拉到 [ 0 , 255 ] [0,255] [0,255]
- 閾值處理
得到二值圖,按照門限將灰度值變?yōu)?或者255
- 灰度級分層
為了在數(shù)字圖像中突出我們感興趣的灰度級區(qū)域 [A,B],在實際情況下可以有兩種處理方式。
突出灰度范圍在 [A,B] 的區(qū)域,將其他區(qū)域灰度級降低到一個更低的級別突出灰度范圍在 [A,B] 的區(qū)域,其他區(qū)域保持原灰度級不變
對比度拉伸結(jié)果:
對數(shù)變換
- 用處
對數(shù)變換將圖像的低灰度值部分擴展,將其高灰度值部分壓縮,以達到強調(diào)圖像低灰度部分的目的;同時可以很好的壓縮像素值變化較大的圖像的動態(tài)范圍,目的是突出我們需要的細節(jié)。
反對數(shù)變換則與對數(shù)函數(shù)不同的是,強調(diào)的是圖像的高灰度部分。
結(jié)果:
冪律變換
- 用處
冪律變換主要用于圖像的校正,對漂白的圖片或者是過黑的圖片進行修正,根據(jù) φ 的大小,主要可分為一下兩種情況:
- φ > 1: 處理漂白的圖片,進行灰度級壓縮
- φ < 1: 處理過黑的圖片,對比度增強,使得細節(jié)看的更加清楚
直方圖
- 用處
對比度較低的圖像適合使用直方圖均衡化方法來增強圖像細節(jié)
直方圖均衡化結(jié)果:
自適應直方圖均衡化結(jié)果:
圖像濾波
平滑圖像
通過模糊圖像達到圖像降噪的目的,但同時存在一個問題就是會使得圖像的邊緣被淡化。
銳化圖像
主要目的是突出灰度的過渡部分,即突出圖像的邊緣(銳化空間濾波)
圖像銳化濾波中圖像平滑是一個積分的過程,圖像銳化便是通過圖像微分增強邊緣和其他突變,削弱灰度變換緩慢的區(qū)域。
- laplacian算子
其強調(diào)的是圖像中灰度的變換,忽視圖像灰度變換緩慢的區(qū)域。
因此我們通過laplacian算子得出的是圖像更多的是邊緣線,因此,我們可以將原圖和拉普拉斯圖像疊加在一起,可以復原背景特性并且保持拉普拉斯銳化處理的效果。
- 用處
可以增強局部的圖像對比度
結(jié)果:
- 非銳化掩蔽
非銳化掩蔽的思路便是應原圖像減去平滑的圖像,這樣便得到強調(diào)邊緣的圖像,然后再和原圖像相加,便達到強調(diào)圖像邊緣的效果,具體步驟如下:
- 模糊原圖像
- 從原圖像減去模糊圖像(產(chǎn)生的差值圖像稱為模板)
- 將模板和原圖像相加
結(jié)果:
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Pandas數(shù)值排序 sort_values()的使用
本文主要介紹了Pandas數(shù)值排序 sort_values()的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-07-07python利用hook技術(shù)破解https的實例代碼
python利用hook技術(shù)破解https的實例代碼,需要的朋友可以參考一下2013-03-03