普通的全局变换就是对像素都做一样的数学处理,其实就分三个:线性变换、Log后线性变换、Gamma(指数),这些不用函数其实写起来也简单,不过 OpenCV 也实现了接口,直接看代码就完事。源码在 opencv contrib intensity_transform 模块。
# autoscaling: 线性变换,即 output = 255 * (input - minVal) / (maxVal - minVal)
cv2.intensity_transform.autoscaling(src, output)
# contrastStretching: 分段式线性变换,[0, r1]-->[0, s1], [r1, r2]-->[s1, s2], [r2, 255]-->[s2, 255]
cv2.intensity_transform.contrastStretching(src, output, r1=50, s1=100, r2=180, s2=200)
# logTransform: Log 后线性变换,即 output = log(input) * (255 / log(maxVal + 1))
cv2.intensity_transform.logTransform(src, output)
# gammaCorrection: 指数变换,即 output = input ^ gamma
cv2.gammaTransform.gammaCorrection(src, output, gamma=2.2)这个就用 CLAHE 就好了,经典方法了。
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
output = clahe.apply(src)利用视网膜模型。原理上是用一堆参数仿照人眼的两种视觉细胞,不仅可以用于对比度增强,也可以用于 ToneMapping、运动检测等等。OpenCV 有一个专门的模块处理,在杂项中也有一篇记录文章[TODO]。
用于对比度增强就相当于调整其中一种叫做 Parvo 视觉细胞的感光形态。Retina 我的实验代码在 test_retina.ipynb 中,下面就是直接摘录下其中的对比度增强的实验代码。同样还是建议可以看一下我对 Retina 学习的记录文章[TODO]。
result = []
# 说明:在 retina 处理 src 前可以进一步处理 src,常见的如只保留直方图的 5%-95% 之间的像素
src = cv2.imread('./image/retina/input.JPG')
# 创建 retina
retina = cv2.bioinspired_Retina.create((src.shape[1], src.shape[0]))
# 打印属性 / 保存属性
# retina.write('retinaParams.xml')
# print(retina.printSetup())
# 读取默认配置
retina.setup('./data/retina/default_retina_config.xml')
retina.run(src)
result.append(('Default Parvo', retina.getParvo()))
result.append(('Default Magno', retina.getMagno()))
# 各个参数含义:https://docs.opencv.org/4.x/d2/d94/bioinspired_retina.html
retina.setColorSaturation(colorSaturationValue=4.0)
# 重要:参数必须要一下子设完,不要出现多次 setupxxx,否则当前 setup 会用默认值覆盖掉前面设好的参数!
retina_config = {
'photoreceptorsLocalAdaptationSensitivity': 0.6,
'ganglionCellsSensitivity': 0.6,
'horizontalCellsGain': 20,
}
retina.setupOPLandIPLParvoChannel(**retina_config)
# 可以用 write 到一个配置文件中,看看是否参数设置成功
# retina.write('./test.xml')
retina.run(src)
result.append(('My Parvo', retina.getParvo()))
result.append(('My Magno', retina.getMagno()))
result.append(('Src Image', src))
show_images(result, colnum=5, scale=4)OpenCV 复现的一篇论文,Github 地址:https://github.com/baidut/BIMEF
但好像 OpenCV 复现的有点问题: Compared to the original code, this implementation is a little bit slower and does not provide the same results. In particular, quality of the image enhancement is degraded for the bright areas in certain conditions.
函数在 https://docs.opencv.org/4.x/dc/dfe/group__intensity__transform.html 中,调包就行,这里记录一下各个参数:
void cv::intensity_transform::BIMEF (
InputArray input, OutputArray output,
float k, float mu, float a, float b
)