两个图像修复案例

来源:互联网 发布:mac 充电iphone 好快 编辑:程序博客网 时间:2024/04/29 04:58

1.图像修复

clc;clear all;close all
I=imread('1.jpg');
[m,n,hh]=size(I);
A=rgb2gray(I);
I1=I;th = 11;
[rowind,columnind]=find(A<th);
pointnum=length(rowind);
% 区域范围
rowstart=rowind-20;
rowend=rowind+20;
rowstart(rowstart<1)=1;
rowend(rowend>m)=m;
columnstart=columnind-20;
columnend=columnind+20;
columnstart(columnstart<1)=1;
columnend(columnend>n)=n;
% 遍历
for num=1:pointnum
    x=rowind(num);
    y=columnind(num);   
    xstart=rowstart(num);
    xend=rowend(num);
    x1=x-xstart+1;
    ystart=columnstart(num);
    yend=columnend(num);
    y1=y-ystart+1;
    % 取出来区域范围内像素
    depthpos=A(xstart:xend,ystart:yend)>th;
    [locind1,locind2]=find(depthpos);
    W=(locind1-x1).*(locind1-x1)+(locind2-y1).*(locind2-y1)+1;    
    TT=1./W;
    T=sum(TT); 
    Aloc=I(xstart:xend,ystart:yend,1);
    Aloc=double(Aloc(depthpos));
    R=Aloc.*TT;
    R=sum(R);
    I1(x,y,1)=R/(T+0.1);
    % 替代值
    Aloc=I(xstart:xend,ystart:yend,2);
    Aloc=double(Aloc(depthpos));
    R=Aloc.*TT;
    R=sum(R);
    I1(x,y,2)=R/(T+0.1);
    % 对不同层进行替代
    Aloc=I(xstart:xend,ystart:yend,3);
    Aloc=double(Aloc(depthpos));
    R=Aloc.*TT;
    R=sum(R);
    I1(x,y,3)=R/(T+0.1);
end
figure,imshow(I,[]);title('污染图');
figure,imshow(I1,[]);title('去污图');



2.二维码图像复原

main function

clc; clear all; close all;
% 载入图像
I = imread('./图像/模糊.jpg');
% 灰度化
if ndims(I) == 3
    Img = rgb2gray(I);
else
    Img = I;
end
% 计算SNR
snr1 = ComputeSNR(I);
% 初始化
snr = 0;I = Img;k = 0;
% 迭代循环处理
while snr < 60 && k < 10
    % 估计PSF
    [J, psf] = ComputePSF(I, 4, 0.58, 1);
    % 计算SNR
    snr2 = ComputeSNR(J);
    %  维纳滤波复原
    J =  WienerFilter(I, J, psf, snr2);
    % 计算复原图像的SNR
    snr = ComputeSNR(J);
    % 更新图像
    I = J;
    % 更新次数
    k = k + 1;
end
% 打印结果
fprintf('\n原图像snr为%.3f,复原图像snr为%.3f\n', snr1, snr);


function snr = ComputeSNR(I)
% 计算SNR
% 设置默认参数

if nargin < 1
    I = imread('./图像/模糊(轻).jpg');
    % 灰度化
    if ndims(I) == 3
        I = rgb2gray(I);
    end
end
% 图像块扫描
Lv = blockproc(I, [5 5], @GetLocVar);
% 利用图像平均值与局域图像的方差的极大值之比来计算信噪比
b = mean(I(:))/sqrt(max(Lv(:)));
% 公式优化
snr = 75/b + 5;
% 计算块方差
function v = GetLocVar(block_struct)
% 数值矩阵
im = double(block_struct.data);
% 计算方差
v  = var(im(:));


function [J, psf] = ComputePSF(I, num, th, tag)
% 计算PSF
% 参数设置
% 针对于两幅实验图像,1----轻、2----重

if nargin < 4
    tag = 2;
end
% 针对于两幅实验图像,提取边缘Sobel算子阈值
if nargin < 3
    if tag == 1
        th = 0.58;
    else
        th = 0.2;
    end
end
% 针对于两幅实验图像,盲去卷积复原的迭代次数
if nargin < 2
    if tag == 1
        num = 4;
    else
        num = 8;
    end
end
% 设置默认参数
if nargin < 1
    if tag == 1
        I = imread('./图像/模糊(轻).jpg');
    else
        I = imread('./图像/模糊(重).jpg');
    end
    % 灰度化
    if ndims(I) == 3
        I = rgb2gray(I);
    end
end
% 根据处理的图片标记,设置初始化PSF的维数
if tag==1
    sz = 10;
else
    sz=8;
end
% 图像复原
INITPSF = ones(sz); % 获取函数的特征
% 盲卷积,保留使用的PSF
if tag == 1
    [J, P]= deconvblind(I, INITPSF, 3);
else
    [J, P]= deconvblind(I, INITPSF, 5);
end
% sobel算子提取边缘
WEIGHT = edge(I, 'sobel', th);
se1 = strel('disk',1);
se2 = strel('line',5,15);
% 膨胀操作,边界像素设为零
WEIGHT = ~imdilate(WEIGHT,[se1 se2]);
% 保存数据
P1 = P;
% 修改PSF函数
P1(P1 < 0.01)=0;
% 利用上面得到的WEIGHT进行盲卷积
[J, psf] = deconvblind(I,P1,num,[],double(WEIGHT));
% 显示PSF
figure; imshow(psf, [],'InitialMagnification','fit');title('PSF视图');


function R =  WienerFilter(I, J, psf, snr)
% 维纳滤波器复原
% 判断条件,维纳滤波

if snr < 60
    R =  deconvwnr(I, psf, snr);
else
    R = J;
end
S = histeq(I);
% 显示结果
figure;
subplot(1, 3, 1); imshow(I, []); title('原图像');
subplot(1, 3, 2); imshow(S, []); title('增强图像');
subplot(1, 3, 3); imshow(R, []); title('复原图像');