图像分段线性变化_暗光也清晰的图像增强算法
個(gè)人學(xué)習(xí)筆記:像素反轉(zhuǎn)、伽馬矯正、對數(shù)變換、線性變換、分段變換。
某天跑完步以后拍出了這樣一張照片,由于晚上開閃光不太好,所以想自己處理一下(為了更好的看出處理效果,所以采用尺寸較大的原圖像,沒有進(jìn)行尺寸縮小):
在光線較暗的情況下拍攝的圖像整體的灰度值偏低,可以從直方圖中很直接的看出,圖像的像素值都分布在50以內(nèi)(直方圖就是統(tǒng)計(jì)圖像中0-255這256個(gè)級別對應(yīng)的像素值個(gè)數(shù),比如圖像有1000個(gè)像素點(diǎn),像素值為0的有10個(gè),值為1的有5個(gè)。。。。值為255的有3個(gè))像素值很多都接近于0并且少部分分布在100-255之間。
這里并沒有對RGB三個(gè)通道分別進(jìn)行統(tǒng)計(jì),而是將RGB轉(zhuǎn)為灰度圖再進(jìn)行統(tǒng)計(jì)(我會在另外的文章中單獨(dú)的介紹直方圖和直方圖均衡算法)。
import imageio import matplotlib.pyplot as plt import numpy as npdef rgb2gray(rgb):gray = rgb[:, :, 0] * 0.299 + rgb[:, :, 1] * 0.587 + rgb[:, :, 2] * 0.114gray = gray.astype(np.uint8)return graydef get_histgram(image, nums=256):"""calculate histgram of a gray imageArgs:image:gray imagenums:pixel grade, defualt is 256Return:histgram"""if len(image.shape) != 2:raise ValueError("Input image is not a gray image")h = image.shape[0]w = image.shape[1]hist = {} for i in range(0, nums):hist[i] = 0for i in range(0, h):for j in range(0, w):hist[image[i][j]] += 1return histimage_rgb = np.array(imageio.imread("dark.jpg")) image = rgb2gray(image_rgb)hist = get_histgram(image, nums=256) x = hist.keys() y = hist.values() plt.bar(x, y) plt.savefig("hist")所以,要增加圖像的亮度,既然直方圖顯示整體像素值偏低,那么就可以直接的把全體的像素值直接加上一個(gè)數(shù)值:
其中c是一個(gè)可以自由選擇的常數(shù),通過線性加法獲得了下面的照片:
代碼如下(由于大于195的像素值加60以后大于255,所以要限制最大像素值的方式):
# y = pixel*k + b # y = pixel*k + b import imageio import numpy as np import matplotlib.pyplot as plt plt.figure(figsize=(10,10)) dark_image = imageio.imread("dark.jpg") plt.subplot(1,2,1) plt.imshow(dark_image/255) plt.subplot(1,2,2) invert_image = dark_image + 60 invert_image = invert_image.astype(np.uint8) plt.imshow(invert_image/255) plt.show()然后統(tǒng)計(jì)一下線性變換以后的直方圖:
現(xiàn)在,像素值不再是集中在0-50之間,而是向50-100靠攏,可是照片中窗口顏色明顯失真,看來這種增強(qiáng)方式不可行。
所以,嘗試使用了分段線性變換的方式(由于計(jì)算速度太慢,所以resize了),分段線性就是針對不同的灰度區(qū)間采取不同變換函數(shù),選擇a=(x1,y1),b=(x2,y2)兩個(gè)分段點(diǎn),對0-a之間和a-b之間與b-255之間,這三個(gè)不同灰度區(qū)間采用不同的變換:
# 灰度分層 from PIL import Image import numpy as np import matplotlib.pyplot as plt dark_image = np.array(Image.open("dark.jpg").resize((300,450),Image.ANTIALIAS)) # dark_image = np.array(Image.open("dark.jpg")) def seg_linear(dark_image,x1,y1,x2,y2):if (x1>x2 or y1>y2):raise ValueError("must make sure x1<x2 and y1<y2")seg_image = np.zeros(shape=dark_image.shape, dtype=np.float32)for i in range(dark_image.shape[2]):for j in range(dark_image.shape[1]):for k in range(dark_image.shape[0]):if dark_image[k][j][i] < x1:seg_image[k][j][i] = (y1/x1)*dark_image[k][j][i]elif dark_image[k][j][i] < x2:seg_image[k][j][i] = ((y2-y1)/(x2-x1))*(dark_image[k][j][i]-x1) + y1else:seg_image[k][j][i] = ((255-y2)/(255-x2))*(dark_image[k][j][i]-x2) + y2return seg_image seg_image = seg_linear(dark_image,40,150,70,220) plt.figure(figsize=(10,10)) plt.subplot(1,2,1) plt.imshow(dark_image/255) plt.subplot(1,2,2) plt.imshow(seg_image/255) plt.show()獲得了下面這種結(jié)果:
效果感覺還行,就是圖像對比度不滿意,但是這兩個(gè)分段點(diǎn)太難選了。
統(tǒng)計(jì)一下直方圖,發(fā)現(xiàn)像素值的分布在不同區(qū)間均勻了很多,這樣圖像的整體像素并沒有全部升高,但是亮度還是增加 了不少:
最后嘗試了一下采用伽馬矯正,這個(gè)名字我也不是很理解,感覺就是冪函數(shù):
代碼如下:
import imageio import numpy as np import matplotlib.pyplot as plt plt.figure(figsize=(10,10)) dark_image = imageio.imread("dark.jpg") gama_image = (dark_image.astype(np.float32)/255)**0.25 plt.figure(figsize=(10,10)) plt.subplot(1,2,1) plt.imshow(dark_image/255) plt.subplot(1,2,2) plt.imshow(gama_image) imageio.imsave("gama.jpg",gama_image*255)可以調(diào)節(jié)不同的gama值,就能得到不同程度的亮度增加,直方圖如下,像素值整體遷移到了更高的區(qū)間,圖像的 亮度很自然的增加了:
總結(jié)一下:想增強(qiáng)圖像的亮度有很多種方式,但是核心就是增大像素值。
總結(jié)
以上是生活随笔為你收集整理的图像分段线性变化_暗光也清晰的图像增强算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: layui遍历json数组_shell脚
- 下一篇: tta部署_YOLOv5项目介绍