专题一:欧拉视频放大(线性)------MATLAB代码解析(二.amplify_spatial_lpyr_temporal_iir())

代码及其注释

function amplify_spatial_lpyr_temporal_iir(vidFile, resultsDir, ...
            alpha, lambda_c, r1, r2, chromAttenuation)
 % ~ 在这里表示忽略输出参数,在这里为什么不涉及扩展名?
    [~,vidName] = fileparts(vidFile);%从结果上我们可以看到只提取了名字,并没有提取到后缀
    outName = fullfile(resultsDir,[vidName '-iir-r1-' num2str(r1)...
        '-r2-' num2str(r2)...
        '-alpha-' num2str(alpha) ...
        '-lambda_c-' num2str(lambda_c) ...
        '-chromAtn-' num2str(chromAttenuation) '.avi']);

    % Read video
    vid = VideoReader(vidFile);%创建对象vid,其中括号里的是该对象读取的视频路径
    % Extract video info 获取视频信息
    vidHeight = vid.Height;
    vidWidth = vid.Width;
    nChannels = 3;
    fr = vid.FrameRate;
    len = vid.NumberOfFrames;
    temp = struct('cdata', ...
		  zeros(vidHeight, vidWidth, nChannels, 'uint8'), ...
		  'colormap', []);%这里的数据存在空矩阵里还是零矩阵里


    startIndex = 1;
    endIndex = len-10;%为什么去掉结尾的十帧

    vidOut = VideoWriter(outName);%创建一个视频对象vidOut同时对其进行命名为outName,可以将若干图像转换为视频


    vidOut.FrameRate = fr;

    open(vidOut)

    % firstFrame
    temp.cdata = read(vid, startIndex);%获取该视频对象的第一帧的所有数据
    
    [rgbframe,~] = frame2im(temp);%将得到的第一帧的帧数据转化为图像数据 frame2im将电影帧转换为索引图像。
