多维小波变换

7
我发现了这篇惊人的回答《如何多次使用 MATLAB 的 idwt2 函数》,我执行了一下以便理解。但是,我不知道如何将其用于 RGB 图像处理。所以,我有3个问题。

  1. 如何将该代码应用于 RGB 图像,并且仅在输出中显示变换后的图像,包括沿行和列的高低频分量,是否可以将所有分量的融合视为单个图像?我知道我必须使用“cat”运算符,但我不知道如何操作。

  2. 其次,我还得到了一个迷宫般的图像!我感到困惑,因为我似乎无法理解原因。我还附上了相同的代码和生成此图像的语句。

    3.函数签名中的术语 db1dwt 函数中表示什么意思?

代码:

    load woman;             % Load image data
%startImage=imread('pic_rgb.jpg');  % IF I WANT TO WORK WITH RGB IMAGE
    nLevel = 3;             % Number of decompositions
    nColors = size(map,1);  % Number of colors in colormap
    cA = cell(1,nLevel);    % Approximation coefficients
    cH = cell(1,nLevel);    % Horizontal detail coefficients
    cV = cell(1,nLevel);    % Vertical detail coefficients
    cD = cell(1,nLevel);    % Diagonal detail coefficients
    startImage = X;
    for iLevel = 1:nLevel,
      [cA{iLevel},cH{iLevel},cV{iLevel},cD{iLevel}] = dwt2(startImage,'db1');



     startImage = cA{iLevel};
    end

    figure;colormap(map);
    imagesc(dwt2(startImage,'db1')); %THIS GIVES THE MAZED IMAGE INSTEAD OF THE TRANSFORMED IMAGE
    figure;
    tiledImage = wcodemat(cA{nLevel},nColors);
    for iLevel = nLevel:-1:1,
     tiledImage = [tiledImage                   wcodemat(cH{iLevel},nColors); ...
                    wcodemat(cV{iLevel},nColors) wcodemat(cD{iLevel},nColors)];

    end
    figure;

    imshow(tiledImage,map);

    %reconstruct
    fullRecon = cA{nLevel};
    for iLevel = nLevel:-1:1,
      fullRecon = idwt2(fullRecon,cH{iLevel},cV{iLevel},cD{iLevel},'db1');
    end
    partialRecon = cA{nLevel};
    for iLevel = nLevel:-1:1,
      partialRecon = idwt2(partialRecon,[],[],[],'db1');
    end
    figure;
    imshow([X fullRecon; partialRecon zeros(size(X))],map,...
           'InitialMagnification',50);

你今天早些时候不是已经问过这个问题了吗?我再也看不到原来的问题了 - 你是删除并重新发布了吗? - Paul R
1
是的,我已经发了,但整整一天都没有被注意到和回复。所以,我猜也许要重新发布一遍来突出它。如果您至少能够摆脱一些答案,而不是再次重新编辑它,那将会非常有帮助,尽管我已经保留了您之前编辑过的版本。感谢额外的努力! - Ria George
2
我所做的只是修复标签 - 我并没有编辑问题本身。以后参考一下,如果你没有得到任何回应,应该尝试改进原始问题,而不是重新发布。 - Paul R
@RiaGeorge 我已经删除了有关上传图片需要声望要求的部分。现在您已经拥有足够的声望,请上传它。如果您在任何时候没有足够的声望来上传图片,请仍然添加链接,有足够声望的人将为您编辑。 - Adriaan
1个回答

9
在我的另一个答案中使用的示例图像是索引图像,因此需要进行一些更改,以使该代码适用于RGB图像。首先要解决的问题是有关传递给DWT2'db1'参数的问题。这指定了用于分解的小波类型(在这种情况下为Daubechies小波)。有关可用小波的更多信息可以在WFILTERSWAVEINFO函数的文档中找到。接下来,我将通过向您展示如何修改我的其他答案中的代码,以便适用于RGB图像来回答您的前两个问题。我将使用示例'peppers.png'图像。首先要加载图像并定义每个颜色组件的值的数量。由于示例图像是无符号8位整数类型(最常见的情况),因此nColors为256:
X = imread('peppers.png');  %# Load sample image
nColors = 256;              %# Number of values per color component

