數(shù)字圖像增強(qiáng)
亮度與對(duì)比度轉(zhuǎn)換
圖像變換可分為以下兩種:
- 點(diǎn)算子:基于像素變換,在這一類圖像變換中,僅僅根據(jù)輸入像素值計(jì)算相應(yīng)的輸出像素值
- 鄰域算子:基于圖像區(qū)域進(jìn)行變換
兩種常用的點(diǎn)算子是用常數(shù)對(duì)點(diǎn)的像素值進(jìn)行乘法或加法運(yùn)算,可以表示為:
g ( i , j ) = α ? f ( i , j ) + β g(i, j) = \alpha * f(i, j) + \beta g(i,j)=α?f(i,j)+β
其中,圖像中點(diǎn)的位置為
(
i
,
j
)
(i, j)
(i,j),α
值代表增益,β
值代表偏置。對(duì)圖像進(jìn)行亮度和對(duì)比度的變換就是一種點(diǎn)算子,這兩個(gè)參數(shù)分別可以用來控制對(duì)比度與亮度??梢酝ㄟ^調(diào)節(jié)這兩個(gè)參數(shù)的值,來對(duì)圖片進(jìn)行對(duì)比度或亮度的調(diào)節(jié)。即將原圖像中的每一個(gè)像素點(diǎn)都加上一個(gè)偏置常數(shù),則可以使圖片的亮度變大。類似地,將原圖片中的像素點(diǎn)乘上一個(gè)增益系數(shù),可以調(diào)整圖片的對(duì)比度。
注意
圖片像素點(diǎn)的像素值取值范圍是[0,255],一定不要讓其溢出,可以使用
np.clip
進(jìn)行截?cái)?/p>
示例圖像:
import cv2
import numpy as np
# 方法1: 基于addWeighted()函數(shù)實(shí)現(xiàn)
def convert_img1(img, alpha, beta):
blank = np.zeros(img.shape, img.dtype)
return cv2.addWeighted(img, alpha, blank, 0, beta)
# 方法2: 通過for循環(huán)手動(dòng)實(shí)現(xiàn)
def convert_img2(img, alpha, beta):
rows, cols, chs = img.shape
new_img = np.zeros(img.shape, img.dtype)
for i in range(rows):
for j in range(cols):
for k in range(chs):
new_img[i, j, k] = np.clip(alpha * img[i, j, k] + beta, 0, 255)
return new_img
img = cv2.imread('woman.png')
cv2.imwrite('convert_img1.jpg', convert_img1(img, 2.2, 50))
cv2.imwrite('convert_img2.jpg', convert_img2(img, 2.2, 50))
在上述代碼中,函數(shù)convert_img1()
中的addWeighted()
函數(shù)的參數(shù)列表分別為:[img1,alpha,img2,beta,gamma]
,代表將兩個(gè)圖片進(jìn)行如下計(jì)算:
n e w _ i m g = a l p h a ? i m g 1 + b e t a ? i m g 2 + g a m m a new\_img = alpha * img1 + beta * img2 + gamma new_img=alpha?img1+beta?img2+gamma
而函數(shù)convert_img2()
實(shí)現(xiàn)的過程,就是通過for循環(huán)修改原始圖片的像素值,與函數(shù)convert_img1()
的過程是一樣的,只不過convert_img1()
函數(shù)調(diào)用addWeighted()
函數(shù)的img2參數(shù)中圖片的像素值都是0而已。
幾何變換
圖像的幾何變換是指對(duì)圖片中的圖像像素點(diǎn)的位置進(jìn)行變換的一種操作,它將一幅圖像中的坐標(biāo)位置映射到新的坐標(biāo)位置,也就是改變像素點(diǎn)的空間位置,同時(shí)也要估算新空間位置上的像素值。
圖像裁剪
在圖像數(shù)據(jù)的矩陣中裁剪出部分矩陣作為新的圖像數(shù)據(jù),從而實(shí)現(xiàn)對(duì)圖像的裁剪。
import cv2
import numpy as np
# 圖像裁剪
img = cv2.imread('woman.png')
print(img.shape)
new_img = img[20:300, 20:400]
cv2.imwrite('crop_img.jpg', new_img)
上述代碼實(shí)現(xiàn)的過程是將原始的圖像從第(20,20)
個(gè)像素點(diǎn)的位置,裁剪到(300,400)
處,裁剪的形狀是矩形。
尺寸變換
修改圖像的尺寸也就是修改圖像的大小,OpenCV的resize()
函數(shù)可以實(shí)現(xiàn)這樣的功能。對(duì)圖像進(jìn)行尺寸變換時(shí),必然會(huì)丟失或者增加一些像素點(diǎn)。在縮放時(shí)建議使用區(qū)域插值cv2.INTER_AREA
,可以避免出現(xiàn)波紋;在放大時(shí)建議使用三次樣條插值cv2.INTER_CUBIC
,但是其計(jì)算速度相對(duì)較慢。也可以使用線性插值cv2.INTER_LINEAR
,默認(rèn)情況下所有改變圖像尺寸大小的操作使用的插值法都是線性插值。
# 圖像縮放
small_resize_img = cv2.resize(img, (200, 200), interpolation=cv2.INTER_AREA)
cv2.imwrite('small_resize.jpg', small_resize_img)
small_resize_img2 = cv2.resize(img, None, fx=0.5, fy=0.6, interpolation=cv2.INTER_AREA) # 圖像的寬對(duì)應(yīng)的是列數(shù),高對(duì)應(yīng)的是行數(shù)
cv2.imwrite('small_resize2.jpg', small_resize_img2)
圖像旋轉(zhuǎn)
旋轉(zhuǎn)通過getRotationMatrix2D()
函數(shù)來實(shí)現(xiàn)。
# 圖像旋轉(zhuǎn)
img = cv2.imread('woman.png')
rows, cols, _ = img.shape
rotated_mat = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1) # 第一個(gè)參數(shù)是旋轉(zhuǎn)中心,第2個(gè)為旋轉(zhuǎn)角度,第3個(gè)為旋轉(zhuǎn)后的縮放因子
rotated_img = cv2.warpAffine(img, rotated_mat, dsize=(cols, rows))
cv2.imwrite('rot45.jpg', rotated_img)
噪聲處理
對(duì)訓(xùn)練數(shù)據(jù)添加適量噪聲,可以使訓(xùn)練后的模型更加魯棒,對(duì)模型的性能提升有一定幫助。對(duì)噪聲進(jìn)行消除,可以增加圖像的質(zhì)量。
添加噪聲
對(duì)圖像添加兩種常用噪聲的方法:
- 椒鹽噪聲
- 高斯噪聲
import cv2
import random
import numpy as np
# 添加椒鹽噪聲
def salt_and_pepper_noise(img, percentage):
rows, cols, chs = img.shape
num = int(percentage * rows * cols)
for i in range(num):
x = random.randint(0, rows-1)
y = random.randint(0, cols-1)
z = random.randint(0, chs-1)
if random.randint(0, 1) == 0:
img[x, y, z] = 0 # 黑色噪點(diǎn)
else:
img[x, y, z] = 255 # 白色噪點(diǎn)
return img
# 添加高斯隨機(jī)噪聲
def gaussian_noise(img, mu, sigma, delta):
rows, cols, chs = img.shape
for i in range(rows):
for j in range(cols):
for k in range(chs):
# 生成高斯分布的隨機(jī)數(shù),與原始數(shù)據(jù)相加要取整
value = int(img[i, j, k] + delta*random.gauss(mu=mu, sigma=sigma))
value = np.clip(a_max=255, a_min=0, a=value)
img[i, j, k] = value
return img
img = cv2.imread('woman.png')
cv2.imwrite('saltPepper.jpg', salt_and_pepper_noise(img, 0.3))
cv2.imwrite('gaussain.jpg', gaussian_noise(img, 0, 1, 100))
可以看到上述為圖像添加椒鹽噪聲和高斯噪聲的方法。對(duì)于高斯噪聲來說,函數(shù)gaussian_noise()
中的mu
參數(shù)代表了隨機(jī)數(shù)高斯分布的平均值,sigma
代表隨機(jī)數(shù)高斯分布的標(biāo)準(zhǔn)差,而參數(shù)delta
代表一個(gè)系數(shù),表明添加高斯噪聲的強(qiáng)度。
處理噪聲
OpenCV提供了幾種濾波方法,如中值濾波、雙邊濾波、高斯模糊、二維卷積等,
import cv2
import random
import numpy as np
# 模糊與濾波
salt_and_pepper_img = cv2.imread('saltPepper.jpg')
gaussain_img = cv2.imread('gaussain.jpg')
# 二維卷積
kernel = np.ones((5, 5), np.float32) / 25 # 每個(gè)值是0.04
conv_2d_img = cv2.filter2D(salt_and_pepper_img, -1, kernel)
cv2.imwrite('filter_2d_img.jpg', conv_2d_img)
# 中值濾波
median_blur_img = cv2.medianBlur(salt_and_pepper_img, 5) # 參數(shù)5表示大小為5x5的區(qū)域像素值進(jìn)行計(jì)算
cv2.imwrite('median_blur_img.jpg', median_blur_img)
# 高斯模糊
gaussian_blur_img = cv2.GaussianBlur(gaussain_img, (5, 5), 0)
cv2.imwrite('gaussian_blur_img.jpg', gaussian_blur_img)
# 雙邊濾波
bilateral_filter_img = cv2.bilateralFilter(gaussain_img, 9, 75, 75) # 9代表鄰域直徑,兩個(gè)參數(shù)75分別代表值域與空域標(biāo)準(zhǔn)差
cv2.imwrite('bilateral_filter_img.jpg', bilateral_filter_img)
文章來源:http://www.zghlxwxcb.cn/news/detail-695763.html
可以看到,中值濾波的效果是最好的。文章來源地址http://www.zghlxwxcb.cn/news/detail-695763.html
到了這里,關(guān)于數(shù)字圖像處理:亮度對(duì)比度-幾何變換-噪聲處理的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!