Localizando quadrados na imagem

34

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:

insira a descrição da imagem aqui

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:

insira a descrição da imagem aqui

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

Abid Rahman K
fonte
sua formação é sempre esbranquiçada?
11
minha idéia era calcular a "saturação" e limitar o sat img, mas usando o seu exemplo, ele não funciona muito bem (calculando a saturação como max (RG, RB, GB) .O fato de alguns quadrados parecerem quase com o fundo Se todas as suas imagens tiverem o mesmo padrão (longas listras brancas com quadrados ao lado), considere encontrar os bits mais fáceis (como os quadrados realmente coloridos ou as listras brancas) deduzir o local possível para outras praças e ... encontrar uma maneira de verificar se eles estão realmente lá ou not.Tough mas interessante que você pode dar mais imagens!?
Bem, acho que isso não deveria ter sido mudado.
Junuxx
11
Você pode fornecer mais imagens? Além disso, o que é isso?
Andrey Rubshtein
2
O OP precisa responder a algumas perguntas. Talvez o fundo branco não seja necessário. E o que há com a luz? Vai ser tão ruim assim? Estes parecem apenas complexidade desnecessária para mim.
Tae-Sung Shin

Respostas:

9

Uma primeira tentativa usando o Matlab:

im = imread('squares.jpg');
im2 = rgb2gray(im);

se = strel('disk', 15);

for i = 1:16;
    t = 60+i*5; % try out a range of bw thresholds to see what works best
    labelled = bwlabel(im2>t); % label regions in the BW image
    closed = imclose(labelled, se); % close small regions
    cleared = imclearborder(~closed,4); % clear regions touching the border
    subplot(4,4,i); 
    imshow(cleared); 
    title(['T = ' num2str(t)]);
end

Resultados nas seguintes regiões:

regiões rotuladas

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.

Junuxx
fonte
8

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):

mascarar imagem

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:

imagem ideal

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:

Imagem de saída

Etapa 4: OU opere acima da saída com a imagem da máscara da primeira etapa

saída final

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 !!!

Abid Rahman K
fonte
5

Nota: Este método será muito lento.

Gere uma máscara parecida com os contornos de um objeto ideal. Semelhante a isso:

máscara do objeto

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.

SlimJim
fonte
5

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 insira a descrição da imagem aqui

insira a descrição da imagem aqui

rotating_image
fonte
11
+1 - Seria ótimo se você pudesse implementá-lo.
Abid Rahman K
2
@AbidRahmanK Não é para isso que serve o StackExchange. Pergunta -> Resposta. Caso contrário, isso acabaria sendo uma feira de empregos.
Jan Krüger 04/07
2

esse arranjo é fixo

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
Encontrei 3-4 quadrados usando o método de contorno. Então tem altura e largura de cada quadrado. Em seguida, verificou se havia espaço entre os quadrados detectados e assumiu se o espaço entre eles é grande o suficiente para manter outro quadrado. Essa é a previsão que fiz.
Abid Rahman K
Alguns quadrados têm cores quase semelhantes às do plano de fundo. Então, eu tenho medo, eles também serão considerados como área não quadrada conforme o seu método.
Abid Rahman K
Talvez você possa tentar trabalhar em todas as colunas para plotar uma curva em que o eixo x seja a altura (em pixels) da imagem e o eixo y seja a intensidade. Em seguida, você pode tentar encontrar algumas arestas de corte com a forma derivada.
isso é a própria detecção de bordas, certo? Eu tentei, mas não obtive um bom resultado.
precisa
11
Sim, mas você pode ver por que razão falha e talvez isolar algumas regiões interessantes da trama. A propósito, se você encontrar algumas dicas úteis para resolver seu problema, poste-as. Boa sorte para suas pesquisas
0

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.

canahari
fonte