首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >3d矩阵中的3d面片

3d矩阵中的3d面片
EN

Stack Overflow用户
提问于 2012-07-19 04:00:08
回答 4查看 2.2K关注 0票数 4

我有一个3d矩阵(3x3x3),我需要提取3d patches (2x2x2)并将它们转换为向量。

在2d中,简单地:

I=randi(5,3,3);

2d_patches=im2col(I,[2 2],'sliding');

那3d呢?

I=randi(5,3,3,3);

3d_patches= ???

im2col只能在2d模式下工作。在3d中,我应该重新组合向量1728,...这个任务有没有什么快速的函数?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-07-19 04:38:31

我不相信有任何内置的方法可以做到这一点。如果你想让它更快,用c编写你自己的mex函数并从Matlab中调用它应该是相当简单的。

这是我的(快速而粗暴的)解决方案:

im3col.c:

代码语言:javascript
复制
#include <mex.h>

void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
  const mxArray *I = prhs[0];
  double *indata = mxGetPr(I);
  double *patchSize = mxGetPr(prhs[1]);
  const int *size = mxGetDimensions(I);
  int J = (int)patchSize[0], K = (int)patchSize[1], H = (int)patchSize[2];
  int M = size[0],           N = size[1],           P = size[2];

  int numPatches = (M - J + 1)*(N - K + 1)*(P - H + 1);
  int out_rows = J*K*H, out_cols = numPatches;
  mxArray *out = mxCreateDoubleMatrix( out_rows, out_cols, mxREAL );
  double *outdata = mxGetPr(out);

  int patch = 0;
  for( int h_offset = 0; h_offset < P-H+1; h_offset++ ){
    for( int k_offset = 0; k_offset < N-K+1; k_offset++ ){
      for( int j_offset = 0; j_offset < M-J+1; j_offset++ ){
        int row = 0;
        for( int h = 0; h < H; h++ ){
          for( int k = 0; k < K; k++ ){
            for( int j = 0; j < J; j++ ){
              outdata[patch*out_rows + row] = 
                indata[ (j_offset+j) + (k_offset+k)*M + (h_offset+h)*M*N ];
              ++row;
            }}}
      ++patch;
      }}}
  plhs[0] = out;
}

编译:

代码语言:javascript
复制
>> mex -O CFLAGS="\$CFLAGS -std=c99 -Wall" im3col.c

测试:

代码语言:javascript
复制
>> A(:,:,1) = [1,4,7;2,5,8;3,6,9]; A(:,:,2) = [10,13,16;11,14,17;12,15,18];
>> B = im3col(A, [2,2,1])

B =

     1     2     4     5    10    11    13    14
     2     3     5     6    11    12    14    15
     4     5     7     8    13    14    16    17
     5     6     8     9    14    15    17    18

>> A(:,:,1),A(:,:,2)

ans =

     1     4     7
     2     5     8
     3     6     9


ans =

    10    13    16
    11    14    17
    12    15    18
票数 2
EN

Stack Overflow用户

发布于 2017-12-09 00:49:01

这是另一个方向:(它相当慢,而且肯定有一个更快的方法)

代码语言:javascript
复制
function [img] = patch2im_2d_time(patch, size_img, size_patch, size_skip, border)
Nx = size_img(1);
Ny = size_img(2);
Nt = size_img(5);

psz1 = size_patch(1);
psz2 = size_patch(2);
psz3 = size_patch(3);

%Extract blocks. One could save a lot here.
patches  = reshape(patch, [psz1 psz2 psz3 size(patch,2)]);
c = 1;
img2 = zeros(squeeze(size_img));
%Count for each pixel how many times we added smth to it.
add_count = zeros(size_img);

%The first three loops, loop through all the pixels in the image
for d=1:Nt-psz3+1
    for j=1:Nx-psz2+1
        for i=1:Ny-psz1+1
            %Here we get the next patch. The next patch is always
            %the patch that has the pixel at i,j,d at its top front corner.
            current_patch = patches(:,:,:,c);
            %counter for the next patch
            c = c + 1;
            %In this loop we add the patch values of each pixel in the
            %patch to the image. i,j,d is the base. We add the offset
            %ii jj and dd to it. This iteration takes psz^3 many
            %iterations.
            for dd=1:psz3
                for ii=1:psz2
                    for jj=1:psz1
                        img2(i+ii-1,j+jj-1,d+dd-1) = img2(i+ii-1,j+jj-1,d+dd-1) + current_patch(ii,jj,dd);
                        add_count(i+ii-1,j+jj-1,d+dd-1) = add_count(i+ii-1,j+jj-1,d+dd-1) + 1;
                    end
                end
            end

        end
    end
end
    img = flipud(rot90(img2 ./ add_count,1));
end

请记住,MATLAB使用的是col。

票数 1
EN

Stack Overflow用户

发布于 2013-07-03 15:30:50

代码语言:javascript
复制
%One possible way to use matlab to call im2col and reshape twice
%N = [row, col, num_frames]

[x_height, ~, num_frames] = size(N);
patchSize = 16;
patchTemporal = 10;

N = reshape(N, x_height, []);

N = im2col(N, [patchSize, patchSize], 'distinct');

N = reshape(N, [], num_frames);

N = im2col(N, [patchSize^2, patchTemporal], 'distinct');
% N = [patchSize^2 *patchTemporal x numPatches]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11549297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档