Matlab: maneira eficiente de contar números diferentes de zero ao longo dos limites de uma matriz

StackOverflow https://stackoverflow.com/questions/19825429

Pergunta

Eu tenho uma matriz cuja imagem parece mostrada abaixo. Os valores na matriz representam o número de partículas em cada pixel/grade. Eu quero calcular a distribuição de partículas diferentes de zero ao longo da periferia/limite (periferia/limite refere -se à distribuição dos pontos mais distantes do centro) onde existem partículas diferentes de zero. Como uma saída disso, gostaria de obter:

1) # de partículas diferentes de zero ao longo da periferia/limite e

2) # de pixels/grades onde essas partículas residem

Alguma maneira rápida/eficiente de fazer isso?

enter image description here

Editar 1: Instantâneo descrevendo o exemplo de um limiteA linha de contorno traça as partículas diferentes de zero.enter image description here

Foi útil?

Solução

Começando com uma matriz M de contagem de partículas, isso lhe dará uma máscara em Mb da fronteira como foi definido pela pergunta,

% define particle count matrix and find non-zero locations
M = randi(5,10,10)-1
[nr,nc] = size(M);
[pRows,pCols] = find(M);

% identify locations that compose the "boundary" line
boundCoords = [accumarray(pCols,pRows',[nc 1],@min)', ...
               accumarray(pCols,pRows',[nc 1],@max)', ...
               1:nr 1:nr; ...
               1:nc 1:nc, ...
               accumarray(pRows,pCols',[nr 1],@min)', ...
               accumarray(pRows,pCols',[nr 1],@max)'];
boundCoords = unique(boundCoords','rows');
boundCoords(any(boundCoords==0,2),:)=[]; %' remove possible (unlikely) zeros

% create a mask representation of the boundary line
Mb = false(size(M));
Mb(sub2ind(size(Mb),boundCoords(:,1),boundCoords(:,2))) = true

É assim que eu entendo que você quer que sua máscara de limite seja. O número de pixels que compõem o limite é

numBorderPix = sum(Mb(:))

O número de partículas nesses pontos de borda é então

numBorderParticles = sum(M(Mb))

Nota: Esta solução garantirá que Cada ponto na linha de limite tem uma contagem de partículas diferentes de zero.

Outras dicas

A periferia peri Para indexação lógica da sua matriz M é

peri = true(25);
peri(2:end-1, 2:end-1) = false;

Então, a partícula conta n na periferia são n = M(peri). (1) O número total de partículas ao longo do limite é sum(n). (2) O número de pixels onde eles residem é sum(n > 0).

-Eu inventei esse algoritmo para o seu problema.

-Os detalhes do que você deseja não são 100% claros, para que isso não possa calcular exatamente o que você deseja.

-A explicação está nos comentários

A=full(sprand(10,10,0.9));

crossKernel=[0 1 0; 1 1 1; 0 1 0]; %% neighbor kernel
isBorder = (conv2(ones(size(A)),crossKernel,'same')~=5); %% find pixels on border
isZeroOnBorder = isBorder & (A==0); %% find zeros on border
%%% the pixels on the new border are...
isNewBorder = (conv2(double(isZeroOnBorder),crossKernel,'same')... %% next to a zero on border
              | isBorder )... %% or on the border of the matrix
              & (~isZeroOnBorder); %% and are not zeros on border
newBorderLength=nnz(isNewBorder) %% counting and obtaining result
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top