%[x,map]=frame2im(f)将单个电影帧f转换为索引图像x和关联的颜色映射。电影帧是getframe或im2frame的结果。如果帧包含TrueColor数据,则映射为空。

    rgbframe = im2double(rgbframe);%常用的是im2double函数,将uint8图像转为double类型,范围为0-1,如果是255的图像,那么255转为10还是0,中间的做相应改变。
    
    frame = rgb2ntsc(rgbframe);%yiqmap=rgb2ntsc(rgbmap)将rgbmap中的m-by-3 rgb值转换为ntsc颜色空间。Yiqmap是一个m-by-3矩阵,其中包含NTSC亮度(Y)和色度(I和Q)颜色分量,这些分量作为等同于RGB颜色映射中颜色的列。
                               %yiq=rgb2ntsc(rgb)将TrueColor图像rgb转换为等效的ntsc图像yiq。
                               
    [pyr,pind] = buildLpyr(frame(:,:,1),'auto');%pyr列向量696325*1,1个元素是拉普拉斯金字塔的第8层(最底层)960*540[1 1]元素,第696325个元素是第一层(最高层)8*5[8 5]元素
                                                %pind各层大小
                                         %拉普拉斯金字塔的第2到第8层都是高斯金字塔同层减去上采样图像,但是拉普拉斯金字塔的第一层就是高斯金字塔,第一层不进行下采样,不进行相减操作。
    pyr = repmat(pyr,[1 3]);
    [pyr(:,2),~] = buildLpyr(frame(:,:,2),'auto');
    [pyr(:,3),~] = buildLpyr(frame(:,:,3),'auto');
    
    lowpass1 = pyr;
    lowpass2 = pyr;

    output = rgbframe;
    %im2uint8用于将归一化到01之间(im2double 处理后的图像)转换为uint8类型
    writeVideo(vidOut,im2uint8(output));

    nLevels = size(pind,1);

    for i=startIndex+1:endIndex
        %progmeter里没有执行任何操作
            progmeter(i-startIndex,endIndex - startIndex + 1);
            %从第二帧重复第一帧的操作,读取帧数据,frame2im将电影帧转换为索引图像,归一化,将TrueColor图像rgb转换为等效的ntsc图像yiq
            temp.cdata = read(vid, i);
            [rgbframe,~] = frame2im(temp);

            rgbframe = im2double(rgbframe);
            frame = rgb2ntsc(rgbframe);
            %构造三通道拉普拉斯金字塔
            [pyr(:,1),~] = buildLpyr(frame(:,:,1),'auto');
            [pyr(:,2),~] = buildLpyr(frame(:,:,2),'auto');
            [pyr(:,3),~] = buildLpyr(frame(:,:,3),'auto');
            
            % temporal filtering
            % 等号右边的lowpass1,lowpass2是第一帧的拉普拉斯金字塔,pyr是第二帧的拉普拉斯金字塔
            lowpass1 = (1-r1)*lowpass1 + r1*pyr;
            lowpass2 = (1-r2)*lowpass2 + r2*pyr;

            filtered = (lowpass1 - lowpass2);
            
            
            %% amplify each spatial frequency bands according to Figure 6 of our paper
            ind = size(pyr,1);

            delta = lambda_c/8/(1+alpha);
            
            % the factor to boost alpha above the bound we have in the
            % paper. (for better visualization)
            
            exaggeration_factor = 2;

            % compute the representative wavelength lambda for the lowest spatial 
            % freqency band of Laplacian pyramid
            %计算拉普拉斯金字塔最低空间频率带的代表波长lambda
            %第一帧不放大 从第二帧开始放大 空间波长等于对角线长度除以3?
            lambda = (vidHeight^2 + vidWidth^2).^0.5/3; % 3 is experimental constant
            %注意不要把l和1弄混
            for l = nLevels:-1:1
              indices = ind-prod(pind(l,:))+1:ind;
              % compute modified alpha for this level
              currAlpha = lambda/delta/8 - 1;
              currAlpha = currAlpha*exaggeration_factor;
              
              if (l == nLevels || l == 1) % ignore the highest and lowest frequency band
                  filtered(indices,:) = 0;
              elseif (currAlpha > alpha)  % representative lambda exceeds lambda_c
                  filtered(indices,:) = alpha*filtered(indices,:);
              else
                  filtered(indices,:) = currAlpha*filtered(indices,:);
              end

              ind = ind - prod(pind(l,:));
              % go one level down on pyramid, 
              % representative lambda will reduce by factor of 2
              %拉普拉斯金子塔每下降一层,lambda就折一半
              lambda = lambda/2; 
            end
            
            
            %% Render on the input video
            output = zeros(size(frame));
            
            output(:,:,1) = reconLpyr(filtered(:,1),pind);
            output(:,:,2) = reconLpyr(filtered(:,2),pind);
            output(:,:,3) = reconLpyr(filtered(:,3),pind);
            %抑制颜色通道,相对的就放大了亮度通道
            output(:,:,2) = output(:,:,2)*chromAttenuation; 
            output(:,:,3) = output(:,:,3)*chromAttenuation;
            %放大的视频加上原始的视频
            output = frame + output;
            %转RGB颜色模型
            output = ntsc2rgb(output); 
%filtered = rgbframe + filtered.*mask;
           %矫正一些超出归一化的值 
            output(output > 1) = 1;
            output(output < 0) = 0;
           %im2uint8用于将归一化到01之间(im2double 处理后的图像)转换为uint8类型
            writeVideo(vidOut,im2uint8(output));%将帧写入视频,第一个参数是视频对象,第二个参数是视频的各帧
            
            
                      
    end
    close(vidOut);
end

理解

首先这个函数算是欧拉放大的核心代码之一了,博主在里面加了不少的注释。
我们把该段代码再来捋一遍,先是读取视频,用fileparts找到视频的名称,用outName设定输出视频的路径名称扩展名等,这里不多说。接着读取第一帧用以获取该视频文件的第一帧,并且构造拉普拉斯金子塔。然后用一个循环结构,从第二帧开始进入滤波的操作。这里的滤波器用的是差分方程直接构造的,并没有设计什么巴特沃斯切比雪夫之类的滤波器。滤波之后就是放大处理。随着空间频率的增加,放大因子也在不断变小。至于里面放大的公式我还一知半解。期待下回解析。最后把处理好的视频帧叠加到输出视频文件里。下面的图是该代码里用的滤波器,用的是两个低通滤波器的差。
在这里插入图片描述

  • 8
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值