Stu*_*PhD 4 matlab image image-processing dct image-segmentation
我必须应用于dct2我的图像的小窗口,最好使用重叠窗口.
我发现,有在Matlab两种功能,可以使这一切成为可能blockproc和im2col.我也很难理解,并希望得到一些澄清.
blockproc可以用于使用BorderSize和TrimBorder参数在滑动窗口上实现我的函数.
B = blockproc(A,[64,64],fun,'BorderSize',[5,5], 'TrimBorder', 'false');
Run Code Online (Sandbox Code Playgroud)
我意识到这会创建一个块[64 + 2*5, 64 + 2*5]并@fun在每个块上应用该函数.但由于我无法@fun在调试中进入我的功能以验证正确的操作,我不能确定这是我需要的.我的上述代码是否符合我的要求?我知道我得到了一个连续的结果,B但它应该在一个重叠的滑块上.这会实现我的需求吗?
第二是im2col.im2col(A,[m n],block_type)将块分成m个n块并将它们排列成列,所以每列是一个块?如果是这样,重叠如何控制?如果每个块都是一列,我可以dct2在每列上成功应用该功能吗?因为我怀疑它会将向量作为输入吗?
一些澄清将不胜感激.
ray*_*ica 10
好的,这是一个非常复杂的问题.我会尝试将其分解为单独的部分,并将分别回答每个问题.
blockproc可以用于使用BorderSize和TrimBorder参数在滑动窗口上实现我的函数.
B = blockproc(A,[64,64],fun,'BorderSize',[5,5], 'TrimBorder', 'false');我意识到这会创建一个块
[64 + 2*5, 64 + 2*5]并@fun在每个块上应用该函数.但由于我无法@fun在调试中进入我的功能以验证正确的操作,我不能确定这是我需要的.我的上述代码是否符合我的要求?我知道我得到了一个连续的结果,B但它应该在一个重叠的滑块上.这会实现我的需求吗?
经过实验blockproc,这确实是正确的,您可以使用它来进行滑动邻域处理.但是,你需要一个额外的标志,这是PadPartialBlocks.此标志的目的是,如果要提取一个位于图像外边缘的块,并且无法生成指定大小的块,则将对此部分块进行零填充以使其符合大小相同.这是一个使用滑动窗口的小例子.假设我们有一个矩阵,以便:
>> A = reshape(1:25,5,5)
A =
1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19 24
5 10 15 20 25
Run Code Online (Sandbox Code Playgroud)
假设我们想要获取上面矩阵中每个3 x 3重叠邻域的平均值,并将那些超出矩阵边界的元素填零.你会这样做blockproc:
B = blockproc(A, [1 1], @(x) mean(x.data(:)), 'BorderSize', [1 1], 'TrimBorder', false, 'PadPartialBlocks', true);
Run Code Online (Sandbox Code Playgroud)
需要注意的重要一点是块大小,在这种情况下BorderSize为1 x 1,并且1 x 1的设置与您对3 x 3块的预期不同.为了解决这种情况的原因,我们需要进一步了解BorderSize工作原理.对于块的给定中心,BorderSize允许您捕获超出原始大小块的尺寸的值/像素.对于那些超出矩阵边界的位置,我们默认将这些位置填充为零. BorderSize允许我们2M + 2N更多地捕获像素,在哪里M以及N您想要的水平和垂直边框大小.这将允许我们捕获M原始块上方和下方的N更多像素以及原始块左侧和右侧的更多像素.
因此,对于1 in的值A,如果块大小是1 x 1,这意味着该元素仅包含1,如果我们BorderSize是1 x 1.这意味着我们的最终块将是:
0 0 0
0 1 6
0 2 7
Run Code Online (Sandbox Code Playgroud)
因为我们的块大小是1,所以下一个块将以6为中心,我们将获得3 x 3像素网格,依此类推.同样重要的TrimBorder是设置为false使得我们可以保留在块扩展时最初捕获的那些像素.默认设置为true.最后,PadPartialBlocks是true确保所有块都是相同的大小.运行上面的代码时,我们得到的结果是:
B =
1.7778 4.3333 7.6667 11.0000 8.4444
3.0000 7.0000 12.0000 17.0000 13.0000
3.6667 8.0000 13.0000 18.0000 13.6667
4.3333 9.0000 14.0000 19.0000 14.3333
3.1111 6.3333 9.6667 13.0000 9.7778
Run Code Online (Sandbox Code Playgroud)
您可以使用nlfilter我们可以将均值应用于3 x 3滑动邻域来验证我们得到相同的结果:
C = nlfilter(A, [3 3], @(x) mean(x(:)))
C =
1.7778 4.3333 7.6667 11.0000 8.4444
3.0000 7.0000 12.0000 17.0000 13.0000
3.6667 8.0000 13.0000 18.0000 13.6667
4.3333 9.0000 14.0000 19.0000 14.3333
3.1111 6.3333 9.6667 13.0000 9.7778
Run Code Online (Sandbox Code Playgroud)
因此,如果要正确使用blockproc滑动操作,则需要分别设置块大小和边框大小.在这种情况下,一般规则是始终将块大小设置为1 x 1,并允许BorderSize指定所需的每个块的大小.具体而言,对于大小的块K x K,你会设置BorderSize为floor(K/2) x floor(K/2)分别.如果K奇怪的话,它会让事情变得简单.
例如,如果您想5 x 5在滑动窗口的基础上进行平均过滤操作,则可以设置BorderSize为[2 2]as K = 5和floor(K/2) = 2.因此,你会这样做:
B = blockproc(A, [1 1], @(x) mean(x.data(:)), 'BorderSize', [2 2], 'TrimBorder', false, 'PadPartialBlocks', true)
B =
2.5200 4.5600 7.2000 6.9600 6.1200
3.6000 6.4000 10.0000 9.6000 8.4000
4.8000 8.4000 13.0000 12.4000 10.8000
4.0800 7.0400 10.8000 10.2400 8.8800
3.2400 5.5200 8.4000 7.9200 6.8400
Run Code Online (Sandbox Code Playgroud)
使用nlfilter5 x 5的大小复制它也会给出:
C = nlfilter(A, [5 5], @(x) mean(x(:)))
C =
2.5200 4.5600 7.2000 6.9600 6.1200
3.6000 6.4000 10.0000 9.6000 8.4000
4.8000 8.4000 13.0000 12.4000 10.8000
4.0800 7.0400 10.8000 10.2400 8.8800
3.2400 5.5200 8.4000 7.9200 6.8400
Run Code Online (Sandbox Code Playgroud)
我正在做一些计时测试,似乎blockproc在这种情况下使用的速度比nlfilter.
第二是
im2col.im2col(A,[m n],block_type)将块分成m个n块并将它们排列成列,所以每列是一个块?如果是这样,重叠如何控制?如果每个块都是一列,我可以dct2在每列上成功应用该功能吗?因为我怀疑它会将向量作为输入吗?
你是正确的,它将im2col每个像素邻域或块转换为单个列,并且这些列的串联形成输出矩阵.您可以通过block_type参数控制块是重叠还是不同.指定distinct或sliding(默认情况下)来控制它.您还可以使用m和控制每个社区的大小n.
但是,如果您的目标是应用dct2输出im2col,那么您将无法得到您想要的.具体而言,dct2将2D数据中每个数据点的空间位置考虑在内,并用作转换的一部分.通过将每个像素邻域变换为单个列,最初存在于每个块的2D空间关系现在消失了. dct2期望2D空间数据,但您将指定1D数据.因此,im2col可能不是你想要的.如果我理解你想要什么,你会想要使用blockproc.
希望这可以帮助!