原理介绍
近期在处理样本的过程中,在对样本的处理的过程中,总是收到样本拍摄过程中光照的影响,查阅了一些资料,决定采取Retinex的方式对图像光照信息进行处理。
图像机理
本次处理过程主要针对单通道的灰度图像(0-255),由二维元素组成,每个元素包含一个坐标 (x,y)和一个响应值
f
(
x
,
y
)
f(x,y)
f(x,y),每个元素为数字图像的一个像素。本次处理的样本直接通过固定角度的相机采集而来,经一定处理之后得到待处理的样本图像,我们基于此图像进行一系列的处理。其大致流程如下图所示
得到的图像分量
F
(
x
,
y
)
F(x,y)
F(x,y)与光照分量
I
(
x
,
y
)
I(x,y)
I(x,y)和反射分量
R
(
x
,
y
)
R(x,y)
R(x,y),他们满足公式:
F
(
x
,
y
)
=
I
(
x
,
y
)
∗
R
(
x
,
y
)
F(x,y)=I(x,y)*R(x,y)
F(x,y)=I(x,y)∗R(x,y)。其中反射分量反应了所照图像的本质,因此我们的目的是从图像分量中还原出反射分量,反映出图像的本质信息。
方法介绍
首先我们需要明确,我们所需要的信息即反射分量
R
(
x
,
y
)
R(x,y)
R(x,y),我们可以将指数域转化为对数域,通过估计光照分量,计算得到反射分量。
l
o
g
[
F
(
x
,
y
)
]
=
l
o
g
[
I
(
x
,
y
)
]
+
l
o
g
[
R
(
x
,
y
)
]
log[F(x,y)]=log[I(x,y)]+log[R(x,y)]
log[F(x,y)]=log[I(x,y)]+log[R(x,y)]
而在估计光照分量时,我们考虑到光照分量属于低频分量,可以利用高斯大核模糊的方式得到估计的光照分量,再用估计出的光照分量转换至对数域最终得到反射分量。
功能实现
主要涉及两部分的内容
- 高斯模糊估计光照分量
- 对数域图像处理以及灰度变换还原图像
程序设计
void Get_Reflect(const Mat& src, Mat& dst, int sigma)
{
Mat doubleImage, gaussianImage, logIImage, logGImage, logRImage,End_My, End_My_log, dst_My;
//转换范围,所有图像元素增加1.0保证log操作正常,防止溢出
src.convertTo(doubleImage, CV_64FC1, 1.0, 1.0);
//高斯模糊,当size为零时将通过sigma自动进行计算
GaussianBlur(doubleImage, gaussianImage, Size(0, 0), sigma);
//OpenCV的log函数可以计算出对数值。logIImage和logGImage就是对数计算的结果。
log(doubleImage, logIImage);
log(gaussianImage, logGImage);
logRImage = logIImage - logGImage;
normalize(logRImage, dst, 0, 255, NORM_MINMAX, CV_8UC1);
}
dst即为需要的反射分量图像
结果展示
原图像:
提取后图像