Estou trabalhando em um projeto em que franjas são projetadas contra um assunto e uma foto é tirada. A tarefa é encontrar as linhas centrais das franjas, que representam, matematicamente, a curva 3D de interseção entre o plano da franja e a superfície do objeto.
A foto é PNG (RGB), e as tentativas anteriores usavam escala de cinza e limiar de diferença para obter uma fotografia em preto e branco, semelhante a uma zebra, a partir da qual era fácil encontrar o ponto médio de cada coluna de pixel de cada franja. O problema é que, limitando e também medindo a altura média de uma coluna discreta de pixels, estamos tendo alguma perda e quantização de precisão, o que não é de todo desejado.
Minha impressão, observando as imagens, é que as linhas de centro poderiam ser mais contínuas (mais pontos) e mais suaves (não quantizadas) se fossem detectadas diretamente a partir da imagem sem limiar (RGB ou escala de cinza), por algum método de varredura estatística (alguma inundação / convolução iterativa, qualquer que seja).
Abaixo está uma imagem de amostra real:
Qualquer sugestão seria muito apreciada!
fonte
Respostas:
Sugiro as seguintes etapas:
x
, encontre o centro ponderado (por intensidade de pixel) nay
direção.y
valores, para remover o ruído.(x,y)
pontos ajustando algum tipo de curva. Este artigo pode ajudá-lo. Você também pode ajustar um polinômio de alto nível, embora seja pior, na minha opinião.Aqui está um código do Matlab que mostra as etapas 1,2 e 4. Ignorei a seleção automática de limite. Em vez disso, escolhi o manual
th=40
:Estas são as curvas encontradas ao encontrar a média ponderada por coluna:
Estas são as curvas após o ajuste de um polinômio:
Aqui está o código:
fonte
double
. Sobre os resultados na metade inferior, eu preciso verificar, pode ser um bug de softwareEu não usaria a imagem RGB. As imagens coloridas geralmente são criadas colocando um "Filtro Bayer" no sensor da câmera, o que geralmente reduz a resolução que você pode obter.
Se você usar a imagem em escala de cinza, acho que os passos que você descreveu (binarizar a imagem "zebra", encontrar a linha média) são um bom começo. Como passo final, eu gostaria
fonte
Aqui está ainda uma solução alternativa para o seu problema, modelando sua pergunta como um 'problema de otimização de caminho'. Embora seja mais complicado do que a solução simples de montagem de binarização e curva, é mais robusta na prática.
Do nível muito alto, devemos considerar esta imagem como um gráfico, onde
cada pixel da imagem é um nó neste gráfico
cada nó está conectado a outros nós, conhecidos como vizinhos, e essa definição de conexão é frequentemente referida como a topologia deste gráfico.
cada nó tem um peso (recurso, custo, energia ou o que você quiser chamar), refletindo a probabilidade de que esse nó esteja em uma linha central ideal que estamos procurando.
Desde que possamos modelar essa probabilidade, seu problema de encontrar 'as linhas centrais das franjas' passa a ser o problema para encontrar caminhos ótimos locais no gráfico , que podem ser efetivamente resolvidos pela programação dinâmica, por exemplo, o algoritmo Viterbi.
Aqui estão alguns profissionais da adoção dessa abordagem:
todos os seus resultados serão contínuos (diferente do método do limite que pode quebrar uma linha central em pedaços)
muitas liberdades para construir esse gráfico, você pode selecionar diferentes recursos e topologia de gráfico.
seus resultados são ótimos no sentido de otimizações de caminho
sua solução será mais robusta contra o ruído, porque, enquanto o ruído estiver igualmente distribuído entre todos os pixels, esses caminhos ideais permanecerão estáveis.
Aqui está uma breve demonstração da idéia acima. Como não uso nenhum conhecimento prévio para especificar quais são os possíveis nós iniciais e finais, simplesmente decodifico wrt todos os nós iniciais possíveis.
Para as terminações difusas, isso é causado pelo fato de estarmos procurando caminhos ideais para todos os nós finais possíveis. Como resultado, embora para alguns nós localizados em áreas escuras, o caminho destacado ainda seja o ideal local.
Para o caminho difuso, você pode suavizá-lo após encontrá-lo ou usar alguns recursos suavizados em vez da intensidade bruta.
É possível restaurar caminhos parciais alterando os nós inicial e final.
Não será difícil remover esses caminhos ótimos locais indesejados. Como temos a probabilidade de todos os caminhos após a decodificação de viterbi, e você pode usar vários conhecimentos anteriores (por exemplo, vemos que é verdade que precisamos apenas de um caminho ideal para aqueles que compartilham a mesma fonte).
Para mais detalhes, consulte o documento.
Aqui está um pequeno pedaço de código python usando para fazer o gráfico acima.
fonte
Pensei que deveria postar minha resposta, pois é um pouco diferente de outras abordagens. Eu tentei isso no Matlab.
Uma desvantagem que vejo aqui é que essa abordagem não terá bom desempenho em algumas orientações das faixas. Nesse caso, temos que corrigir sua orientação e aplicar este procedimento.
Aqui está o código do Matlab:
Por exemplo, se você usar a coluna do meio da imagem, seu perfil deverá ficar assim: (em azul é o perfil. Em verde são os máximos locais)
E a imagem que contém os máximos locais para todas as colunas fica assim:
Aqui estão os componentes conectados (embora algumas faixas estejam quebradas, a maioria delas obtém uma região contínua):
fonte