视网膜类概述
- 注意
- 请记住,视网膜模型包含在以下命名空间中:使用 C++ 的 cv::bioinspired 和使用 Python 的 cv.bioinspired
简介
此类提供 Gipsa/Listic 实验室人类视网膜模型的主要控制。这是一个非可分离时空滤波器,模拟视网膜的两个主要信息通道:
- 中央视觉,用于精细的彩色视觉:视细通路。
- 周边视觉,用于灵敏的瞬态信号检测(运动和事件):视大通路。
此模型源自 Jeanny Herault 的工作 [135]。它参与了 Alexandre Benoit 的博士研究及其当前的研究 [24],[254]。他目前在 OpenCV 中维护此模块。它包括其他 Jeanny 的博士生的工作,例如 [67],以及 Jeanny 的书中描述的 Barthelemy Durette 的对数极坐标变换。
更详细地介绍此处实现的视网膜属性概述:
- 关于亮度和细节增强
- 局部对数亮度压缩(在感光细胞的入口点和神经节细胞的输出点)。
- 外丛状层水平的频谱白化(感光细胞和水平细胞的时空滤波)。
前一种行为压缩亮度范围,并允许在同一图像上看到非常明亮的区域和非常黑暗的区域,同时保留大量细节。后者减少低频亮度能量(平均亮度)并增强中频(细节)。总而言之,视网膜在高级分析之前很好地准备了视觉信号。这些特性在视频中非常有趣,其中光线变化会显著减少,并具有良好的时间一致性。
- 关于噪声滤波
- 滤除高频空间和时间噪声。视细通路和视大通路都受益于此。噪声减少得益于非可分离时空滤波。
- 在视细通路输出中,静态纹理得到增强,噪声被滤除(在视频中,时间噪声被很好地去除)。然而,像人类行为一样,运动纹理会被平滑处理。因此,只有当视网膜跟踪移动物体并将其从其视点保持静止时,才能增强移动物体的细节。
- 在视大通路输出中,即使在光线条件恶劣的情况下,它也能更清晰地检测事件(运动、变化),并减少噪声误差。作为一种折衷方案,视大通路输出是低空间频率信号,允许可靠地提取事件斑点(为此检查 TransientAreasSegmentationModule 模块)。
用途
此模型可用作预处理阶段,用于:
- 执行纹理分析,具有增强的信噪比和增强的细节,这些细节对输入图像的亮度范围具有鲁棒性(通过使用提供的 getParvo 方法检查视细通路视网膜通道输出)。
- 执行运动分析,也利用前面提到的特性(通过使用提供的 getMagno 方法检查视大通路视网膜通道输出)。
- 使用一个或两个通道对通用图像/视频序列进行描述。在词袋方法中使用视网膜的示例在 [254] 中给出。
- 注意
- 为了方便在计算机视觉应用中的使用,两个视网膜通道都应用于所有输入图像。这并不遵循真实的视网膜拓扑结构,但从图像处理的角度来看是实用的。如果需要视网膜映射(中央和旁中央视觉),请使用类中提出的对数采样功能。
- 请随时为补充说明和演示扩展视网膜描述、代码和用例。
用例示例
使用视细通路(视细通路视网膜输出)进行图像预处理
作为初步介绍,让我们从一个视觉示例开始。我们建议将滤波器应用于具有背光问题的低质量彩色 JPEG 图像。以下是所考虑的输入……“嗯,我能用眼睛看到的比用相机捕捉到的更多……”
具有背光问题的低质量彩色 JPEG 图像。
下面,视网膜中央模型应用于具有默认参数的整个图像。无论局部亮度如何,细节都会得到增强。这里轮廓得到强烈增强,但噪声水平保持较低。在此配置中,光晕效应是故意可见的。请参阅下面的参数讨论,并将 horizontalCellsGain 提高到接近 1 以将其移除。
视网膜中央模型应用于具有默认参数的整个图像。此处轮廓得到增强,亮度得到校正,并且在此配置中,光晕效应是故意可见的,将 horizontalCellsGain 提高到接近 1 以将其移除。
下面,第二个视网膜中央模型输出应用于具有侧重于自然感知的参数设置的整个图像。“嘿,我现在认出我的猫了,它在一天结束时看着山!”。此处轮廓得到增强,亮度得到校正,但在此配置中避免了光晕。背光效果得到校正,并且仍然保留了高光细节。然后,即使在低质量 JPEG 图像上,如果保留一些亮度信息,视网膜也能重建正确的视觉信号。正如 [24] 和下面讨论的演示代码中所述,这种配置也适用于将高动态范围 (HDR) 图像压缩到 8 位图像。如页面末尾所示,与默认值的差异参数为:
- horizontalCellsGain=0.3
- photoreceptorsLocalAdaptationSensitivity=ganglioncellsSensitivity=0.89。
视网膜中央模型应用于具有“自然度”参数的整个图像。此处轮廓得到增强,但在此配置中避免了光晕效应,horizontalCellsGain 为 0.3,photoreceptorsLocalAdaptationSensitivity=ganglioncellsSensitivity=0.89。
正如在这个初步演示中观察到的那样,视网膜可以使用各种参数进行设置,默认情况下,如上图所示,视网膜会强烈降低平均亮度能量并增强视觉场景的所有细节。亮度能量和光晕效应可以进行调节(从夸张到取消,如两个示例所示)。为了使用您自己的参数,您可以至少使用一次 write(String fs) 方法,该方法将使用所有默认参数编写正确的 XML 文件。然后,您可以根据需要进行调整,并随时使用 setup(String fs) 方法重新加载它们。这些方法更新了 Retina::RetinaParameters 成员结构,该结构将在后面介绍。XML 参数文件示例显示在页面末尾。
使用视细通路(视细通路视网膜输出)进行色调映射处理能力
此视网膜模型自然地处理亮度范围压缩。局部适应阶段和频谱白化有助于亮度范围压缩。此外,在过程的早期阶段去除了经常损坏色调映射图像的高频噪声,从而实现了自然的感知和无噪声的色调映射。
与上面显示的演示相比,设置差异如下:(有关更多详细信息,请参阅 bioinspired/samples/OpenEXRimages_HDR_Retina_toneMapping.cpp)
- 加载 HDR 图像(OpenCV 支持 OpenEXR 格式),并将直方图边界裁剪到约 5% 和 95%,以消除椒盐噪声般的像素损坏。
- 应用具有默认参数以及以下更改的视网膜(本节所示插图使用的通用参数):
- 视网膜 H 细胞增益 =0.4(与默认配置相比,主要变化:它大大减少了光晕效应)。
- localAdaptation_photoreceptors=0.99 (略高于默认值,以加强局部适应)
- localAdaptation_Gcells=0.95 (同样略高于默认值,以加强局部适应)
- 使用getParvo() 方法获取视网膜P通路输出。
请查看此页末尾,了解如何在配置文件中指定这些参数。
以下两个示例图显示了这种配置对两个图像样本的影响。
使用通用参数的HDR图像色调映射示例。原始图像来自http://openexr.com/ samples (openexr-images-1.7.0/ScanLines/CandleGlass.exr)
使用相同通用参数的HDR图像色调映射示例。原始图像来自http://www.pauldebevec.com/Research/HDR/memorial.exr)
使用视网膜M通路(视网膜M通路输出)进行运动和事件检测
可以使用视网膜的magno 输出轻松检测时空事件(使用getMagno() 方法)。其能量随运动速度线性增加。本文提出了一种使用bioinspired模块中提供的TransientAreasSegmentationModule类的事件斑点检测器。其基本思想是检测局部能量下降(相对于邻域),然后应用阈值。此过程已用于TRECVid挑战赛中视频的词袋描述[254],并且仅允许对瞬态区域进行视频帧描述。
这里我们展示了一些来自http://changedetection.net/的RGB和热成像视频示例的视网膜输出图。
- 注意
- 这里,我们使用默认的视网膜设置,会在强边缘周围产生光晕。请注意,时间常数允许在运动物体上可见时间效应(对于视频的静止图像插图很有用)。可以通过增加视网膜H细胞增益来去除光晕,而可以通过减小时间常数来减少时间效应。还要考虑到,两个视网膜输出都在[0:255]范围内重新缩放,因此当绘制magno输出时,如果没有运动,可能会显示很多“噪声”。但是,如果您使用getMagnoRAW getter获取它,则其能量仍然很低。
RGB图像序列的视网膜处理:来自http://changedetection.net/ (baseline/PETS2006)的示例。P通路增强静态信号,但会平滑移动的人,因为从其角度来看他们并非保持静止。M通路突出显示移动的人,观察上面那个(部分位于深色玻璃后面)的能量映射。
灰度图像序列的视网膜处理:来自http://changedetection.net/ (thermal/park)的示例。在这样的灰度图像上,P通路增强对比度,而M通路对移动的行人强烈反应。
文献
更多信息,请参考以下论文:
此视网膜滤波器代码包含博士/研究同事的研究贡献,作者已从中重新绘制代码。
- 查看retinacolor.hpp 模块,了解Brice Chaix de Lavarene博士的彩色马赛克/解马赛克以及他的参考论文:[67]
- 查看imagelogpolprojection.hpp 模块,了解源自Barthelemy Durette博士和Jeanny Herault的视网膜空间对数采样。还提出了视网膜/V1皮质投影,其源自Jeanny的讨论。更多信息请参见上述Jeanny Heraults的著作。
- Meylan&al关于HDR色调映射的工作,已作为模型中的特定方法实现:[191]
视网膜编程接口
该类允许使用Gipsa(初步工作)/Listic实验室的视网膜模型。它可以应用于静止图像、图像序列和视频序列。
以下是视网膜接口的概述,使用Retina::create() 函数(C++、Java、Python)分配一个实例。
namespace cv{
namespace bioinspired{
class Retina : public Algorithm
{
public:
struct RetinaParameters;
void setup (
String retinaParameterFile=
"",
const bool applyDefaultSetupOnFailure=
true);
void setup (FileStorage &fs,
const bool applyDefaultSetupOnFailure=
true);
void setup (RetinaParameters newParameters);
virtual void write (FileStorage &fs)
const;
void setupOPLandIPLParvoChannel (
const bool colorMode=
true,
const bool normaliseOutput=
true,
const float photoreceptorsLocalAdaptationSensitivity=0.7,
const float photoreceptorsTemporalConstant=0.5,
const float photoreceptorsSpatialConstant=0.53,
const float horizontalCellsGain=0,
const float HcellsTemporalConstant=1,
const float HcellsSpatialConstant=7,
const float ganglionCellsSensitivity=0.7);
void setupIPLMagnoChannel (
const bool normaliseOutput=
true,
const float parasolCells_beta=0,
const float parasolCells_tau=0,
const float parasolCells_k=7,
const float amacrinCellsTemporalCutFrequency=1.2,
const float V0CompressionParameter=0.95,
const float localAdaptintegration_tau=0,
const float localAdaptintegration_k=7);
void setColorSaturation (
const bool saturateColors=
true,
const float colorSaturationValue=4.0);
};
}}
virtual void clearBuffers()=0
清除所有视网膜缓冲区。
virtual Size getOutputSize()=0
检索视网膜输出缓冲区大小,如果进行了空间对数变换,则可能与输入不同……
virtual void applyFastToneMapping(InputArray inputImage, OutputArray outputToneMappedImage)=0
旨在校正图像亮度、校正背光问题的图像处理方法……
virtual void activateContoursProcessing(const bool activate)=0
激活/停用视网膜的视网膜通路处理(轮廓信息提取)……
virtual void setup(String retinaParameterFile="", const bool applyDefaultSetupOnFailure=true)=0
尝试打开一个XML视网膜参数文件来调整当前视网膜实例的设置。
virtual Mat getMagnoRAW() const =0
virtual void getParvo(OutputArray retinaOutput_parvo)=0
视网膜细节通道的访问器(模拟中央凹视觉)。
virtual Size getInputSize()=0
检索视网膜输入缓冲区大小。
virtual void write(String fs) const =0
写入xml/yml格式的参数信息。
virtual String printSetup()=0
输出一个字符串,显示使用的参数设置。
virtual void run(InputArray inputImage)=0
允许将视网膜应用于输入图像的方法。
virtual void setColorSaturation(const bool saturateColors=true, const float colorSaturationValue=4.0f)=0
激活颜色饱和度作为颜色解复用过程的最后一步 -> 此饱和度为……
static Ptr< Retina > create(Size inputSize)
virtual void setupOPLandIPLParvoChannel(const bool colorMode=true, const bool normaliseOutput=true, const float photoreceptorsLocalAdaptationSensitivity=0.7f, const float photoreceptorsTemporalConstant=0.5f, const float photoreceptorsSpatialConstant=0.53f, const float horizontalCellsGain=0.f, const float HcellsTemporalConstant=1.f, const float HcellsSpatialConstant=7.f, const float ganglionCellsSensitivity=0.7f)=0
设置OPL和IPL视网膜小细胞通路(参见生物学模型)
virtual void setupIPLMagnoChannel(const bool normaliseOutput=true, const float parasolCells_beta=0.f, const float parasolCells_tau=0.f, const float parasolCells_k=7.f, const float amacrinCellsTemporalCutFrequency=1.2f, const float V0CompressionParameter=0.95f, const float localAdaptintegration_tau=0.f, const float localAdaptintegration_k=7.f)=0
设置内丛状层 (IPL) 大细胞通路的参数值。
virtual void getMagno(OutputArray retinaOutput_magno)=0
视网膜运动通路的访问器(模拟周边视觉)。
virtual RetinaParameters getParameters()=0
virtual Mat getParvoRAW() const =0
virtual void activateMovingContoursProcessing(const bool activate)=0
激活/停用大细胞通路处理(运动信息提取),……
@ RETINA_COLOR_BAYER
标准拜耳采样
定义 retina.hpp:86
std::string String
定义 cvstd.hpp:151
Size2i Size
定义 types.hpp:370
const _InputArray & InputArray
定义 mat.hpp:443
std::shared_ptr< _Tp > Ptr
定义 cvstd_wrapper.hpp:23
const _OutputArray & OutputArray
定义 mat.hpp:445
设置视网膜
管理配置文件
使用Retina::write 和 Retina::load 方法时,您可以创建或加载存储视网膜配置的XML文件。
默认配置如下所示。
<?xml version="1.0"?>
<opencv_storage>
<OPLandIPLparvo>
<colorMode>1</colorMode>
<normaliseOutput>1</normaliseOutput>
<photoreceptorsLocalAdaptationSensitivity>7.5e-01</photoreceptorsLocalAdaptationSensitivity>
<photoreceptorsTemporalConstant>9.0e-01</photoreceptorsTemporalConstant>
<photoreceptorsSpatialConstant>5.7e-01</photoreceptorsSpatialConstant>
<horizontalCellsGain>0.01</horizontalCellsGain>
<hcellsTemporalConstant>0.5</hcellsTemporalConstant>
<hcellsSpatialConstant>7.</hcellsSpatialConstant>
<ganglionCellsSensitivity>7.5e-01</ganglionCellsSensitivity></OPLandIPLparvo>
<IPLmagno>
<normaliseOutput>1</normaliseOutput>
<parasolCells_beta>0.</parasolCells_beta>
<parasolCells_tau>0.</parasolCells_tau>
<parasolCells_k>7.</parasolCells_k>
<amacrinCellsTemporalCutFrequency>2.0e+00</amacrinCellsTemporalCutFrequency>
<V0CompressionParameter>9.5e-01</V0CompressionParameter>
<localAdaptintegration_tau>0.</localAdaptintegration_tau>
<localAdaptintegration_k>7.</localAdaptintegration_k></IPLmagno>
</opencv_storage>
以下是一些关于所有这些参数的说明,您可以根据需要调整它们来放大或减弱视网膜效果(轮廓增强、光晕效果、运动灵敏度、运动模糊等)。
基本参数
最简单的参数如下:
- colorMode:让视网膜处理颜色信息(如果为1)或灰度图像(如果为0)。在后一种情况下,只会处理输入的第一个通道。
- normaliseOutput:每个通道都有此参数:如果值设置为1,则将所考虑通道的输出重新缩放至0到255之间。请注意大细胞输出级别(运动/瞬态通道检测)的情况。残余噪声也将被重新缩放!
注意:使用颜色需要颜色通道复用/解复用,这也需要更多的处理。您可以预期使用灰度级可以获得更快的处理速度:它需要大约30个乘积才能处理所有视网膜过程中的每个像素,并且最近已针对多核架构进行了并行化。
光感受器参数
以下参数作用于视网膜的入口点——光感受器——并影响所有后续过程。这些传感器是低通时空滤波器,用于平滑时空数据并调整其对局部亮度的敏感性,从而提高细节提取和高频噪声消除。
- photoreceptorsLocalAdaptationSensitivity在0到1之间。接近1的值允许在光感受器级别实现高亮度对数压缩效果。接近0的值提供更线性的灵敏度。单独增加它可能会“烧毁”Parvo(细节通道)输出图像。如果与ganglionCellsSensitivity一起调整,则无论局部亮度如何,图像都可以非常对比……但会降低自然度。
- photoreceptorsTemporalConstant这设置了视网膜入口处低通滤波器效果的时间常数。较高的值会导致强烈的时空平滑效果:移动物体变得模糊并可能消失,而静态物体则被突出显示。但是,当开始视网膜处理时,稳定状态的达到时间会更长。
- photoreceptorsSpatialConstant指定与光感受器低通滤波器效果相关的空间常数。这些参数指定了后续允许的空间信号周期的最小值。通常,此滤波器应消除高频噪声。另一方面,0值不消除任何噪声,而较高的值开始消除高空间频率,并逐渐消除较低的频率……如果您想查看输入图像的一些细节,请注意不要将值设置得太高!对于彩色图像,一个好的折衷值为0.53,因为这种选择不会过多地影响颜色频谱。较高的值会导致灰度和模糊的输出图像。
水平细胞参数
此参数集调整连接到感光细胞(水平细胞)的神经网络。它调节感光细胞的灵敏度,并完成最终光谱白化处理(空间带通效应的一部分,因此有利于视觉细节增强)。
- horizontalCellsGain 是一个关键参数!如果您不关心平均亮度,只想关注细节增强,则将此参数设置为零。但是,如果您想保留一些环境亮度数据,让一些低空间频率进入系统,则设置较高的值(<1)。
- hcellsTemporalConstant 与感光细胞类似,此参数作用于低通时间滤波器的时常数,该滤波器平滑输入数据。此处,较高的值会产生较高的视网膜后效应,而较低的值则使视网膜更具反应性。此值应低于photoreceptorsTemporalConstant 以限制强烈的视网膜后效应。
- hcellsSpatialConstant 是这些细胞滤波器的低通滤波器的空间常数。它指定后续允许的最低空间频率。视觉上,较高的值会导致非常低的空间频率处理,并导致明显的晕影效应。较低的值会减少这种效应,但其限制是不低于photoreceptorsSpatialConstant 的值。这两个参数实际上指定了视网膜的空间带通。
注意 在由前面参数管理的处理完成后,输入数据已去除噪声,亮度也已部分增强。以下参数作用于两个输出视网膜信号的最后处理阶段。
Parvo(细节通道)专用参数
- ganglionCellsSensitivity 指定此细节专用通道输出处发生的最终局部适应的强度。参数值保持在 0 和 1 之间。低值倾向于给出线性响应,而较高的值则增强剩余的低对比度区域。
注意:此参数可以通过偏向视觉场景中低能量细节(即使在明亮区域)来校正可能的烧焦图像。
IPL Magno(运动/瞬态通道)参数
一旦图像信息被清理,此通道充当高通时间滤波器,
仅选择与瞬态信号(事件、运动等)相关的信号。低通空间滤波器平滑提取的瞬态数据,而最终的对数压缩则增强低瞬态事件,从而增强事件灵敏度。
- parasolCells_beta 通常设置为零,可以视为此处理阶段入口处的放大器增益。通常设置为 0。
- parasolCells_tau 可以添加的时间平滑效果
- parasolCells_k 空间滤波效果的空间常数,将其设置为高值以偏向低空间频率信号,这些信号更容易受到残余噪声的影响。
- amacrinCellsTemporalCutFrequency 指定高通滤波器的时常数。较高的值允许选择慢瞬态事件。
- V0CompressionParameter 指定对数压缩的强度。与之前的描述类似的行为,但此处增强了瞬态事件的灵敏度。
- localAdaptintegration_tau 通常设置为 0,实际上在这里没有实际用途。
- localAdaptintegration_k 指定执行局部适应的区域大小。低值导致短程局部适应(对噪声的灵敏度更高),高值确保对数压缩。
演示和实验!
首次实验
以下是一些代码片段,简要展示如何使用具有默认参数(带晕影效果)的视网膜。下一节将跳转到主视网膜类提供的更完整的演示。
此处介绍了如何使用以下步骤处理网络摄像头流:
- 加载第一个输入图像以获取其大小
- 使用适当的输入大小分配视网膜实例
- 遍历抓取的帧
- 抓取新帧
- 运行帧
- 调用两个输出获取器
- 显示视网膜输出
C++ 版本(参见 bioinspired/samples/basicRetina.cpp)
#include <iostream>
int main(
int argc,
char* argv[]) {
videoCapture>>inputFrame;
myRetina->write("RetinaDefaultParameters.xml");
myRetina->setup("RetinaSpecificParameters.xml");
myRetina->clearBuffers();
while(true){
if (videoCapture.isOpened())
videoCapture>>inputFrame;
else
break;
imshow('input frame', inputImage)
myRetina->run(inputFrame);
myRetina->getParvo(retinaOutput_parvo);
myRetina->getMagno(retinaOutput_magno);
}
}
MatSize size
定义 mat.hpp:2177
用于从视频文件、图像序列或摄像机捕获视频的类。
定义 videoio.hpp:766
void imshow(const String &winname, InputArray mat)
在指定的窗口中显示图像。
int waitKey(int delay=0)
等待按下键。
int main(int argc, char *argv[])
定义 highgui_qt.cpp:3
使用以下命令编译此 C++ 代码:
// 编译
g++ basicRetina.cpp -o basicRetina -lopencv_core -lopencv_highgui -lopencv_bioinspired -lopencv_videoio -lopencv_imgcodecs
Python 版本
import cv2 as cv
succeed, inputImage=videoHandler.read()
retina = cv.bioinspired_Retina.create((inputImage.shape[1], inputImage.shape[0]))
retina.write('retinaParams.xml')
retina.setup('retinaParams.xml')
stillProcess=True
while stillProcess is True
stillProcess, inputImage=videoHandler.read()
retina.run(inputImage)
retinaOut_parvo=retina.getParvo()
retinaOut_magno=retina.getMagno()
更完整的演示
- 注意
- 作为以下示例的补充,请查看教程/contrib部分中的视网膜教程,以获取补充说明。**
查看OpenCV提供的C++示例
samples/cpp/retinademo.cpp演示了如何使用视网膜模块进行细节增强(Parvo通道输出)和瞬态图观察(Magno通道输出)。您可以使用图像、视频序列和网络摄像头视频。典型用途是(假设您的OpenCV安装位于OpenCVReleaseFolder文件夹中)
- 图像处理:OpenCVReleaseFolder/bin/retinademo -image myPicture.jpg
- 视频处理:OpenCVReleaseFolder/bin/retinademo -video myMovie.avi
- 网络摄像头处理:OpenCVReleaseFolder/bin/retinademo -video
- 注意
- 此演示生成文件RetinaDefaultParameters.xml,其中包含视网膜的默认参数。然后,将其重命名为RetinaSpecificParameters.xml,根据需要调整参数,然后重新加载程序以检查效果。
samples/cpp/OpenEXRimages_HDR_Retina_toneMapping.cpp 演示了如何使用视网膜模型进行高动态范围 (HDR) 亮度压缩。
然后,使用相机括号法拍摄HDR图像并生成OpenEXR图像,然后使用演示程序进行处理。
典型用法,假设您有OpenEXR图像,例如memorial.exr(位于samples/cpp/文件夹中)
OpenCVReleaseFolder/bin/OpenEXRimages_HDR_Retina_toneMapping memorial.exr [可选:'fast']
请注意,提供了一些滑块,允许您调整亮度压缩。
如果不使用“fast”选项,则色调映射将使用完整的视网膜模型[24]执行。它包括光谱白化,允许降低亮度能量。使用“fast”选项时,将使用一种更简单的方法,它是[191]中提出的算法的改编版本。此方法也能获得良好的结果,并且处理速度更快,但有时需要更多参数调整。