[opencv] camadas de contorno ()

4_9_5_Estratificação de contorno - Documentação oficial chinesa do OpenCV

contente

teoria

Representação hierárquica no OpenCV

Modo de pesquisa de contorno

1. RETR_LIST

2. RETR_EXTERNAL

3. RETR_CCOMP

4. RETR_TREE


1. RETR_LIST

Esta é a mais simples das quatro bandeiras (do ponto de vista da interpretação). Ele apenas recupera todos os contornos, mas não cria nenhum relacionamento pai-filho. Sob esta regra, os contornos pai e filho são iguais, são apenas contornos . Todos pertencem ao mesmo nível.

2. RETR_EXTERNAL Se este sinalizador for usado, ele retornará apenas o sinalizador externo extremo. Todas as silhuetas infantis são deixadas para trás. Podemos dizer que de acordo com essa regra, apenas o filho mais velho de cada família recebe atenção. Não se importa com o resto da família :) .

3. RETR_CCOMP Este sinalizador recupera todos os contornos e os organiza em uma hierarquia de 2 níveis. O contorno externo do objeto (ou seja, o limite do objeto) é colocado na hierarquia-1. O contorno do buraco dentro do objeto (se houver) é colocado na hierarquia-2.

4. RETR_TREE: Recupera todos os contornos e cria uma lista completa de hierarquia de famílias. Até conta, quem é o avô, pai, filho, neto e muito mais... :).

 

teoria

Diversas funções relacionadas aos contornos fornecidos pelo OpenCV foram discutidas anteriormente. Mas quando usamos a função **cv.findcontour**() para encontrar o contorno na imagem, passamos um parâmetro, o modo de recuperação de contorno . Geralmente passamos **cv.RETR_LIST ** ou **cv.RETR_TREE ** , que funciona bem. Mas o que exatamente isso significa?

Na saída, temos três arrays,

  1. A primeira é a imagem,
  2. O segundo é o esboço,
  3. Há também uma saída que chamamos de **hierarquia** (verifique o código no artigo anterior).
    Mas nunca usamos essa hierarquia em nenhum lugar. Então, o que é essa hierarquia? Para que é usada? Como ela se relaciona com os parâmetros da função acima mencionados?

É isso que vamos discutir neste artigo.

Qual é a hierarquia?

  • Normalmente usamos a função **cv.findcontour**() para detectar objetos na imagem, às vezes os objetos estão em posições diferentes.
  • Mas em alguns casos algumas formas estão dentro de outras formas . Assim como gráficos aninhados. Nesse caso, chame a externa de **classe pai** e a interna de **subclasse** . Desta forma, os contornos na imagem têm uma certa relação entre si.
  • Você pode especificar como um contorno é conectado entre si, por exemplo, se é um contorno filho de outro contorno, um contorno pai, etc. A representação dessa relação é chamada de ** hierarquia **.

Abaixo segue um exemplo: 

Nesta foto, há algumas formas que numerei de **0-5**. *2* e *2a* representam os contornos externo e interno da caixa mais externa .

  • Os contornos 0,1,2 são **externos ou externos**. Podemos dizer que estão no **nível-0**, ou simplesmente, estão no **mesmo nível**.
  • O próximo é **contorno-2a**. Ele pode ser considerado um filho do contorno-2 (ou, inversamente, o contorno-2 é um pai do contorno-2a). Digamos que esteja no **nível 1**.
  • Da mesma forma, contour-3 é filho de contour-2, que está na próxima hierarquia.
  • Finalmente, os contornos 4,5 são filhos do contorno-3a, estão no último nível. Pela numeração das caixas, acho que o contorno-4 é o primeiro filho do contorno-3a (também poderia ser o contorno-5).

Menciono estes para entender alguns termos como ** mesmo nível **, contorno externo , contorno filho , contorno pai , **primeiro contorno filho**, etc. Agora vamos entrar no OpenCV.

Representação hierárquica no OpenCV

Portanto, cada perfil tem suas próprias informações sobre o nível, quem é seu filho, quem é seu pai, etc.

