Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image 使用blockproc或im2col在图像上重叠滑动窗口?_Image_Matlab_Image Processing_Image Segmentation_Dct - Fatal编程技术网

Image 使用blockproc或im2col在图像上重叠滑动窗口?

Image 使用blockproc或im2col在图像上重叠滑动窗口?,image,matlab,image-processing,image-segmentation,dct,Image,Matlab,Image Processing,Image Segmentation,Dct,我必须将dct2应用于图像的小窗口,最好使用重叠窗口 我发现Matlab中有两个函数可以使blockproc和im2col成为可能。我在理解这两个方面都有困难,希望能澄清一下 blockproc可用于使用BorderSize和TrimBorder参数在滑动窗口上实现my函数 B = blockproc(A,[64,64],fun,'BorderSize',[5,5], 'TrimBorder', 'false'); 我意识到这会创建一个[64+2*5,64+2*5]块,并在每个块上应用@fun

我必须将dct2应用于图像的小窗口,最好使用重叠窗口

我发现Matlab中有两个函数可以使blockproc和im2col成为可能。我在理解这两个方面都有困难,希望能澄清一下

blockproc可用于使用BorderSize和TrimBorder参数在滑动窗口上实现my函数

B = blockproc(A,[64,64],fun,'BorderSize',[5,5], 'TrimBorder', 'false');
我意识到这会创建一个[64+2*5,64+2*5]块,并在每个块上应用@fun函数。但由于我无法进入调试中的@fun函数来验证正确的操作,我不能确定这是我所需要的。 我的上述代码是否符合我的需要?我知道我在B中得到了一个串联的结果,但它应该在一个重叠的滑块上。这能满足我的需要吗

第二种是im2col。im2colA,[mn],block_type将块划分为m×n块,并将它们排列在列中,因此每列都是一个块?如果是,如何控制重叠?如果每个块都是一列,我能在每个列上成功地应用dct2函数吗?因为我怀疑它会接受向量作为输入


如能澄清,将不胜感激

好的,这是一个相当复杂的问题。我将试着把它分成几个部分,并分别回答每个问题

问题1 blockproc可用于使用BorderSize和TrimBorder参数在滑动窗口上实现my函数

B = blockproc(A,[64,64],fun,'BorderSize',[5,5], 'TrimBorder', 'false');
B=blockprocA[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
假设我们想要取上面矩阵中每个3x3重叠邻域的平均值,并对超出矩阵边界的元素进行零填充。您可以使用blockproc执行此操作:

需要注意的是,块大小(在本例中为1 x 1)和边框大小(在本例中为1 x 1)的设置与预期的3 x 3块不同。为了探究为什么会出现这种情况,我们需要进一步了解BorderSize是如何工作的。对于块的给定中心,BorderSize允许您捕获超出原始大小块尺寸的值/像素。对于超出矩阵边界的位置,默认情况下,我们将这些位置填充为零。BorderSize允许我们捕获更多2M+2N像素,其中M和N是您想要的水平和垂直边界大小。这将允许我们在原始块的上方和下方再捕获M个像素,在原始块的左侧和右侧再捕获N个像素

因此,对于A中的值1,如果块大小为1 x 1,这意味着元素仅由1组成,如果边界大小为1 x 1。这意味着我们的最后一块将是:

0  0  0
0  1  6
0  2  7
因为我们的块大小是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
您可以使用我们可以将平均值应用于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
因此,如果要正确使用blockproc进行滑动操作,则需要注意如何分别设置块大小和边框大小。在这种情况下,一般规则是始终将块大小设置为1 x 1,并允许BorderSize指定所需的每个块的大小。具体来说,对于大小为K x K的块,您可以将BorderSize分别设置为floorK/2 x floorK/2。如果K是个古怪的人,事情就会变得简单

例如,如果希望在滑动窗口的基础上进行5 x 5的平均值过滤操作,可以将BorderSize设置为[2 2],即K=5和floorK/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
用nlfilter wit复制此文件 h尺寸为5 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
我在做一些计时测试,在这个上下文中使用的blockproc似乎比nlfilter更快

问题2 第二种是im2col。im2colA,[mn],block_type将块划分为m×n块,并将它们排列在列中,因此每列都是一个块?如果是,如何控制重叠?如果每个块都是一列,我能在每个列上成功地应用dct2函数吗?因为我怀疑它会接受向量作为输入

您是正确的,im2col将每个像素邻域或块转换为一列,这些列的串联形成输出矩阵。可以通过“块类型”参数控制块是重叠的还是不同的。指定默认用于控制此操作的“独特”或“滑动”。您还可以使用m和n控制每个邻域的大小

但是,如果您的目标是将dct2与im2col的输出一起应用,那么您将无法得到所需的结果。具体而言,dct2将每个数据点在2D数据中的空间位置考虑在内,并用作变换的一部分。通过将每个像素邻域转换为单个列,每个块原来存在的二维空间关系现在消失了。dct2需要2D空间数据,但您可以指定1D数据。因此,im2col可能不是您想要的。如果我正确理解了您的需求,您将希望使用blockproc


希望这有帮助

非常感谢@rayryeng的出色和详细的解释。当你可以得到这样一个详细而有用的回复时,赏金被添加并给予:@FarazKhan-哦,非常感谢你的赏金!你根本不需要!顺便说一句,这与我所说的不能在滑动窗口方法中使用blockproc与你之前的问题相矛盾。。。因为在我做了一些实验之后,你当然可以。。。你只需要在参数上胡闹。这是一个非常有趣的问题,我也从中学到了一些东西。另外,谢谢你提出这个问题!在使用上述代码之后,我相信blockproc产生的输出对于我的分类器来说并不理想。每个块应该生成一个1x200大小的向量,但我得到的是一个1x1600大小的向量。我发现这是blockproc的工作,因为它连接了4个块的结果,ul_输出、ll_输出、ur_输出、lr_输出,所以它将区域划分为更小的块,然后连接在一起,这对我的分类器不起作用。因为我需要每个块单独的输出。我试图更改内部函数设置,但失败。@FarazKhan-您是否可以发布另一个问题,并更详细地谈谈您在做什么?我也许能帮你回答你的问题。我同意,有很多话要说。我将开始一个新问题: