二维反卷积的实现(实际意义不明确)

前言

一维反卷积(deconv),可以很好的实现一维卷积的反过程!但是二维反卷积就很难恢复了!为什么呢?因为我们知道二维卷积计算的过程就是:卷积核不断滑动,卷积核不断与原始数据中的小矩阵做"点乘并求和";现假设卷积核为3x3,那么每一个和它点乘的小矩阵对应尺寸也是3x3。现在我们只知道"卷积核里的9个数"和这两个小矩阵"卷积操作后"的"一个"数值结果!也就说是"小矩阵里的9个元素"都还是"未知的"!这个方程没办法解的,也就没办法恢复原矩阵的。

网上关于二维反卷积实现的方法

这里的二维反卷积更像是一种别的操作,它已经不符合"(一维)卷积与反卷积的定义了!所以这种操作的"实际意义也还不明确"(Matlab中也没有自带的相关命令)。本文纯粹是把其方法实现,不深究其结果和意义。

首先二维反卷积的输入是"二维卷积处理后的图像矩阵",卷积核还是"原先的卷积核"。二维反卷积分两步:1. 预处理:卷积核翻转180°,原始图像矩阵每个元素扩0边,操作如图1所示;2. 卷积计算,操作如这里所示。

图1:预处理操作

Matlab编程实现

可以看出二维反卷积操作其实非常简单,其对应的处理一张二维图片矩阵的操作如下(这里是对3通道的彩图处理的):

clc; clear;

% 卷积核
k = [1 1 1;1 -8 1;1 1 1];      % "强边缘锐化"卷积核

data = imread('zxc.jpg');  % 数据——最好比卷积核的尺寸大
figure(1);
imshow(data);
data = double(data);
% 输入的数据:
data1 = data(:,:,1);
data2 = data(:,:,2);
data3 = data(:,:,3);

% 二维卷积:
result1 = conv2(data1, k, 'same');
result2 = conv2(data2, k, 'same');
result3 = conv2(data3, k, 'same');
result = cat(3, result1, result2, result3);
figure(2);
image(result);

% 反卷积开始: 卷积和不变, 输入变成3个result
size_k = size(k);
bc = fix(size_k(1)/2)  % 单点周围扩大的边长
x = data1;
% x = [8 11 13 1 1 1 2;5 26 17 2 2 3 2;39 12 11 1 3 4 5]
size_x = size(x);
rowx = size_x(1);
colx = size_x(2);

% 扩展后尺寸:
kz1 = zeros(rowx+(rowx-1)*bc+bc*2,colx+(colx-1)*bc+bc*2);
kz2 = zeros(rowx+(rowx-1)*bc+bc*2,colx+(colx-1)*bc+bc*2); 
kz3 = zeros(rowx+(rowx-1)*bc+bc*2,colx+(colx-1)*bc+bc*2); 
% 注意上式扩边的写法,为了保证通用性(任意扩边长度均可实现)
size_kz = size(kz1);
rowkz = size_kz(1);
colkz = size_kz(2);

% 将原数值按对应位置插回去:
fprintf('反卷积拓边开始:\n')
countn = 1;
countm = 1; % 行与列的计数器(方便理解)
mtmp = bc*countm;
ntmp = bc*countn; % 这两个临时变量是记录x原数据的坐标 
for m = bc+1:bc+1:rowkz
    for n = bc+1:bc+1:colkz
        kz1(m,n) = x(m-mtmp,n-ntmp);  % 对应位置插进去
        kz2(m,n) = x(m-mtmp,n-ntmp);
        kz3(m,n) = x(m-mtmp,n-ntmp);
        countn = countn + 1;
        ntmp = bc*countn;
    end
    countm = countm + 1;
    mtmp = bc*countm;
    % 列序号记得恢复(因为列的新一轮开始了)
    countn = 1;
    ntmp = bc*countn;
end

% 卷积(反卷积中的一步):
fprintf('反卷积中卷积开始:\n')
fresult1 = zeros(rowkz,colkz);
fresult2 = zeros(rowkz,colkz);
fresult3 = zeros(rowkz,colkz);
k = rot90(rot90(k));
for mm = bc+1:rowkz-bc
    for nn = bc+1:colkz-bc
        t1 = kz1(mm-bc:mm+bc,nn-bc:nn+bc);
        t2 = kz2(mm-bc:mm+bc,nn-bc:nn+bc);
        t3 = kz3(mm-bc:mm+bc,nn-bc:nn+bc);
        fjuan1 = sum(k.*t1);
        fjuan2 = sum(k.*t2);
        fjuan3 = sum(k.*t3);
        fresult1(mm,nn) = sum(fjuan1(:));
        fresult2(mm,nn) = sum(fjuan2(:));
        fresult3(mm,nn) = sum(fjuan3(:));
    end
end

fresult1 = fresult1(bc:rowkz-bc,bc:colkz-bc);
fresult2 = fresult2(bc:rowkz-bc,bc:colkz-bc);
fresult3 = fresult3(bc:rowkz-bc,bc:colkz-bc);

fresult = cat(3, fresult1, fresult2, fresult3);
figure(3);
imshow(fresult)

结果图没什么意义,就不展示了。"zxc.jpg"图片在这里。

你可能感兴趣的:(二维反卷积的实现(实际意义不明确))