Eu preciso encontrar os quadrados em uma imagem usando OpenCV (sem problemas no matlab ou qualquer outro, geralmente o que eu espero são algumas idéias).
Considere a imagem de teste abaixo:
Preciso encontrar com precisão os quadrados coloridos na imagem acima (não as faixas brancas longas).
O que eu fiz :
Eu apliquei o método comum (que vem com amostras OpenCV), ou seja, encontre contornos em todos os planos de cores, aproxime-o e verifique o número de elementos = 4. Funciona até certo ponto que, poucos quadrados são detectados, especialmente os escuros.
O próximo passo que fiz foi a previsão . isto é, este arranjo é fixo . Portanto, se algumas são obtidas, posso prever as restantes. Também funcionou em certa medida. Mas a precisão era muito ruim.
Mas sinto que a previsão não é um bom método aqui e nem sempre fornece respostas precisas, conforme fornecidas no primeiro passo.
O que eu preciso :
1) Existem outros métodos melhores para detectar esses quadrados com mais precisão? Ou vários métodos?
Um ponto importante é que, o tempo não é um problema aqui . O algoritmo pode ser lento, não importa. Mas a precisão é o principal critério.
Às vezes, as imagens podem ficar muito mais embaçadas.
E um dos principais problemas que enfrentei é que alguns quadrados têm cores quase iguais às do plano de fundo (verifique o primeiro e o segundo quadrados da coluna 3).
À procura de ideias, obrigado antecipadamente
ATUALIZAÇÃO:
Abaixo está o resultado exato máximo que obtive:
Obviamente, a imagem resultante é redimensionada um pouco.
ATUALIZAÇÃO 2:
Dei uma solução muito mais melhor na minha resposta abaixo: https://dsp.stackexchange.com/a/7526/818
fonte
Respostas:
Uma primeira tentativa usando o Matlab:
Resultados nas seguintes regiões:
Como você pode ver, selecionar o limite que resulta no maior número de regiões (T = 120) já forneceria 7 locais corretos, alguns locais mesclados, um falso positivo e dois falsos negativos.
Foi uma tentativa bastante simples, mas acho que mostra que a abordagem funciona. Adicionar algumas coisas para dividir regiões alongadas ou fazer isso para cada canal de cor separadamente são apenas algumas das ações que você pode fazer para melhorar isso.
Também ajudaria se você fornecesse mais algumas imagens de teste.
fonte
Eu tentei outra coisa para melhorar meu resultado em questão. A solução abaixo pressupõe que o primeiro quadrado (laranja) seja sempre detectado na etapa 1. E é prático devido à sua cor de alto contraste em comparação com o fundo. Até o resultado que mostrei em questão o detectou corretamente
Etapa 1: encontre o maior número possível de quadrados
Dividi a imagem nos planos R, G, B, H, S, V e limpei a imagem para valores de limiar diferentes, como múltiplos de 25. Para cada imagem, encontrei quadrados nela e os coloquei em uma "imagem de máscara" . Também encontrei altura e largura médias do quadrado.
imagem da máscara (total de 7/12 quadrados detectados):
Etapa 2: formar uma grade de quadrados
Em seguida, encontrei os centróides desses quadrados na imagem da máscara. Classificou-os e encontrou o centróide do primeiro quadrado (laranja). Analisando de perto, podemos ver que a diferença entre dois quadrados é um quadrado na direção horizontal e vertical. Então, dessa maneira, criei uma grade de quadrados como abaixo e chamei de ideal_squares (é apenas um nome, não significa que essa é a saída que eu preciso):
ideal_squares:
Etapa 3: Remapear a imagem ideal
Agora, temos os centróides ideal_squares e centróides originais. Descobri as correspondências corretas para cada centróide original a partir de ideal_centroids (medindo a distância euclidiana entre eles). Em seguida, usei o Scipy interpolate.griddata para interpolação e refiz a imagem ideal_de acordo com os valores do centróide (é quase o mesmo que o deformação realizado nestas perguntas e respostas: Como remover defeitos de convexidade no quadrado do sudoku e transformação de imagem no OpenCV ). Então, abaixo está a saída que recebi:
Saída:
Etapa 4: OU opere acima da saída com a imagem da máscara da primeira etapa
Agora você pode ver todos os quadrados foram detectados, mas com um problema mencionado abaixo:
Problema:
Veja a saída da Etapa 3, ou seja, imagem remapeada da grade quadrada. Exceto dois quadrados centrais, todos os outros quadrados são cortados. É um problema associado a este remapeamento. Não sei onde está o problema, com scipy.interpolate.griddata () ou cv2.remap (). Eu pensei que toda a imagem seria distorcida, mas não é. Ele distorce apenas a imagem dentro dos centróides que demos. Se eu puder corrigir isso, a saída será boa.
Então, se alguém conhece uma boa idéia para isso, muito bem-vindo !!!
fonte
Nota: Este método será muito lento.
Gere uma máscara parecida com os contornos de um objeto ideal. Semelhante a isso:
deslize (posição, escala, rotação) a máscara sobre a imagem e combine-a com o contorno da imagem real (talvez um pouco embaçada para obter uma resposta mais suave) para calcular quão semelhantes elas são, a (posição, escala, rotação) com a resposta de maior similaridade deve ser a (posição, escala, rotação) do objeto real.
O método não se importa com os quadrados que se misturam com o plano de fundo ou mesmo com oclusões parciais do objeto, uma vez que considera o objeto inteiro.
Pessoalmente, usei esse método com êxito para rastrear um focinho de rato e bigodes, mas tive algumas suposições como se estivessem próximas da última posição conhecida etc. Mas acho que você pode reduzir o espaço de pesquisa aplicando algumas suposições como: tamanhos possíveis do objeto na câmera, a que distância do centro pode estar ou a rotação <10 graus, etc.
fonte
Etapa 1: Qualquer que seja a imagem binária final que você está obtendo da análise nos planos B, G, R, H, S, V, nessa imagem, faça um algoritmo de contagem de blob.
Etapa 2: encontre o maior blob com base na área ou no comprimento do contorno. Como seus blobs são principalmente tipos de paralelogramos, portanto, área ou contorno, qualquer um fará.
Etapa 3: com o maior blob (já que o maior blob é o melhor blob que se assemelha aos quadrados do mundo real), tente encontrar a orientação do blob ... isso pode ser obtido com um retângulo mais adequado ou com os pontos de canto ... obtenha a inclinação das linhas que as unem (na direção horizontal e vertical).
Etapa 4: depois de obter as duas pistas, desenhe duas linhas que atravessam o eixo do blob. para o eixo você pode calcular a média dos pontos de canto ou usar o centróide (centro de massa) ... eu usaria a média dos pontos de canto ...
Etapa 5: Como em cada direção horizontal e vertical, o espaçamento é igual (o ideal é o espaçamento horizontal e vertical também são iguais, pois vem da sua imagem quadrada ideal, mas não a assumimos ..) só precisamos localizar os possíveis centróides da outra paralelogramos
LINHA INFERIOR: Se qualquer quadrado for detectado perfeitamente, você poderá fazer a grade inteira. Apenas mantenha os centros de marcação em um intervalo de 2H (H = largura horizontal do maior blob) ao longo do eixo horizontal do maior blob e em um intervalo de 2V (V = altura vertical do maior blob) verticalmente ao longo do eixo vertical do blob.
Algumas fotos para apoiar
fonte
Eu realmente não sei que tipo de previsão você fez antes, mas você tentou se concentrar nas longas tiras brancas como raiz. Então (se três colunas de quadrados tiverem o mesmo tamanho), você poderá detectar a altura de um quadrado (distância entre as duas faixas) e a área máxima e mínima (altura e largura) na imagem.
Em seguida, tente detectar a cor mais comum em todo o quadrado e defina-a como uma área "não quadrada". O resto deve ser o quadrado que você está procurando.
fonte
Eu sugeriria o uso da transformação Hough, que é um algoritmo muito robusto para encontrar formas paramétricas simples, como linhas, círculos, etc. A detecção de linhas seria melhor no seu caso. Você poderia encontrar pelo menos os lados dos longos compridos brancos; então, com qualquer algoritmo extrator de canto (Harris ou talvez SIFT ou SURF), você poderá encontrar cantos nessas linhas, mesmo usando o fato de que os quadrados são aproximadamente igualmente espaçados.
fonte
Eu tentei esse problema usando opencv, python. A abordagem envolve mascarar a imagem com base nas cores, seguida pela localização de contornos adequados.
Código: https://github.com/rbhambriiit/computer_vision/blob/master/find_color_box
[Perdeu 1 caixa, mas isso deve vir ajustando a função de mascaramento]
fonte