项目获取一批图像数据,由于采集设备GOPRO本身和拍摄时的参数设置的问题导致数据成像质量很差,需要进行图像处理。
数据存在图像色彩不均匀、图像上有渐变纹(不知道术语,暂时如此描述)、偏暗等情况,几张样例如下:
此博客记录处理过程,并贴出相关的代码。
1.直方图均衡-效果不好
import cv2
img = cv2.imread('')
# cv2.imshow("src", img)
# 彩色图像均衡化,需要分解通道 对每一个通道均衡化
(b, g, r) = cv2.split(img)
bH = cv2.equalizeHist(b)
gH = cv2.equalizeHist(g)
rH = cv2.equalizeHist(r)
# 合并每一个通道
result = cv2.merge((bH, gH, rH))
# cv2.imshow("dst", result)
cv2.imwrite('', result)
2.对比度、亮度:
3.色调调节-部分图片整体偏绿,将图像通道分离,对g通道单独调整:
4.曝光调整
对比度/亮度/色调/曝光调整对不同的图片需要设置不同的参数,很难对全部数据集处理,对图片的渐变纹也无法取得很好的效果,使用cv2.createTrackbar()交互调整不同的对比度/亮度/色调/曝光参数,代码如下:
import cv2
import numpy as np
import os
def gamma_trans(img, gamma): # gamma函数处理
gamma_table = [np.power(x / 255.0, gamma) * 255.0 for x in range(256)] # 建立映射表-(Color/255)^R*255
# 当gamma > 1时,颜色空间的数值在变换后整体下降,R越大,颜色数值下降得越明显,宏观的表现为图片亮度下降增加
# 当0 < R < 1时,颜色空间的数值在变换后整体上升,R越小,颜色数值上升得越明显,宏观的表现为图片亮度上升增加
gamma_table = np.round(np.array(gamma_table)).astype(np.uint8) # 颜色值为整数
return cv2.LUT(img, gamma_table)
# 图片颜色查表。另外可以根据光强(颜色)均匀化原则设计自适应算法。
# 通过LUT,我们可以将一组RGB值输出为另一组RGB值,从而改变画面的曝光与色彩
def nothing(x):
pass
cv2.namedWindow("demo", 0) # 将显示窗口的大小适应于显示器的分辨率
cv2.createTrackbar('Value of Gamma', 'demo', 100, 1000, nothing) # 使用滑动条动态调节参数gamma
cv2.createTrackbar('bt', 'demo', 100, 120, nothing) # 使用滑动条动态调节参数b
cv2.createTrackbar('gt', 'demo', 95, 120, nothing) # 使用滑动条动态调节参数g
cv2.createTrackbar('rt', 'demo', 100, 120, nothing) # 使用滑动条动态调节参数r
cv2.createTrackbar('contrast', 'demo', 100, 300, nothing) # 使用滑动条动态调节参数 对比度
cv2.createTrackbar('brightness', 'demo', 0, 200, nothing) # 使用滑动条动态调节参数 亮度
data_base_dir = '' # 输入文件夹的路径
outfile_dir = '' # 输出文件夹的路径
print("press enter to make sure your operation and process the next picture")
list = os.listdir(data_base_dir)
list.sort()
list2 = os.listdir(outfile_dir)
list2.sort()
for file in list: # 遍历目标文件夹图片
read_img_name = data_base_dir + '/' + file.strip() # 取图片完整路径
image = cv2.imread(read_img_name) # 读入图片
# image = np.rot90(image,-1)
while (1):
value_of_gamma = float(cv2.getTrackbarPos('Value of Gamma', 'demo') * 0.01) # gamma取值
bt = float(cv2.getTrackbarPos('bt', 'demo') * 0.01) # bt取值
gt = float(cv2.getTrackbarPos('gt', 'demo') * 0.01) # gt取值
rt = float(cv2.getTrackbarPos('rt', 'demo') * 0.01) # rt取值
contrast = float(cv2.getTrackbarPos('contrast', 'demo') * 0.01) # rt取值
brightness = cv2.getTrackbarPos('brightness', 'demo')
b, g, r = cv2.split(image)
image_hue_correct = cv2.merge([np.uint8(b * bt), np.uint8(g * gt), np.uint8(r * rt)])
image_gamma_correct = gamma_trans(image_hue_correct, value_of_gamma) # value_of_gamma大于1曝光度下降,大于0小于1曝光度增强
img_cb_adj = np.uint8(np.clip((contrast * image_gamma_correct + brightness), 0, 255))
cv2.imshow("demo", img_cb_adj)
k = cv2.waitKey(1)
if k == 13: # 按回车键确认处理、保存图片到输出文件夹和读取下一张图片
out_img_name = outfile_dir + '/' + file.strip()
cv2.imwrite(out_img_name, image_gamma_correct)
print("The photo which is processed is {}".format(file))
break
如果对每一张图片都手动调整,工作量巨大,寻找自适应的处理方法。
5.滤波-能想到不是噪声的问题,但还是尝试了一下,结果确实没效果
import cv2
img = cv2.imread('')
result_path = ''
# 均值滤波
img_mean = cv2.blur(img, (5,5))
cv2.imwrite(result_path + '/' + 'GOPR0750_mean.JPG', img_mean)
# 高斯滤波
img_Guassian = cv2.GaussianBlur(img,(5,5),0)
cv2.imwrite(result_path + '/' + 'GOPR0750_Guassian.JPG', img_Guassian)
# 中值滤波
img_median = cv2.medianBlur(img, 5)
cv2.imwrite(result_path + '/' + 'GOPR0750_median.JPG', img_median)
# 双边滤波
img_bilater = cv2.bilateralFilter(img,9,75,75)
cv2.imwrite(result_path + '/' + 'GOPR0750_bilater.JPG', img_bilater)
6.自动gamma校正-利用图像均值计算gamma,效果甚微:
import cv2
import numpy as np
import math
import os
def gamma_trans(img, gamma): # gamma函数处理
gamma_table = [np.power(x / 255.0, gamma) * 255.0 for x in range(256)] # 建立映射表
gamma_table = np.round(np.array(gamma_table)).astype(np.uint8) # 颜色值为整数
return cv2.LUT(img, gamma_table) # 图片颜色查表。另外可以根据光强(颜色)均匀化原则设计自适应算法。
def nothing(x):
pass
data_base_dir = '' # 输入文件夹的路径
outfile_dir = '' # 输出文件夹的路径
list = os.listdir(data_base_dir)
list.sort()
list2 = os.listdir(outfile_dir)
list2.sort()
for file in list: # 遍历目标文件夹图片
read_img_name = data_base_dir + '/' + file.strip() # 取图片完整路径
image = cv2.imread(read_img_name) # 读入图片
img_gray = cv2.imread(read_img_name, 0) # 灰度图读取,用于计算gamma值
mean = np.mean(img_gray)
gamma_val = math.log10(0.5) / math.log10(mean / 255) # 公式计算gamma
image_gamma_correct = gamma_trans(image, gamma_val) # gamma变换
out_img_name = outfile_dir + '/' + file.strip()
cv2.imwrite(out_img_name, image_gamma_correct)
print("The photo which is processed is {}".format(file))
7.基于二维伽马函数的光照不均匀图像自适应校正算法-效果不好
import cv2
import math
import numpy as np
from skimage import color
import os
path = ''
outfile_dir = ''
# 获取该文件夹中的所有文件
files = os.listdir(path)
# 定义一个全局参数用于对输出图片命名
global i
i = 1
# 参数
HSIZE = 25
q = math.sqrt(2)
SIGMA1 = 15
SIGMA2 = 80
SIGMA3 = 250
# 对所有文件进行遍历处理
for file in files:
# 判断file是否为文件夹
if not os.path.isdir(file):
# 读取图片
im = cv2.imread(path + '/' + file.strip())
hsv = color.rgb2hsv(im)
# 分离hsv通道
h, s, v = cv2.split(hsv)
# 对亮度v通道进行不同参数的高斯滤波
F1 = cv2.GaussianBlur(v, (HSIZE, HSIZE), SIGMA1 / q, HSIZE)
F2 = cv2.GaussianBlur(v, (HSIZE, HSIZE), SIGMA2 / q, HSIZE)
F3 = cv2.GaussianBlur(v, (HSIZE, HSIZE), SIGMA3 / q, HSIZE)
# 取每个滤波后的平均值
gaus = (F1 + F2 + F3) / 3
# 获取亮度通道的平均值,便于跟原亮度进行比较
m = np.mean(gaus)
# 获取亮度通道的宽和高
w, height = np.shape(v)
out = np.zeros(np.size(v))
# 进行gama变换
gama = np.power(0.5, ((m - gaus) / m))
out = (np.power(v, gama))
hsv1 = cv2.merge([h, s, out])
rgb = color.hsv2rgb(hsv1)
rgb = rgb / rgb.max()
rgb = 255 * rgb
rgb = rgb.astype(np.uint8)
# 将结果输出到文件夹中保存
cv2.imwrite(outfile_dir + '/' + file.strip(), rgb)
v1 = out
mini = v - v1
p = np.mean(mini)
print(str(i) + ':' + str(p))
i = i + 1
8.带色彩恢复的多尺度视网膜增强算法MSRCR-效果相对较好
参考:https://blog.csdn.net/ajianyingxiaoqinghan/article/details/71435098
代码:https://github.com/falrom/MSRCR_Python
效果如图: