Retinex系列之McCann99 Retinex

2023-10-29 09:59
文章标签 系列 retinex mccann99

本文主要是介绍Retinex系列之McCann99 Retinex,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、McCann99 Retinex

McCann99利用金字塔模型建立对图像的多分辨率描述,自顶向下逐层迭代,提高增强效率。对输入图像的长宽有

严格的限制,要求可表示成 ,且 

上述限制来源于金字塔模型的结构要求,由于要对输入图像进行下采样,金字塔中上层低分辨率图像的宽分别为下

层高分辨率图像的1/2,顶层(第n层)大小为,底层(第0层)为原图像。金字塔结构如下图所示。

McCann99算法对输入图像的尺寸要求过于严格,以至于大部分图像不能直接用此算法进行增强,后续有很多改进

措施,此处暂不考虑。

算法从顶层开始,将每个像素与其8领域像素比较,估计每个像素点的亮度值(lightness),比较的迭代次数nIterator

由用户决定,每次迭代有四步操作:比例(ratio)、乘积(product)、重置(reset)、平均(average)。随着迭代次数的增

大,像素受到邻域的影响范围就会扩大。每层计算结束后对该层所得图像进行插值运算,使其尺寸与下一层相同,并

将插值结果作为下一层处理的初始值。对下一层进行相同操作,这样自顶向下直至金字塔底层得到最终增强结果。

对每金字塔每一层:设OP为上一步迭代的乘积;NP为当前迭代的乘积;IP为中间乘积结果;R为该层输入图像;符号

*表示重置操作。其中对于每个像素执行的四步操作使用和Frankle-McCann相同的公式:

变量初始化:

金字塔层数由原始图像尺寸决定,大小为  ,层数为n+1;

OP初始尺寸为,各像素值一般设为原始图像中的最大值;

R:第k层输入图为像原始图像的下采样,大小为

迭代次数nIterator一般设为4;


图像金字塔模型


 二、Matlab实现

function Test()
ImOriginal=imread('fig5.tif');
[m,n,z] = size(ImOriginal);
ImOut = zeros(m,n,z);
for i = 1:zImChannel = log(double(ImOriginal(:,:,i))+eps);ImOut(:,:,i)=retinex_mccann99(ImChannel,4); ImOut(:,:,i)=exp(ImOut(:,:,i));a=min(min(ImOut(:,:,i)));b=max(max(ImOut(:,:,i)));ImOut(:,:,i)=((ImOut(:,:,i)-a)/(b-a))*255;     
end
ImOut=uint8(ImOut);
figure(1);
imshow(ImOriginal);
figure(2);
imshow(ImOut);function Retinex = retinex_mccann99(L, nIterations)
% INPUT:  L           - logarithmic single-channel intensity image to be processed
%         nIterations - number of Retinex iterations
%
% OUTPUT: Retinex     - raw Retinex output
global OPE RRE Maximum
[nrows ncols] = size(L);                             % get size of the input image
nLayers = ComputeLayers(nrows, ncols);               % compute the number of pyramid layers
nrows = nrows/(2^nLayers);                           % size of image to process for layer 0
ncols = ncols/(2^nLayers);
if (nrows*ncols > 25)                                % not processing images of area > 25error('invalid image size.')                       % at first layer
end
Maximum = max(L(:));                                 % maximum color value in the image
OP = Maximum*ones([nrows ncols]);                    % initialize Old Product
for layer = 0:nLayersRR = ImageDownResolution(L, 2^(nLayers-layer));   % reduce input to required layer sizeOPE = [zeros(nrows,1) OP zeros(nrows,1)];         % pad OP with additional columnsOPE = [zeros(1,ncols+2); OPE; zeros(1,ncols+2)];  % and rowsRRE = [RR(:,1) RR RR(:,end)];                     % pad RR with additional columnsRRE = [RRE(1,:); RRE; RRE(end,:)];                % and rowsfor iter = 1:nIterationsCompareWithNeighbor(-1, 0);                     % NorthCompareWithNeighbor(-1, 1);                     % North-EastCompareWithNeighbor(0, 1);                      % EastCompareWithNeighbor(1, 1);                      % South-EastCompareWithNeighbor(1, 0);                      % SouthCompareWithNeighbor(1, -1);                     % South-WestCompareWithNeighbor(0, -1);                     % WestCompareWithNeighbor(-1, -1);                    % North-WestendNP = OPE(2:(end-1), 2:(end-1));OP = NP(:, [fix(1:0.5:ncols) ncols]);             %%% these two lines are equivalent with OP = OP([fix(1:0.5:nrows) nrows], :);             %%% OP = imresize(NP, 2) if using Imagenrows = 2*nrows; ncols = 2*ncols;                 % Processing Toolbox in MATLAB
end
Retinex = NP;%将当前像素与八邻域比较
function CompareWithNeighbor(dif_row, dif_col)
global OPE RRE Maximum
% Ratio-Product operation
IP = OPE(2+dif_row:(end-1+dif_row), 2+dif_col:(end-1+dif_col)) + ...RRE(2:(end-1),2:(end-1)) - RRE(2+dif_row:(end-1+dif_row), 2+dif_col:(end-1+dif_col));     
IP(IP > Maximum) = Maximum;                          % The Reset step% ignore the results obtained in the rows or columns for which the neighbors are undefined
%因OPE边界处填充了0,故IP对应的边界处结果无意义,直接置成原值
if (dif_col == -1) IP(:,1) = OPE(2:(end-1),2); end
if (dif_col == +1) IP(:,end) = OPE(2:(end-1),end-1); end
if (dif_row == -1) IP(1,:) = OPE(2, 2:(end-1)); end
if (dif_row == +1) IP(end,:) = OPE(end-1, 2:(end-1)); endNP = (OPE(2:(end-1),2:(end-1)) + IP)/2;              % The Averaging operation
OPE(2:(end-1), 2:(end-1)) = NP;%power:nrows,ncols的最大公约数且是2的整数次方
function Layers = ComputeLayers(nrows, ncols)
power = 2^fix(log2(gcd(nrows, ncols)));              % start from the Greatest Common Divisor
while(power > 1 && ((rem(nrows, power) ~= 0) || (rem(ncols, power) ~= 0)))power = power/2;                                  % and find the greatest common divisor
end                                                  % that is a power of 2
Layers = log2(power);%下采样,将blocksize*blocksize区域映射为一个像素点
function Result = ImageDownResolution(A, blocksize)
[rows, cols] = size(A);                              % the input matrix A is viewed as
result_rows = rows/blocksize;                        % a series of square blocks
result_cols = cols/blocksize;                        % of size = blocksize
Result = zeros([result_rows result_cols]);
for crt_row = 1:result_rows                          % then each pixel is computed asfor crt_col = 1:result_cols                       % the average of each such blockResult(crt_row, crt_col) = mean2(A(1+(crt_row-1)*blocksize:crt_row*blocksize, ...1+(crt_col-1)*blocksize:crt_col*blocksize));end
end