O OpenCV o representa como um array com quatro valores:[Next, Previous, First_Child, Parent]

"Próximo representa o próximo contorno no mesmo nível."

Por exemplo, pegue o contorno-0 em nossa imagem. Quem é o próximo contorno no mesmo nível? Este é o contorno-1. basta encomendar Next = 1. Da mesma forma, Contour-1 também é contorno-2. Então. Next = 2_ E quanto ao contorno 2? Não há próxima linha de contorno na mesma linha horizontal. Simplesmente, deixe Next = -1. E o contorno 4? Está no mesmo nível do contorno 5. Seu próximo contorno é o contour-5, então next = 5.

" Anterior representa um contorno anterior no mesmo nível."

O mesmo que acima. O contorno antes do contorno-1 é o contorno-0 no mesmo nível. Da mesma forma, o contorno-2 também é o contorno-1. Para contour-0, não há item anterior, portanto, é definido como -1.

"First_Child representa seu primeiro contorno filho."

Nenhuma explicação é necessária. Para contorno-2, a criança é contorno-2a. Assim, obtém-se o valor do índice correspondente ao contorno-2a. E o contorno 3a? Ele tem dois filhos. Mas focamos apenas no primeiro filho. É contorno-4. Então First_Child = 4 para contorno-3a.

"Parent representa o índice de seu contorno pai."

É o oposto de **First_Child**. Para contorno-4 e contorno-5, o contorno pai é contorno-3a. Para o contorno 3a, é o contorno 3 e assim por diante.

Observe que  este campo é tratado como -1 se não houver elementos filho ou pai

Agora que entendemos os estilos hierárquicos usados ​​no OpenCV, podemos verificar o modo de recuperação de contorno no OpenCV com a ajuda da mesma imagem fornecida acima. O significado de alguns sinalizadores como  cv.RETR_LISTcv.RETR_TREE , cv.RETR_CCOMP , **cv.RETR_EXTERNAL** e assim por diante.

Modo de pesquisa de contorno

1. RETR_LIST

Esta é a mais simples das quatro bandeiras (do ponto de vista da interpretação).

  • Ele apenas recupera todos os contornos, mas não cria nenhum relacionamento pai-filho.
  • Sob esta regra, os contornos pai e filho são iguais, são apenas contornos . Todos pertencem ao mesmo nível.

Aqui, o 3º e o 4º itens são sempre -1. Mas obviamente, o próximo item e o item anterior têm valores correspondentes. Basta verificar você mesmo.

Abaixo está o resultado que obtive, cada linha é o nível de detalhe para o contorno correspondente. Por exemplo, a primeira linha corresponde ao contorno 0. O próximo contorno é o contorno 1. Então. Next = 1_ Não há contorno anterior, então Previous=-1. Os dois restantes, como mencionado, são -1.

>>> hierarchy
array([[[ 1, -1, -1, -1],
        [ 2,  0, -1, -1],
        [ 3,  1, -1, -1],
        [ 4,  2, -1, -1],
        [ 5,  3, -1, -1],
        [ 6,  4, -1, -1],
        [ 7,  5, -1, -1],
        [-1,  6, -1, -1]]])

Essa é a melhor opção para usar em seu código se você não estiver usando nenhum recurso de hierarquia.

2. RETR_ EXTERNO

Se este sinalizador for usado, ele retornará apenas o sinalizador externo extremo. Todas as silhuetas infantis são deixadas para trás. Podemos dizer que de acordo com essa regra, apenas o filho mais velho de cada família recebe atenção. Não se importa com o resto da família :) .

Então, na nossa imagem, quantos contornos externos extremos existem? No nível 0? Existem 3, ou seja, o contorno é 0 1 2, certo? Agora tente encontrar o contorno com este sinalizador. Aqui, dê a cada elemento o mesmo valor acima. e comparado com os resultados acima. Aqui está o que eu recebo:

>>> hierarchy
array([[[ 1, -1, -1, -1],
        [ 2,  0, -1, -1],
        [-1,  1, -1, -1]]])
Você pode usar este sinalizador se quiser apenas extrair contornos externos. Pode ser útil em alguns casos.

