常见的数据增强算法
1. 基于直方图均衡化的图像增强
直方图均衡化是通过调整图像的灰阶分布,使得在0~255灰阶上的分布更加均衡,提高了图像的对比度,达到改善图像主观视觉效果的目的。对比度较低的图像适合使用直方图均衡化方法来增强图像细节。
彩色图像的直方图均衡化实现:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 直方图均衡增强
def hist(image):
r, g, b = cv2.split(image)
r1 = cv2.equalizeHist(r)
g1 = cv2.equalizeHist(g)
b1 = cv2.equalizeHist(b)
image_equal_clo = cv2.merge([r1, g1, b1])
return image_equal_clo
image = cv2.imread("example.jpg")
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
plt.subplot(4, 2, 1)
plt.imshow(image)
plt.axis('off')
plt.title('Offical')
# 直方图均衡增强
image_equal_clo = hist(image)
plt.subplot(4, 2, 2)
plt.imshow(image_equal_clo)
plt.axis('off')
plt.title('equal_enhance')
plt.show()
2. 对数图像增强算法
对数图像增强是图像增强的一种常见方法,其公式为:
S = c log(r+1)
其中c是常数(以下算法c=255/(log(256)),这样可以实现整个画面的亮度增大。
def log(image):
image_log = np.uint8(np.log(np.array(image) + 1))
cv2.normalize(image_log, image_log, 0, 255, cv2.NORM_MINMAX)
# 转换成8bit图像显示
cv2.convertScaleAbs(image_log, image_log)
return image_log
3. 指数图像增强算法
指数图像增强的表达为:S = cR^r,通过合理的选择c和r可以压缩灰度范围,算法以c=1.0/255.0, r=2实现。
4. 加Masaic算法
在日常中有时候保密或其他需要将图像马赛克,下面的算法实现图像马赛克功能(原理:用中心像素来表示邻域像素)。
import cv2
import numpy as np
def gamma(image):
fgamma = 2
image_gamma = np.uint8(np.power((np.array(image) / 255.0), fgamma) * 255.0)
cv2.normalize(image_gamma, image_gamma, 0, 255, cv2.NORM_MINMAX)
cv2.convertScaleAbs(image_gamma, image_gamma)
return image_gamma
5. 曝光过度问题处理
对于曝光过度问题,可以通过计算当前图像的反相(255-image),然后取当前图像和反相图像的较小者为当前像素位置的值。
import cv2
import numpy as np
from matplotlib import pyplot as plt
def main():
Overexpose = cv2.imread("res/Overexposed.jpg")
underexpose = cv2.imread("res/underexposed.jpg")
#cv2.imshow("Over", Overexpose)
#cv2.imshow("under", underexpose)
plt.figure(1)
plt.subplot(4,2,1)
plt.imshow(Overexpose)
plt.subplot(4,2,2)
plt.imshow(underexpose)
plt.subplot(4, 2, 3)
chans = cv2.split(Overexpose)
colors = ("b", "g", "r")
for (chan, color) in zip(chans, colors):
hist = cv2.calcHist([chan], [0], None, [256], [0, 256])
plt.plot(hist, color=color)
plt.xlim([0, 256])
plt.subplot(4, 2, 4)
chans = cv2.split(underexpose)
colors = ("b", "g", "r")
for (chan, color) in zip(chans, colors):
hist = cv2.calcHist([chan], [0], None, [256], [0, 256])
plt.plot(hist, color=color)
plt.xlim([0, 256])
plt.subplot(4, 2, 5)
equalizeOver = np.zeros(Overexpose.shape, Overexpose.dtype)
equalizeOver[:, :, 0] = cv2.equalizeHist(Overexpose[:, :, 0])
equalizeOver[:, :, 1] = cv2.equalizeHist(Overexpose[:, :, 1])
equalizeOver[:, :, 2] = cv2.equalizeHist(Overexpose[:, :, 2])
plt.imshow(equalizeOver)
cv2.imwrite('./out/equlizeOver.jpg', equalizeOver)
# cv2.imshow('equalizeOver', equalizeOver)
plt.subplot(4, 2, 6)
equalizeUnder = np.zeros(underexpose.shape, underexpose.dtype)
equalizeUnder[:, :, 0] = cv2.equalizeHist(underexpose[:, :, 0])
equalizeUnder[:, :, 1] = cv2.equalizeHist(underexpose[:, :, 1])
equalizeUnder[:, :, 2] = cv2.equalizeHist(underexpose[:, :, 2])
plt.imshow(equalizeUnder)
cv2.imwrite('./out/equalizeunder.jpg', equalizeUnder)
plt.subplot(4, 2, 7)
chans = cv2.split(equalizeOver)
colors = ("b", "g", "r")
for (chan, color) in zip(chans, colors):
hist = cv2.calcHist([chan], [0], None, [256], [0, 256])
plt.plot(hist, color=color)
plt.xlim([0, 256])
plt.subplot(4, 2, 8)
chans = cv2.split(equalizeUnder)
colors = ("b", "g", "r")
for (chan, color) in zip(chans, colors):
hist = cv2.calcHist([chan], [0], None, [256], [0, 256])
plt.plot(hist, color=color)
plt.xlim([0, 256])
plt.show()
cv2.waitKey(0)
if __name__ == '__main__':
main()
OpenCV使用直方图均衡,修正曝光过度和曝光不足的图片_opencv曝光过度修复_王小鹏鹏的博客-CSDN博客
6. 高反差保留
高反差保留主要是将图像中颜色、明暗反差较大两部分的交界处保留下来,比如图像中有一个人和一块石头,那么石头的轮廓线和人的轮廓线以及面部、服装等有明显线条的地方会变被保留,儿其他大面积无明显明暗变化的地方则生成中灰色。其表达形式为:dst = r*(img - Blur(img))。
7. 拉普拉斯算子图像增强
拉普拉斯算子可以增强局部的图像对比度
def laplacian(image):
kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
image_lap = cv2.filter2D(image, cv2.CV_8UC3, kernel)
return image_lap
8. 伽马变换
伽马变换对于图像对比度偏低,并且整体亮度值偏高(对于相机过曝)情况下的图像增强效果明显
def gamma(image):
fgamma = 2
image_gamma = np.uint8(np.power((np.array(image) / 255.0), fgamma) * 255.0)
cv2.normalize(image_gamma, image_gamma, 0, 255, cv2.NORM_MINMAX)
cv2.convertScaleAbs(image_gamma, image_gamma)
return image_gamma