测试结果:

输入

输出

注:输出时只是简单的进行线性拉伸,使得灰度值落在[0-255],没有使用更好调整方法。

参考:

http://www.cnblogs.com/sleepwalker/p/3676600.html

[1] J.J. McCann, “LessonsLearned from Mondrians Applied to Real Images and Color Gamuts”, Proc.IS&T/SID Seventh Color Imaging Conference, pp. 1-8, 1999.

[2] Brian Funt, FlorianCiurea, and John McCann "Retinex in Matlab," Proceedings of the IS&T/SIDEighth Color Imaging Conference: Color Science, Systems and Applications, 2000.

这篇关于Retinex系列之McCann99 Retinex的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/299903

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0

GPT系列之:GPT-1,GPT-2,GPT-3详细解读

一、GPT1 论文:Improving Language Understanding by Generative Pre-Training 链接:https://cdn.openai.com/research-covers/languageunsupervised/language_understanding_paper.pdf 启发点:生成loss和微调loss同时作用,让下游任务来适应预训

Java基础回顾系列-第七天-高级编程之IO

Java基础回顾系列-第七天-高级编程之IO 文件操作字节流与字符流OutputStream字节输出流FileOutputStream InputStream字节输入流FileInputStream Writer字符输出流FileWriter Reader字符输入流字节流与字符流的区别转换流InputStreamReaderOutputStreamWriter 文件复制 字符编码内存操作流(

Java基础回顾系列-第五天-高级编程之API类库

Java基础回顾系列-第五天-高级编程之API类库 Java基础类库StringBufferStringBuilderStringCharSequence接口AutoCloseable接口RuntimeSystemCleaner对象克隆 数字操作类Math数学计算类Random随机数生成类BigInteger/BigDecimal大数字操作类 日期操作类DateSimpleDateForma

Java基础回顾系列-第三天-Lambda表达式

Java基础回顾系列-第三天-Lambda表达式 Lambda表达式方法引用引用静态方法引用实例化对象的方法引用特定类型的方法引用构造方法 内建函数式接口Function基础接口DoubleToIntFunction 类型转换接口Consumer消费型函数式接口Supplier供给型函数式接口Predicate断言型函数式接口 Stream API 该篇博文需重点了解:内建函数式

Java基础回顾系列-第二天-面向对象编程

面向对象编程 Java类核心开发结构面向对象封装继承多态 抽象类abstract接口interface抽象类与接口的区别深入分析类与对象内存分析 继承extends重写(Override)与重载(Overload)重写(Override)重载(Overload)重写与重载之间的区别总结 this关键字static关键字static变量static方法static代码块 代码块String类特

Java基础回顾系列-第六天-Java集合

Java基础回顾系列-第六天-Java集合 集合概述数组的弊端集合框架的优点Java集合关系图集合框架体系图java.util.Collection接口 List集合java.util.List接口java.util.ArrayListjava.util.LinkedListjava.util.Vector Set集合java.util.Set接口java.util.HashSetjava