0

我正在尝试使用MATLAB的cvx 库来实现图像的压缩感知。这与 Steve Brunton 在此处的示例中使用的库相同。我的测试图像是Lenna

这是我的 MATLAB 脚本:

close all; clear; clc

% read in an image
lenna = imread('lenna.png');
X = lenna(:, :, 2); % greem channel only
X = X(200:249, 100:149); % just a chunk
M = size(X, 1); N = size(X, 2);
x = vectorify(X);

figure, subplot(1, 3, 1), imshow(X), title(strcat("Original Image: ", num2str(M), " by ", num2str(N), " Pixels"))

% Sample randomly
K = 80; %number of random sampled pixels
c = randsample(numel(X), K); %locations of pixels as a list
y = x(c); %values
C = zeros(K, numel(X)); %C(c) = y;%(1:K);
Y = zeros(M, N); % there must be a more elegant way to do this...
for k=1:K
    C(k, c(k)) = y(k);
    Y2 = rectanglefy(C(k, :), M, N);
    Y=Y+Y2;
end
% Y=rectanglefy(C, M, N)
C = C>0; %convert C to a binary matrix
C = double(C); %cast
subplot(1, 3, 2), imshow(Y/255), title(strcat(num2str(K), ' Sampled Pixels'))


% Solve for sparse representation
psi = dftmtx(M*N); psi=real(psi);
Theta = C*psi; n = M*N;

Theta = double(Theta); y = double(y); %cast required
cvx_begin;
    variable s_L1(n)
    minimize( norm(s_L1, 1) );
    subject to
        Theta * s_L1 ==y; 
cvx_end

xr = psi*s_L1;
Xr = rectanglefy(xr, M, N);
subplot(1, 3, 3), imshow(Xr/255), title('Reconstructed Image')

function x = vectorify(X)
    x = reshape(X, [numel(X), 1]);
end

function X = rectanglefy(x, M, N)
    X = reshape(x, [M, N]);
end

当我使用 K=80 运行它时,它能够重建图像,虽然它当然不是很接近真实的东西: 50x50 像素的图像重建,具有 80 个随机采样的像素。

但是,如果我将样本数量增加到 800 - 我希望这会使结果更接近 - 求解器告诉我这是不可行的: 尝试使用 800 个随机采样像素重建图像,并在命令窗口中显示来自 cvx 求解器的文本,说明求解不可行。

在这两者之间,如果我将 K 设置为 180 个随机样本,求解器会产生“失败”,这显然与“不可行”的结果不同: 尝试使用 180 个随机采样像素重建图像,并在命令窗口中显示来自 cvx 求解器的文本,说明求解失败。

我不确定问题出在我的代码中还是我对凸优化的理解(相当差),但我的问题是:(a)为什么会发生这种情况?(b) 我应该做些什么来重建这个图像?

4

1 回答 1

0

所以我有点像猿,在这方面没有太多经验,但我试图复制你的代码,到目前为止我得到了 2 个提示:

1:如果你像这样定义 cvx 部分,你会得到更好的结果(通过增加采样点会变得更好:

epsilon=0.01;
%Using the cvx
cvx_begin;
    variable s_L1(n) complex
    minimize( norm(s_L1, 1) );
    subject to
        norm(y - Theta*s_L1,2) <= epsilon; 
cvx_end

2:您将 2D 图像逐列转换为 1D 向量,这意味着您的第一个元素和第 51 个元素具有非常高的相关性。我想你最好使用 2d fft,像这样,但我不确定现在如何实现它。如果您仍然对该主题感兴趣,我很乐意分享我发现的任何内容。:)

希望有帮助。

于 2021-03-19T10:08:43.710 回答