Na troca de pilha TeX, discutimos como detectar "rios" nos parágrafos desta pergunta .
Nesse contexto, rios são faixas de espaço em branco que resultam do alinhamento acidental de espaços entre palavras no texto. Como isso pode ser bastante perturbador para um leitor, rios ruins são considerados um sintoma de tipografia ruim. Um exemplo de texto com rios é este, onde existem dois rios fluindo na diagonal.
Há interesse em detectar esses rios automaticamente, para que possam ser evitados (provavelmente pela edição manual do texto). O Raphink está fazendo algum progresso no nível TeX (que apenas conhece as posições dos glifos e as caixas delimitadoras), mas sinto-me confiante de que a melhor maneira de detectar rios é com algum processamento de imagem (já que as formas dos glifos são muito importantes e não estão disponíveis para o TeX) . Eu tentei várias maneiras de extrair os rios da imagem acima, mas minha ideia simples de aplicar uma pequena quantidade de desfoque elipsoidal não parece ser boa o suficiente. Eu também tentei alguns RadonFiltragem baseada em transformação, mas também não cheguei a lugar nenhum. Os rios são muito visíveis aos circuitos de detecção de características do olho humano / retina / cérebro e, de alguma forma, acho que isso poderia ser traduzido para algum tipo de operação de filtragem, mas não consigo fazê-lo funcionar. Alguma ideia?
Para ser específico, estou procurando alguma operação que detecte os 2 rios na imagem acima, mas não tenha muitas outras detecções de falsos positivos.
EDIT: endolith perguntou por que estou adotando uma abordagem baseada no processamento de imagens, uma vez que no TeX temos acesso às posições de glifos, espaçamentos etc., e pode ser muito mais rápido e confiável usar um algoritmo que examina o texto real. Minha razão para fazer as coisas de outra maneira é que a formaUm dos glifos pode afetar o grau de visibilidade de um rio e, no nível do texto, é muito difícil considerar essa forma (que depende da fonte, da ligadura etc.). Para um exemplo de como a forma dos glifos pode ser importante, considere os dois exemplos a seguir, onde a diferença entre eles é que substituí alguns glifos por outros quase da mesma largura, para que uma análise baseada em texto considere eles igualmente bons / ruins. Note, no entanto, que os rios no primeiro exemplo são muito piores que no segundo.
fonte
ImageLines[]
no Mathematica, com e sem algum pré-processamento. Eu acho que isso é tecnicamente usando uma transformação Hough ao invés de Radon. Não ficarei surpreso se o pré-processamento adequado (não tentei o filtro de dilatação sugerido pelo datagrama) e / ou as configurações de parâmetros puderem fazer esse trabalho.Respostas:
Pensei um pouco mais sobre isso e acho que o seguinte deve ser bastante estável. Observe que me limitei às operações morfológicas, porque elas devem estar disponíveis em qualquer biblioteca de processamento de imagens padrão.
(1) Abra a imagem com uma máscara nPix por 1, em que nPix é a distância vertical entre as letras
(2) Abra a imagem com uma máscara de 1 por mPix para eliminar o que for muito estreito para ser um rio.
(3) Remova os "rios e lagos" horizontais que são devidos ao espaço entre parágrafos ou recuo. Para isso, removemos todas as linhas verdadeiras e abrimos com a máscara nPix por 1 que sabemos que não afetará os rios que encontramos anteriormente.
Para remover lagos, podemos usar uma máscara de abertura um pouco maior que nPix por nPix.
Nesta etapa, também podemos jogar fora tudo que é pequeno demais para ser um rio real, ou seja, tudo que cobre menos área que (nPix + 2) * (mPix + 2) * 4 (que nos dará ~ 3 linhas). O +2 está lá porque sabemos que todos os objetos têm pelo menos nPix de altura e mPix de largura, e queremos ir um pouco acima disso.
(4) Se estivermos interessados não apenas no comprimento, mas também na largura do rio, podemos combinar a transformação de distância com o esqueleto.
(as cores correspondem à largura do rio (embora a barra de cores esteja desativada por um fator de 2)
Agora você pode obter o comprimento aproximado dos rios contando o número de pixels em cada componente conectado e a largura média calculando a média dos valores de pixels.
Aqui está exatamente a mesma análise aplicada à segunda imagem "no-river":
fonte
No Mathematica, usando erosão e transformada de Hough:
Editar Respondendo ao comentário do Sr. Wizard
Se você quiser se livrar das linhas horizontais, faça algo assim (provavelmente alguém poderia simplificá-lo):
fonte
lines = ImageLines[ImageResize[#, {300, 300}], .6, "Segmented" -> True] & /@ i1;
. Tudo dito, para esse problema, uma abordagem morfológica parece mais robusta.Hummm ... acho que a transformação de radônio não é tão fácil de extrair. (A transformação de radônio basicamente gira a imagem enquanto "olha através dela" de ponta a ponta. É o princípio por trás das tomografias.) A transformação de sua imagem produz esse sinograma, com os "rios" formando picos brilhantes, que são circulados:
Aquele com rotação de 70 graus pode ser visto claramente como o pico à esquerda deste gráfico de uma fatia ao longo do eixo horizontal:
Especialmente se o texto fosse gaussiano borrado primeiro:
Mas não sei como extrair esses picos de maneira confiável do resto do barulho. As extremidades superior e inferior brilhantes do sinograma representam os "rios" entre as linhas horizontais do texto, das quais você obviamente não se importa. Talvez uma função de ponderação versus ângulo que enfatize mais linhas verticais e minimize as horizontais?
Uma função simples de ponderação de cosseno funciona bem nesta imagem:
encontrar o rio vertical a 90 graus, que é o máximo global no sinograma:
e nesta imagem, encontrando a de 104 graus, embora o desfoque primeiro a torne mais precisa:
(A
radon()
função SciPy é meio idiota , ou eu mapeia esse pico de volta para a imagem original como uma linha que atravessa o meio do rio.)Mas ele não encontra nenhum dos dois picos principais no sinograma da sua imagem, depois de desfocar e ponderar:
Eles estão lá, mas estão sobrecarregados com as coisas próximas ao pico médio da função de ponderação. Com a ponderação e os ajustes corretos, esse método provavelmente pode funcionar, mas não tenho certeza de quais são os ajustes corretos. Provavelmente também depende das propriedades das digitalizações da página. Talvez a ponderação precise ser derivada da energia geral na fatia ou algo assim, como uma normalização.
fonte
Treinei um classificador discriminativo nos pixels usando recursos derivados (até a 2ª ordem) em diferentes escalas.
Meus marcadores:
Previsão na imagem do treinamento:
Previsão nas outras duas imagens:
Acho que isso parece promissor e pode gerar resultados úteis, com mais dados de treinamento e recursos talvez mais inteligentes. Por outro lado, levei apenas alguns minutos para obter esses resultados. Você pode reproduzir os resultados usando o software de código aberto ilastik . [Aviso: sou um dos principais desenvolvedores.]
fonte
(Desculpe, este post não vem com demonstrações impressionantes.)
Se você deseja trabalhar com as informações que o TeX já possui (letras e posições), pode classificar manualmente as letras e os pares de letras como "inclinados" em uma direção ou outra. Por exemplo, "w" tem inclinações de canto SW e SE, o combo "al" tem uma inclinação de canto noroeste, "k" tem uma inclinação de canto NE. (Não se esqueça da pontuação - uma citação seguida de uma letra que preenche a metade inferior da caixa de glifos estabelece uma inclinação agradável; a citação seguida de q é particularmente forte.)
Em seguida, procure por ocorrências de declives correspondentes em lados opostos de um espaço - "w al" para um rio SW-para-NE ou "k T" para um rio NW-SE. Quando você encontrar um em uma linha, veja se um semelhante ocorre, movido adequadamente para a esquerda ou direita, nas linhas acima / abaixo; quando você encontra uma corrida dessas, provavelmente há um rio.
Além disso, obviamente, basta procurar espaços empilhados quase na vertical, para os rios verticais simples.
Você pode ficar um pouco mais sofisticado medindo a "força" da inclinação: quanto da caixa de avanço está "vazia" devido à inclinação e, assim, contribuindo para a largura do rio. "w" é bastante pequeno, pois possui apenas um pequeno canto de sua caixa de avanço para contribuir com o rio, mas "V" é muito forte. "b" é um pouco mais forte que "k"; a curva mais suave fornece uma margem do rio mais visualmente contínua, tornando-a mais forte e visualmente mais larga.
fonte