Na minha pergunta anterior, recebi uma excelente resposta que me ajudou a detectar onde uma pata atingiu uma placa de pressão, mas agora estou lutando para vincular esses resultados às correspondentes.
Anotei manualmente as patas (RF = frente direita, RH = traseira direita, LF = frente esquerda, LH = traseira esquerda).
Como você pode ver, há claramente um padrão de repetição e ele volta em quase todas as medições. Aqui está um link para uma apresentação de 6 tentativas que foram anotadas manualmente.
Meu pensamento inicial era usar heurísticas para fazer a classificação, como:
- Há uma proporção de ~ 60-40% no suporte de peso entre as patas dianteiras e traseiras;
- As patas traseiras são geralmente menores na superfície;
- As patas são (frequentemente) divididas espacialmente em esquerda e direita.
No entanto, sou um pouco cético em relação às minhas heurísticas, pois elas falhariam comigo assim que eu encontrasse uma variação que eu não tinha pensado. Eles também não serão capazes de lidar com as medições de cães coxos, que provavelmente têm regras próprias.
Além disso, a anotação sugerida por Joe às vezes fica bagunçada e não leva em consideração a aparência da pata.
Com base nas respostas que recebi na minha pergunta sobre detecção de pico na pata , espero que haja soluções mais avançadas para classificá-las. Especialmente porque a distribuição da pressão e a progressão da mesma são diferentes para cada pata separada, quase como uma impressão digital. Espero que exista um método que possa usar isso para agrupar minhas patas, em vez de apenas classificá-las em ordem de ocorrência.
Então, estou procurando uma maneira melhor de classificar os resultados com a pata correspondente.
Para qualquer pessoa que esteja à altura do desafio, escolhi um dicionário com todas as matrizes fatiadas que contêm os dados de pressão de cada pata (agrupada por medição) e a fatia que descreve sua localização (localização na placa e no tempo).
Para esclarecer: walk_sliced_data é um dicionário que contém ['ser_3', 'ser_2', 'sel_1', 'sel_2', 'ser_1', 'sel_3'], que são os nomes das medidas. Cada medida contém outro dicionário, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] (exemplo de 'sel_1') que representa os impactos que foram extraídos.
Observe também que impactos "falsos", como onde a pata é parcialmente medida (no espaço ou no tempo), podem ser ignorados. Eles são úteis apenas porque podem ajudar a reconhecer um padrão, mas não serão analisados.
E para qualquer pessoa interessada, estou mantendo um blog com todas as atualizações sobre o projeto!
fonte
walk_sliced_data
estão estruturados? Eu vejo um dicionário de dicionários de matrizes 3D. Se eu fixar a terceira dimensão e plotar as duas primeiras como uma imagem, acho que vejo patas.Respostas:
Tudo bem! Finalmente consegui fazer algo funcionar consistentemente! Esse problema me atraiu por vários dias ... Coisas divertidas! Desculpe pela duração desta resposta, mas preciso elaborar um pouco sobre algumas coisas ... (Embora eu possa estabelecer um recorde para a resposta mais longa de fluxo de pilha sem spam de todos os tempos!)
Como uma observação lateral, estou usando o conjunto de dados completo ao qual Ivo forneceu um link na pergunta original . É uma série de arquivos rar (um por cão), cada um contendo várias execuções experimentais diferentes armazenadas como matrizes ascii. Em vez de tentar copiar e colar exemplos de código autônomo nesta pergunta, aqui está um repositório de mercúrio de bitbucket com código completo e autônomo. Você pode cloná-lo com
hg clone https://[email protected]/joferkington/paw-analysis
Visão geral
Existem essencialmente duas maneiras de abordar o problema, como você observou na sua pergunta. Na verdade, vou usar os dois de maneiras diferentes.
Basicamente, o primeiro método trabalha com as patas do cão segue o padrão trapezoidal mostrado na pergunta de Ivo acima, mas falha sempre que as patas não seguem esse padrão. É bastante fácil detectar programaticamente quando não funciona.
Portanto, podemos usar as medições em que funcionou para criar um conjunto de dados de treinamento (de ~ 2000 impactos da pata de ~ 30 cães diferentes) para reconhecer qual pata é qual e o problema se reduz a uma classificação supervisionada (com algumas rugas adicionais. .. O reconhecimento de imagens é um pouco mais difícil que um problema de classificação supervisionado "normal").
Análise de Padrões
Para elaborar o primeiro método, quando um cachorro está andando (sem correr!) Normalmente (o que alguns desses cães podem não estar), esperamos que as patas impactem na ordem de: Frente Esquerda, Traseira Direita, Frente Direita, Traseira Esquerda , Frente esquerda, etc. O padrão pode começar com a pata dianteira esquerda ou dianteira direita.
Se esse sempre fosse o caso, poderíamos simplesmente classificar os impactos pelo tempo de contato inicial e usar o módulo 4 para agrupá-los por pata.
No entanto, mesmo quando tudo está "normal", isso não funciona. Isso ocorre devido à forma trapezoidal do padrão. Uma pata traseira cai espacialmente atrás da pata anterior anterior.
Portanto, o impacto da pata traseira após o impacto inicial da pata frontal geralmente cai da placa do sensor e não é registrado. Da mesma forma, o último impacto da pata geralmente não é a próxima na seqüência, pois o impacto antes de ocorrer na placa do sensor e não foi registrado.
No entanto, podemos usar a forma do padrão de impacto da pata para determinar quando isso aconteceu e se começamos com uma pata dianteira esquerda ou direita. (Na verdade, estou ignorando problemas com o último impacto aqui. Porém, não é muito difícil adicioná-lo.)
Apesar de tudo isso, freqüentemente não funciona corretamente. Muitos dos cães no conjunto de dados completo parecem estar correndo, e os impactos das patas não seguem a mesma ordem temporal de quando o cachorro está andando. (Ou talvez o cão tenha problemas graves no quadril ...)
Felizmente, ainda podemos detectar programaticamente se os impactos das patas seguem ou não o nosso padrão espacial esperado:
Portanto, mesmo que a classificação espacial simples não funcione o tempo todo, podemos determinar quando ela funciona com confiança razoável.
Conjunto de dados de treinamento
A partir das classificações baseadas em padrões em que funcionou corretamente, podemos criar um conjunto de dados de treinamento muito grande de patas corretamente classificadas (~ 2400 impactos de 32 cães diferentes!).
Agora podemos começar a ver como é a frente "média" esquerda, etc, da pata.
Para fazer isso, precisamos de algum tipo de "métrica da pata" que seja da mesma dimensionalidade para qualquer cão. (No conjunto de dados completo, existem cães muito grandes e muito pequenos!) Uma impressão de pata de um elkhound irlandês será muito mais ampla e muito "mais pesada" do que uma impressão de pata de um poodle toy. Precisamos redimensionar cada impressão de pata para que a) eles tenham o mesmo número de pixels eb) os valores de pressão sejam padronizados. Para fazer isso, ralei novamente cada impressão de pata em uma grade de 20x20 e redimensionei os valores de pressão com base no valor máximo, mínimo e médio de pressão para o impacto da pata.
Depois de tudo isso, finalmente podemos dar uma olhada em como é uma pata dianteira esquerda média, traseira direita, etc. Observe que essa média é calculada em mais de 30 cães de tamanhos muito diferentes, e parece que estamos obtendo resultados consistentes!
No entanto, antes de fazer qualquer análise sobre isso, precisamos subtrair a média (a pata média para todas as pernas de todos os cães).
Agora podemos analisar as diferenças em relação à média, que são um pouco mais fáceis de reconhecer:
Reconhecimento de pata com base em imagem
Ok ... Finalmente temos um conjunto de padrões com os quais podemos começar a combinar as patas. Cada pata pode ser tratada como um vetor 400-dimensional (retornado pela
paw_image
função) que pode ser comparado a esses quatro vetores 400-dimensionais.Infelizmente, se apenas usarmos um algoritmo de classificação supervisionado "normal" (ou seja, descobrir qual dos 4 padrões está mais próximo de uma impressão de pata específica usando uma distância simples), ele não funcionará de forma consistente. De fato, não se sai muito melhor do que a chance aleatória no conjunto de dados de treinamento.
Este é um problema comum no reconhecimento de imagens. Devido à alta dimensionalidade dos dados de entrada e à natureza um tanto "confusa" das imagens (ou seja, os pixels adjacentes têm uma alta covariância), simplesmente observar a diferença entre uma imagem e uma imagem de modelo não fornece uma medida muito boa da semelhança de suas formas.
Eigenpaws
Para contornar isso, precisamos construir um conjunto de "patas próprias" (como "faces próprias" no reconhecimento facial) e descrever cada impressão de pata como uma combinação dessas patas próprias. Isso é idêntico à análise dos componentes principais e basicamente fornece uma maneira de reduzir a dimensionalidade dos nossos dados, para que a distância seja uma boa medida de forma.
Como temos mais imagens de treinamento do que dimensões (2400 x 400), não é necessário fazer álgebra linear "sofisticada" para obter velocidade. Podemos trabalhar diretamente com a matriz de covariância do conjunto de dados de treinamento:
Estes
basis_vecs
são os "eigenpaws".Para usá-los, simplesmente pontilhamos (ou seja, multiplicação da matriz) cada imagem de pata (como um vetor de 400 dimensões, em vez de uma imagem de 20x20) com os vetores de base. Isso nos dá um vetor 50-dimensional (um elemento por vetor base) que podemos usar para classificar a imagem. Em vez de comparar uma imagem 20x20 com a imagem 20x20 de cada pata "modelo", comparamos a imagem transformada em 50 dimensões com cada pata modelo transformada em 50 dimensões. Isso é muito menos sensível a pequenas variações de exatamente como cada dedo está posicionado etc., e basicamente reduz a dimensionalidade do problema apenas às dimensões relevantes.
Classificação de pata baseada em Eigenpaw
Agora podemos simplesmente usar a distância entre os vetores de 50 dimensões e os vetores de "modelo" para cada perna para classificar qual pata é qual:
Aqui estão alguns dos resultados:
Problemas restantes
Ainda existem alguns problemas, principalmente em cães pequenos demais para criar uma impressão clara de pata ... (Funciona melhor com cães grandes, pois os dedos dos pés ficam mais claramente separados na resolução do sensor.) enquanto eles podem estar com o sistema baseado em padrões trapezoidais.
No entanto, como a análise da pinha própria inerentemente usa uma métrica de distância, podemos classificar as patas nos dois sentidos e voltar ao sistema baseado em padrões trapezoidais quando a menor distância da análise da pinha própria do "livro de códigos" está acima de algum limite. Ainda não implementei isso.
Ufa ... Isso foi longo! Estou de olho em Ivo por ter uma pergunta tão divertida!
fonte
Usando as informações puramente baseadas na duração, acho que você poderia aplicar técnicas de modelagem cinemática; ou seja, cinemática inversa . Combinado com orientação, comprimento, duração e peso total, fornece algum nível de periodicidade que, espero, seja o primeiro passo para resolver o seu problema de "classificação das patas".
Todos esses dados podem ser usados para criar uma lista de polígonos delimitados (ou tuplas), que você pode usar para classificar por tamanho da etapa e depois por paw-ness [index].
fonte
Você pode fazer com que o técnico que executa o teste insira manualmente a primeira pata (ou as duas primeiras)? O processo pode ser:
fonte