3. RETR_CCOMP

Este sinalizador recupera todos os contornos e os organiza em uma hierarquia de 2 níveis.

  • O contorno externo do objeto (ou seja, o limite do objeto) é colocado na hierarquia-1.
  • O contorno do buraco dentro do objeto (se houver) é colocado na hierarquia-2.

Se houver algum objeto nele, seu contorno só é reposicionado na hierarquia 1. e suas vulnerabilidades na Camada 2 e assim por diante.

Basta considerar uma imagem "zero branco" em um fundo preto. O círculo externo de zero pertence ao primeiro nível e o círculo interno de zero pertence ao segundo nível.

Podemos explicá-lo com uma imagem simples. Aqui marquei a ordem dos contornos e as camadas a que pertencem em vermelho e em verde (1 ou 2), na mesma ordem em que o OpenCV detecta os contornos.

Considere o primeiro contorno, que é o contorno-0. Esta é a hierarquia-1. Possui dois furos, Contornos 1 e 2, que pertencem ao segundo nível. Assim, para o contorno-0, o próximo contorno no mesmo nível é o contorno-3. Nem anterior. Na hierarquia-2, seu primeiro filho é o contorno-1. Ele não tem classe pai porque está na hierarquia-1. Portanto, sua matriz hierárquica é[3,-1,1,-1]

Agora contorno-1. Está no nível 2. O próximo na mesma hierarquia (sob o pai do contorno-1) é o contorno-2. Não há anterior. Não child, mas parentcontorno-0. Então a matriz é[2,-1,-1,0]

Similar contorno-2: está na hierarquia-2. Sob o contorno-0, não há próximo contorno na mesma hierarquia. Então não Next. previousé contorno-1. Não child, parenté contorno0. Então a matriz é[-1,1,-1,0]

contorno-3: Ao lado do nível-1 está o contorno-5. Costumava ser contorno-0. childé contorno4, não parent. Então a matriz é[5,0,4,-1]

contorno-4: Está na hierarquia 2 sob o contorno-3, não tem irmãos. Não next, não previous, não child, parenté contorno-3. Então a matriz é[-1,-1,-1,3]

Você pode adicionar o resto. Aqui está a resposta final que obtive:

>>> hierarchy
array([[[ 3, -1,  1, -1],
        [ 2, -1, -1,  0],
        [-1,  1, -1,  0],
        [ 5,  0,  4, -1],
        [-1, -1, -1,  3],
        [ 7,  3,  6, -1],
        [-1, -1, -1,  5],
        [ 8,  5, -1, -1],
        [-1,  7, -1, -1]]])

4. RETR_TREE

Ele recupera todos os contornos e cria uma lista completa de hierarquia de família. Até conta, quem é o avô, pai, filho, neto e muito mais... :).

Por exemplo, tirei a foto acima e reescrevi o código para cv. RETR_TREE, reordene os contornos e analise-os de acordo com os resultados fornecidos pelo OpenCV. Novamente, as letras vermelhas indicam o número de contornos e as letras verdes indicam a ordem de hierarquia.

Pegue contour-0: está hierarchy-0dentro. O contorno da mesma hierarquia nexté o contorno-7. nenhuma previoussilhueta. childé contorno-1, não parent. Então a matriz é[7,-1,1,-1]

Tomemos por contour-2exemplo: está em hierarchy-1. Nenhum contorno está no mesmo nível. previous_ childSim contour-3. Os pais são contour-1. Então a matriz é[-1,-1,3,1]

De resto, experimente você mesmo. Aqui está a resposta completa:

>>> hierarchy
array([[[ 7, -1,  1, -1],
        [-1, -1,  2,  0],
        [-1, -1,  3,  1],
        [-1, -1,  4,  2],
        [-1, -1,  5,  3],
        [ 6, -1, -1,  4],
        [-1,  5, -1,  4],
        [ 8,  0, -1, -1],
        [-1,  7, -1, -1]]])

Acho que você gosta

Origin blog.csdn.net/dujuancao11/article/details/122431371
Recomendado
Clasificación