2015-06-10 2 views
2

Я хочу проецировать текстуру трехмерной поверхности (CylCoors300000x3) в 2D-плоскость (Image 380x360). Для делать это я беру все уникальное значение в Z (UniqueZ=unique(CylCoors(:,3))) и и Тета (UniqueTheta=unique(CylCoors(:,1))) и проецировать все значения текстуры (PointValues300000x1), где оба отвечают так:Векторизация с использованием накопителя

Image=zeros(max(UniqueH),max(UniqueTheta)); %380x360 

tic 

HMat=bsxfun(@eq,CylCoors(:,3),UniqueH'); % 300000x380 
ThetaMat=bsxfun(@eq,CylCoors(:,1),UniqueTheta'); %300000x360 


for ii=1:length(UniqueH)   % Sloooow and not nice :(
    for jj=1:length(UniqueTheta) 

     Image(ii,jj)=sum(PointValues.*... 
      HMat(:,ii).*ThetaMat(:,jj))/... 
      sum(HMat(:,ii).*ThetaMat(:,jj)); 

    end 
end 

toc 

Вот пример с обрезанными переменными :

CylCoorsSample = [263.0000 184.2586 10.0000  
        264.0000 183.0417 10.0000  
        264.0000 182.1572 10.0000  
        82.0000 157.4746 11.0000  
        80.0000 158.2348 11.0000  
        86.0000 157.3507 11.0000  
        84.0000 157.7633 11.0000] 

PointValuesSample = [0.4745 
        0.5098 
        0.5020 
        0.4784 
        0.4510 
        0.4431 
        0.5804] 


UniqueTheta = [80    
       82    
       84 
       86 
       263 
       264] 

UniqueH =[10 
      11] 

ThetaMat =        HMat = 

0  0  0  0  1  0  1 0 
0  0  0  0  0  1  1 0 
0  0  0  0  0  1  1 0 
0  1  0  0  0  0  0 1 
1  0  0  0  0  0  0 1 
0  0  0  1  0  0  0 1 
0  0  1  0  0  0  0 1 

Image =  % size: length(UniqueH)xlength(UniqueTheta) 

    NaN  NaN  NaN  NaN 0.4745 0.5059 
0.4510 0.4784 0.5804 0.4431  NaN  NaN 

есть ли способ векторизовать for петли с помощью accumarray? Что-то подсказывает мне, что это так, но я считаю, что многомерное индексирование для этой функции довольно запутанно.

Любые другие решения векторизации (с использованием смарт-комбинации из reshape, bsxfun и sum я предполагаю), также приветствуется, но я бы очень хотел, чтобы понять это использование accumarray немного лучше.

+0

Вы можете добавить небольшой вход и выход пробы? – Dan

+0

Конечно, просто сделал! – McMa

+0

Нет. Я имею в виду сделать * маленький * образец с входной матрицей в упрощенных номерах и как номера изменены, чтобы продемонстрировать ваш процесс. – Dan

ответ

2

Дано:

CylCoorsSample = [263.0000 184.2586 10.0000  
        264.0000 183.0417 10.0000  
        264.0000 182.1572 10.0000  
        82.0000 157.4746 11.0000  
        80.0000 158.2348 11.0000  
        86.0000 157.3507 11.0000  
        84.0000 157.7633 11.0000] 

PointValuesSample = [0.4745 
        0.5098 
        0.5020 
        0.4784 
        0.4510 
        0.4431 
        0.5804] 

Вы можете использовать accumarray следующим образом (используя третий вывод unique для создания необходимого subs вход):

[UniqueTheta, ~, subsTheta]=unique(CylCoorsSample(:,1)) 
[UniqueH,~,subsH]=unique(CylCoorsSample(:,3)) 
sz = [numel(UniqueH), numel(UniqueTheta)] 

Image = accumarray([subsH, subsTheta], PointValuesSample, sz, @mean, NaN) 
+0

Работает отлично, но мне нужно будет сесть и проанализировать накопитель() и все его параметры, чтобы действительно понять его. Спасибо! – McMa

+1

subs - это список векторов строк позиций в выходной матрице. Так что, если строка первая из подставок '[1 1]', то это означает, что строка 1 «val» в позиции '[1 1]' выводится. Однако, если в моем примере есть много строк subs с таким же значением (например, '[1 1]'), тогда поместите все соответствующие значения val в эту позицию, но агрегируйте их с помощью дескриптора функции fun (в моем случае '@ mean', так что усредняйте их). – Dan

+0

Теперь это именно то, что я еще не понял! Теперь все ясно, еще раз спасибо за отличный ответ. – McMa

Смежные вопросы