首页 > 解决方案 > 使用 python opencv 进行照明标准化

问题描述

我正在做一个深度学习的图像分类项目,想实现论文https://arxiv.org/pdf/1907.09449.pdf 4.4节中提供的光照归一化,但没有得到预期的结果。

在论文的 4.4 节中,它使用 gaussian kerenl filter 得到背景图像,然后在 YCrCb 颜色空间中从 Y 通道中减去它,我尝试重现结果但与图 4 中的论文不一样

下面是我的代码

image = cv2.imread(file)
cv2.imshow("origin", image)

# illumination normalize
ycrcb = cv2.cvtColor(image, cv2.COLOR_BGR2YCrCb)
y, cr, cb = cv2.split(ycrcb)

# get background which paper says (gaussian method using standard deviation 5 pixel)
gaussian = cv2.GaussianBlur(y, (0, 0), 5, 5)

# subtract background from Y channel which paper says
y = y - gaussian
ycrcb = cv2.merge([y, cr, cb])

output = cv2.cvtColor(ycrcb, cv2.COLOR_YCrCb2BGR)
cv2.imshow("output", output)

但输出结果图像(见下图)与纸上说的不一样(图 4)

原始图像->照明归一化图像

有谁知道该怎么做?感谢您的大力帮助:-)

标签: pythonopencv

解决方案


你有两个问题。首先,您需要根据图像大小与参考中使用的 299 像素大小成比例调整高斯模糊的 sigma。其次,您需要将差异偏向中灰色附近。根据需要调整亮度偏差。

所以这就是我在 Python/OpenCV 中实现它的方法。

输入:

在此处输入图像描述

import cv2
import numpy as np

# read input
image = cv2.imread('retina2.jpg')
hh, ww = image.shape[:2]
print(hh, ww)
max = max(hh, ww)

# illumination normalize
ycrcb = cv2.cvtColor(image, cv2.COLOR_BGR2YCrCb)

# separate channels
y, cr, cb = cv2.split(ycrcb)

# get background which paper says (gaussian blur using standard deviation 5 pixel for 300x300 size image)
# account for size of input vs 300
sigma = int(5 * max / 300)
print('sigma: ',sigma)
gaussian = cv2.GaussianBlur(y, (0, 0), sigma, sigma)

# subtract background from Y channel
y = (y - gaussian + 100)

# merge channels back
ycrcb = cv2.merge([y, cr, cb])

#convert to BGR
output = cv2.cvtColor(ycrcb, cv2.COLOR_YCrCb2BGR)

# save results
cv2.imwrite('retina2_proc.jpg', output)

# show results
cv2.imshow("output", output)
cv2.waitKey(0)


结果:

在此处输入图像描述


推荐阅读