Agora, estou lidando com algum processamento de imagem em Python via PIL (Python Image Library). Meu principal objetivo é contar o número de células coloridas em uma imagem imuno-histoquímica. Sei que existem programas, bibliotecas, funções e tutoriais relevantes sobre o assunto, e verifiquei quase todos eles. Meu principal objetivo é escrever o código manualmente do zero, o máximo possível. Por isso, estou tentando evitar o uso de muitas bibliotecas e funções externas. Eu escrevi a maior parte do programa. Então, aqui está o que está acontecendo passo a passo:
O programa recebe o arquivo de imagem:
E processa para os glóbulos vermelhos (basicamente, desativa os valores RGB abaixo de um certo limite para o vermelho):
E cria o mapa booleano dele ((vai colar uma parte dele porque é grande), que basicamente coloca 1 onde quer que encontre um pixel vermelho na segunda imagem processada acima.
22222222222222222222222222222222222222222
20000000111111110000000000000000000000002
20000000111111110000000000000000000000002
20000000111111110000000000000000000000002
20000000011111100000000000000000001100002
20000000001111100000000000000000011111002
20000000000110000000000000000000011111002
20000000000000000000000000000000111111002
20000000000000000000000000000000111111102
20000000000000000000000000000001111111102
20000000000000000000000000000001111111102
20000000000000000000000000000000111111002
20000000000000000000000000000000010000002
20000000000000000000000000000000000000002
22222222222222222222222222222222222222222
Eu intencionalmente gerei esse quadro como algo nas bordas com 2s para me ajudar a contar o número de grupos de 1s naquele mapa booleano.
Minha pergunta para vocês é: como é que eu posso contar com eficiência o número de células (grupos de 1s) nesse tipo de mapa booleano? Eu descobri http://en.wikipedia.org/wiki/Connected-component_labeling que parecem extremamente relacionados e semelhantes, mas, tanto quanto vejo, é no nível de pixel. O meu está no nível booleano. Apenas 1s e 0s.
Muito obrigado.
Respostas:
Uma abordagem de força bruta, mas feita ao inverter o problema para indexar sobre coleções de pixels para encontrar regiões, em vez de rasterizar sobre a matriz.
Impressões:
fonte
Scipy
fazer isso, o que provavelmente é mais rápido também ^^ 'Mas provavelmente é um bom exercício de qualquer maneira e mostra como fazer isso em geral. Vou votar então.Você pode usar
ndimage.label
, que é uma boa maneira de fazer isso. Ele retorna uma nova matriz, com todos os recursos com um valor único e o número de recursos. Você também pode especificar um elemento de conexão.fonte
Aqui está um algoritmo que é O (número total de pixels + número de pixels da célula). Simplesmente digitalizamos a imagem em busca de pixels da célula e, quando a encontramos, preenchemos a célula para apagá-la.
Implementação no Common Lisp, mas você poderá traduzi-lo para o Python trivialmente.
fonte
Mais um comentário extenso do que uma resposta:
Como @interjay sugeriu, em uma imagem binária, ou seja, na qual apenas duas cores estão presentes, os pixels assumem o valor 1 ou 0. Isso pode ou não ser verdade no formato de representação de imagem que você está usando, mas é verdade na representação "conceitual" da sua imagem; não deixe que os detalhes da implementação o confundam sobre esse problema. Um desses detalhes de implementação é o uso de 2s na borda da imagem - uma maneira perfeitamente sensata de identificar a zona morta ao redor da imagem, mas não afetando qualitativamente o binário da imagem.
Quanto ao exame dos pixels N, NE, NW e W: trata-se da conectividade dos pixels na formação do componente. Cada pixel (com exceção dos casos especiais da borda) tem 8 vizinhos (N, S, E, W, NE, NW, SE, SW), mas quais são candidatos à inclusão no mesmo componente? Às vezes, os componentes que se encontram apenas nos cantos (NE, NW, SE, SW) não são considerados conectados, às vezes são.
Você precisa decidir o que é apropriado para sua aplicação. Sugiro que você trabalhe, manualmente, algumas operações do algoritmo seqüencial, verificando vizinhos diferentes para cada pixel, para ter uma ideia do que está acontecendo.
fonte