如果你的图像是更大的无符号整数类型(例如 'uint16'),找到颜色值的通用方法是使用函数INTMAX,如下所示:

nColors = double(intmax(class(X)))+1;

对于下面的代码,假设图像类型为'uint8'

应用分解与索引图像情况下没有区别。系数矩阵只是M×N×3矩阵而不是M×N矩阵:

nLevel = 3;             %# Number of decompositions
cA = cell(1,nLevel);    %# Approximation coefficient storage
cH = cell(1,nLevel);    %# Horizontal detail coefficient storage
cV = cell(1,nLevel);    %# Vertical detail coefficient storage
cD = cell(1,nLevel);    %# Diagonal detail coefficient storage
startImage = X;
for iLevel = 1:nLevel,  %# Apply nLevel decompositions
  [cA{iLevel},cH{iLevel},cV{iLevel},cD{iLevel}] = dwt2(startImage,'db1');
  startImage = cA{iLevel};
end

由于我们现在处理的是三维矩阵,所以创建平铺图以显示每个分解的水平、垂直和对角线分量的代码将发生变化,必须使用CAT函数而不是连接运算符[]

tiledImage = wcodemat(cA{nLevel},nColors);
for iLevel = nLevel:-1:1
  tiledImage = cat(1,cat(2,tiledImage,...
                           wcodemat(cH{iLevel},nColors)),...
                     cat(2,wcodemat(cV{iLevel},nColors),...
                           wcodemat(cD{iLevel},nColors)));
end
figure;
imshow(uint8(tiledImage-1));  %# Convert to unsigned 8-bit integer to display

这将生成以下图像,显示每个分解步骤的水平(右上)、垂直(左下)和对角线(右下)分量,以及缩小的图像(左上): enter image description here 重建步骤与其他答案相同。仅需要修改用于显示最终图像的代码。
fullRecon = cA{nLevel};
for iLevel = nLevel:-1:1,
  fullRecon = idwt2(fullRecon,cH{iLevel},cV{iLevel},cD{iLevel},'db1');
end
partialRecon = cA{nLevel};
for iLevel = nLevel:-1:1,
  partialRecon = idwt2(partialRecon,[],[],[],'db1');
end
figure;
tiledImage = cat(1,cat(2,X,uint8(fullRecon)),...
                   cat(2,uint8(partialRecon),zeros(size(X),'uint8')));
imshow(tiledImage,'InitialMagnification',50);

您将获得一张图像,显示原始RGB图像(左上角),使用所有存储的详细系数矩阵进行完全重建的图像(右上角)以及不使用任何存储的详细系数矩阵进行部分重建的图像(左下角):

谢谢,但是是否也可以仅查看最终分解的图像而排除所有组件?只显示Peppers图像的小波变换的一个平铺图像。此外,变量X似乎是内置的,这意味着除了使用X之外,没有其他变量起作用。 - Ria George
@Ria:您可以通过以下方式查看转换后的图像:imshow(uint8(wcodemat(cA{N},nColors)-1));N 的值分别为 1、2 或 3,具体取决于您想查看已分解一次、两次或三次的图像。X 只是我选择存储图像数据的变量。您可以轻松地将代码中的 X 替换为任何您想要称呼该变量的名称。 - gnovice
我在第一个for循环后加入了上述代码行。但是它显示的是原始图像,而不是转换后的图像。我尝试过不同级别的N,但都只给出原始图像。 :( - Ria George
@Ria:你确定它显示的是原始图像吗?你可能认为它显示的是原始图像,但每个转换后的图像实际上都是原始图像的缩小版,每次小波变换时图像大小都会减小2。 - gnovice
是的,它与原始图像完全相同。实际上,我想查看在进行快速傅里叶变换时输出的结果。因此,在这种情况下,输出应该是平铺结果中显示的任何一个图像吗? - Ria George
能否一次查看所有组件?回复一下将会非常有帮助。 - Ria George

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接