Mostrando postagens com marcador texto. Mostrar todas as postagens
Mostrando postagens com marcador texto. Mostrar todas as postagens

domingo, 3 de março de 2013

Ajustar níveis de cor no tratamento de texto digitalizado

Um texto impresso em papel e digitalizado para um arquivo de imagem pode conter diversas interferências, que comprometam a qualidade da cópia digital. Desconsiderando o desempenho do dispositivo de digitalização (scanner), o próprio impresso pode dificultar uma boa digitalização. A cor do papel, o tipo do papel, a qualidade da impressão e até a gramatura que, quando pequena deixa o papel um pouco transparente e assim a impressão do verso torna-se levemente visível na frente. Tudo isso influencia no resultado final.

Quase sempre é preciso fazer alguma correção na imagem do texto digitalizado. Felizmente temos os softwares de tratamento de imagens, que não são somente para fotografias pois são capazes também de tratar desenhos e textos digitalizados.

Este artigo mostra uma ferramenta de cor, a ferramenta de níveis de cor, que realiza um tratamento muito bom para este tipo de imagem digitalizada. O software utilizado na demonstração desta ferramenta é o GIMP (www.gimp.org), um software gratuito com muitos recursos e disponível para Linux e Windows.

O texto é basicamente uma imagem de duas cores, a cor do fundo, que é a cor do papel, e a cor do texto, que é a cor da tinta da impressão. Apenas ajustando os níveis podemos modificar os pixels para que eles se concentrem no preto e no branco. Poderíamos converter a imagem para a paleta preto e branco de 1 bit mas nisso perderia-se a suavidade dos caracteres, ou usar a ferramenta de contraste mas esta não permite um controle preciso no nível da cor preta e da cor branca.

A ferramenta de níveis de cor proporciona uma funcionalidade semelhante a ferramenta de histograma, entretanto, pode alterar o alcance da intensidade, tornar a imagem mais clara ou mais escura, alterar o contraste e corrigir a cor predominante. No GIMP, a ferramenta de ajuste de níveis de cor está acessível pelo menu "Cores/Níveis..." (Colors/Levels).

Vamos iniciar o nosso exemplo com esta imagem de um texto digitalizado. Veja que a cor dos caracteres está fraca, o papel está acinzentado e é possível perceber a impressão do verso:


Imagem digitalizada original

Abrindo a janela da ferramenta de ajuste de níveis de cor vemos o histograma linear na imagem, nos níveis de entrada. O histograma mostra a quantidade de pixels em cada nível de cor. O eixo horizontal vai do nível 0 (preto) ao nível 255 (branco) e a quantidade de pixels por nível está no eixo vertical. A área da curva representa todos os pixels da imagem.

No histograma desta imagem original vemos dois picos, o da esquerda é referente aos pixels próximos do preto e o da direita é referente aos pixels próximos do branco. Perceba que a quantidade de pixels próximos do branco é bem maior pois a área livre (sem impressão) do papel é predominante. Os pixels próximos do preto são os caracteres. Abaixo este histograma original:


Histograma da imagem original

Não mostrarei todas as funcionalidades desta ferramenta de níveis, apenas os ajustes dos níveis de entrada, que são suficientes para o propósito deste artigo. No combo do canal deixe em "Valor", significa todos os canais.

Os níveis de entrada são ajustados pelos três triângulos deslizantes, ou pelos conta-gotas (desnecessário neste artigo), ou pelas três caixas de valor numérico. São três pontos porque o da esquerda seleciona o ponto negro, o da direita seleciona o ponto branco e o do centro ajusta o gama, o ponto médio.

Reposicionando o ponto negro faz com que todos os pixels, que possuírem este valor ou menos, tornem-se pretos. Assim, vamos posicioná-lo para alcançar todos os pixels referentes aos caracteres. Abaixo o histograma ajustado no ponto negro e a imagem digitalizada após este ajuste:


Histograma com ajuste do ponto negro


Imagem resultante

Podemos ver que os caracteres estão quase que totalmente pretos.

Reposicionando o ponto branco faz com que todos os pixels, que possuírem este valor ou mais, tornem-se brancos. Assim, vamos posicioná-los para alcançar todos os pixels referentes ao papel. Abaixo o histograma ajustado no ponto branco e a imagem digitalizada após este ajuste:


Histograma com ajuste do ponto branco


Imagem resultante

Podemos ver que o papel está completamente branco.

O que foi feito até agora foi o ajuste isolado de cada ponto, para mostrar o seu respectivo efeito. O tratamento final da imagem digitalizada está no reposicionando dos dois pontos, o negro e o branco, fazendo o ajuste em conjunto. Abaixo o histograma ajustado no ponto negro e no ponto branco e a imagem após este ajuste. Temos agora a imagem final:


Histograma com ajustes de ambos os pontos


Imagem resultante final

O texto está bem mais nítido, com o contraste adequado e o papel (fundo) sem qualquer sujeira. Volte lá na imagem original e compare com esta. Agora perfeito, não? A ferramenta de ajustes dos níveis de cor é mais eficiente em eliminar as sujeiras no papel. As vezes, existem pontos que são escuros o suficiente para confundir com os caracteres e esta ferramenta possibilita distanciá-los do preto e aproximá-los do branco.

O reposicionamento do ponto médio pode ser feito se desejar alterar o gama. Indo para a esquerda, para o preto, a imagem fica mais clara, indo para a direita, para o branco, a imagem fica mais escura. Nestes exemplos estou mantendo no 1 para evidenciar o efeito dos outros níveis.

Apenas com este ajuste dos níveis de cor podemos obter uma imagem, de um texto digitalizado, muito mais agradável para leitura. Inclusive, facilita o reconhecimento ótico dos caracteres (OCR), caso o propósito da imagem seja para este procedimento, o software não sofrerá com as interferências. Boas digitalizações!

sexta-feira, 4 de maio de 2012

Exibindo determinadas colunas com o awk

O programa awk é um editor de fluxo de texto. Sua função básica é procurar, em arquivos ou fluxo de dados, linhas ou textos que contenham um ou mais padrões. Quando a linha casa com um dos padrões, uma ação pode ser executada na respectiva linha.

Nas distribuições de Linux é comum encontrar o gawk, uma variante GNU com algumas extensões. O gawk possui todas as funcionalidades do awk original do UNIX. Neste artigo o programa será referenciado simplesmente como awk, entretanto usando como base o programa gawk.

O awk possui uma linguagem de programação própria, usando o tipo de dado string, arrays associativos e expressões regulares. Este artigo não abordará a linguagem toda mas apenas uma ação de impressão na saída padrão, a instrução print.

A sintaxe padrão do programa awk é:

gawk [opções] 'programa' arquivo

A única opção utilizada neste artigo é a -F, a qual define um ou mais caracteres como separadores de campo, ou delimitadores de campo. Por padrão o awk separa as palavras (ou campos) da linha delimitando-as pelos espaços vazios entre elas, incluindo qualquer caractere de espaço ou tab. Semelhante a arquivos CSV, onde os valores são separados por vírgula. Com a opção -F é possível especificar um caractere que será utilizado como delimitador, por exemplo "-F ,". Cada campo da linha será tratado como uma coluna vertical, como será visto mais adiante.

O argumento 'programa' define o processamento executado pelo awk. Pode ser um programa completo com uma sequência de instruções com condição-ação ou um simples comando, como será tratado aqui, o comando print. É importante proteger o código do programa com aspas, assim o shell não interpretará quaisquer caracteres especiais contidos no programa. Fazendo com que o shell trate todo o programa como um único argumento para o awk. Na sintaxe da linha de comando do awk, a instrução de ação deve ficar entre chaves, { e }.

A instrução de entrada/saída "print" é usada para realizar a saída de texto, na tela ou redireção a um arquivo, como em outras linguagens. Faz a impressão do resultado do programa. Como não usaremos uma condição, a instrução print será executada em cada linha da entrada.

Além da instrução print, na ação podemos incluir operadores. O operador para determinar quais colunas serão impressas é o $, na sintaxe $n. O número n indica a coluna, ou o campo na linha. Também é possível incluir sequências de caracteres, entre aspas, e alguns caracteres de escape, como \n (nova linha), \t (tab horizontal) e \ddd (caractere ASCII representado pelos três dígitos).

Vamos aos exemplos. A saída do comando "ls -l" retorna uma série de dados tabulados onde na primeira coluna temos as permissões, na segunda o número de ligações, na terceira o proprietário etc., em um total de "nove" colunas:

$ ls -l
drwxr-xr-x.  2 daniel daniel 4096 Mai  2 08:09 Desktop
drwxr-xr-x. 22 daniel daniel 4096 Mai  1 11:03 Documentos
drwxr-xr-x.  9 daniel daniel 4096 Mai  3 23:05 Downloads
drwxr-xr-x.  4 daniel daniel 4096 Abr 19 13:19 Imagens
drwxr-xr-x.  2 daniel daniel 4096 Jan  4 16:52 Músicas
drwxr-xr-x.  5 daniel daniel 4096 Mai  1 11:10 Vídeos

    $1      $2   $3     $4    $5  $6  $7  $8     $9

Para ser exibido em tela apenas a primeira coluna, com as permissões, e a nona coluna, com os nomes dos arquivos e diretórios, podemos usar a seguinte linha de comando:

$ ls -l | awk '{print $1 "\t" $9}'

A saída será:

drwxr-xr-x.     Desktop
drwxr-xr-x.     Documentos
drwxr-xr-x.     Downloads
drwxr-xr-x.     Imagens
drwxr-xr-x.     Músicas
drwxr-xr-x.     Vídeos

Obs.: O comando ls talvez tenha opções que façam esta filtragem, não vem ao caso. Se o nome do arquivo ou diretório conter espaço, somente a primeira palavra será exibida, a "nona" coluna.

Também podemos dar como entrada um arquivo. Se neste arquivo os campos estiverem separados por dois pontos, por exemplo no arquivo /etc/passwd, poderíamos usar a seguinte linha de comando para exibir somente o nome do usuário e o caminho do diretório home:

# awk -F : '{print "Usuário: " $1 "\tDiretório: " $6}' /etc/passwd

O awk é muito útil para filtragem de textos e formatação durante um processamento textual em um shell script, juntamente com o programa sed. Por exemplo, esta linha em um script, alimentaria a variável CONT com o número de linhas do arquivo texto:

CONT=`wc -l artigo.txt | awk '{print $1}'`

Consulte a página manual do awk para conhecer tudo que este interessante programa é capaz de fazer (man gawk).

sexta-feira, 9 de setembro de 2011

Conversor de texto para código Morse em áudio

Um programinha simples, existente desde 2007 e que ganhou novas versões agora em 2011, tem um propósito bem divertido. O ebook2cw é um programa de linha de comando capaz de converter um arquivo de texto puro (ISO 8859-1 ou UTF-8) para código Morse, em um arquivo de áudio MP3 ou OGG.

O ebook2cw está disponível pelo endereço http://fkurz.net/ham/ebook2cw.html e funciona em diversas plataformas, incluindo Windows, Linux, FreeBSD e Mac OS X.

Para compilar o fonte deste programa são necessárias as bibliotecas de desenvolvimento do Lame e Ogg/Vorbis. Estão disponíveis também os arquivos binários executáveis nas principais plataformas e uma interface gráfica é fornecida à parte.

Em sua execução é possível modificar alguns parâmetros, por exemplo, pela linha de comando os parâmetros -s samplerate e -b bitrate especificam a taxa de amostragem e a taxa de bits. Em sua página na Internet existe um manual de operação.

O resultado é muito bom e o autor do ebook2cw utiliza o programa para converter os livros fornecidos pelo Projeto Gutenberg.

terça-feira, 16 de março de 2010

Converter a codificação de caracteres de um arquivo texto

No Linux existe um comando chamado "iconv", do pacote "glibc-common" (no Fedora é este pacote, em outras distros pode ser outro), que serve para converter a codificação de caracteres de um arquivo texto de um padrão para outro.

Executando o comando com o parâmetro "--list", retorna-se a lista com todas as codificações suportadas e aceitas nos parâmetros "--from-code=" e "--to-code=" (ou -f e -t respectivamente). O arquivo de saída é definido no parâmetro "--output", ou "-o". Por exemplo:

$ iconv --from-code=UTF-8 --to-code=ISO-8859-1 utf.txt -o iso.txt

Caso queira descobrir em qual codificação de caracteres está o arquivo texto use o comando "file", do pacote de mesmo nome, com o parâmetro "-i". Por exemplo:

$ file -i arquivo.txt

Consulte as páginas manuais destes dois comandos para mais informações.

segunda-feira, 17 de agosto de 2009

Editor de texto sed

sed é um "Stream EDitor" ou editor de fluxo, bastante leve para linha de comando. Um editor de fluxo é um programa usado para executar transformações básicas em textos recebidos de uma entrada em fluxo, pode ser vindo de um arquivo ou da entrada padrão.

O sed trabalha com somente uma passagem sobre a entrada, tornando-o assim mais eficiente. Mas é a habilidade de filtragem de texto em um redirecionamento da saída para a entrada padrão, canalização, que o distingue dos outros tipos de editores.

A característica principal do sed é poder editar arquivos automaticamente. É um editor de textos não interativo, ele pode editar automaticamente, sem interação do usuário, vários arquivos seguindo um conjunto de regras especificadas. É como uma edição em "lote".

O sed é um editor de fluxo que está incluído em quase todos os sabores de UNIX, incluindo o Linux. Entretanto as distribuições do Linux contém o GNU sed, uma versão melhorada com muitas extensões úteis que economizam tempo ao padrão sed POSIX e também não sofre as muitas limitações que versões anteriores e proprietárias do sed tinham.

O sed trabalha executando qualquer número de operações de edição especificadas pelo usuário nos dados de entrada. O sed é baseado em linhas, assim os comandos são executados em cada linha, em ordem. E o sed escreve o resultado na saída padrão, ele não modifica nenhum arquivo de entrada.

Abaixo apresento alguns exemplos de uso do sed. Dentre eles alguns exemplos com o uso do sed combinado com outros programas para que tenha algo mais prático e assim entender melhor a utilidade do sed:

Substitui em cada linha de arquivo.txt as palavras "assim" para "assado":
sed 's/assim/assado/g' arquivo.txt

Substitui somente nas linhas que encontrar a string as palavras "assim" para "assado":
sed '/string/s/assim/assado/g'

Remove os 34 primeiros caracteres a partir do início de cada linha:
sed 's/^.\{34\}//' hash.md5 > arquivo.txt

Remove desde o início de cada linha até a última / encontrada
sed 's/^.*\///' caminhos.txt > sonomes.txt

Renomeia todos os arquivos .doc trocando _ e - por espaços:
for i in `ls *.doc`; do mv $i "`echo $i | sed 's/_/ /g; s/-/ /g'`"; done

Remove em arquivo.txt a linha 1 até a 28:
sed '1,28d' arquivo.txt > outro_arquivo.txt

Remove todas as linhas em branco:
sed '/^$/d' arquivo_com_linhas_em_branco.txt | sort > arquivo_limpo.txt

Remove todas as linhas que contenham a string:
sed '/string/d' arquivo.txt

Renomeia todos os arquivos de letras maiúsculas para minúsculas:
for i in `ls *.*`; do mv $i `echo $i | sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÇÑ/abcdefghijklmnopqrstuvwxyzàáâãäåèéêëìíîïòóôõöùúûüçñ/'`; done

Remove todas as tags HTML:
sed 's/<[^>]*>//g' arquivo.html > arquivo.txt

Adiciona um texto no início de cada linha:
sed 's/^/texto incluido/' arquivo.txt

Adiciona um texto no final de cada linha:
sed 's/$/texto incluido/' arquivo.txt

quarta-feira, 12 de agosto de 2009

Juntando arquivos linha a linha no Linux

Digamos que você tenha um arquivo (ex. letras.txt) que contenha:

a
b
c

E outro arquivo (ex. numeros.txt) que contenha:

1
2
3

E você quer unir estes arquivos para que o resultado fique:

a 1
b 2
c 3

Para isso existe um programa de linha de comando no Linux que é o paste, do pacote coreutils. O paste é capaz de unir linhas de arquivos. Por exemplo:

paste letras.txt numeros.txt > unidos.txt

Por padrão o paste separa os campos por tabulações mas você pode facilmente mudar isto adicionando o argumento -d. Por exemplo:

paste letras.txt numeros.txt -d , > unidos.txt

Resulta em um arquivo delimitado por vírgulas, ou seja, CSV (comma separated value):

a,1
b,2
c,3

sábado, 6 de junho de 2009

Gravando um DVD de dados em terminal de texto no Linux

Os aplicativos em modo texto para gravação de CD e DVD no Linux são uma forma muito eficiente de ter seus dados copiados para estes tipos de mídia. São ferramentas que proporcionam um controle total no processo e permitem a escolha de qualquer parâmetro de gravação.

Antes de qualquer gravação é necessária a organização dos arquivos que serão copiados. Uma maneira segura é juntá-los dentro de um diretório, assim tudo o que estiver lá dentro não será esquecido. Uma solução ainda mais eficiente é a geração de uma imagem de DVD, na qual pode-se testar se tudo está como deseja antes de queimar uma mídia.

Para a geração de uma imagem existe uma ferramenta chamada "genisoimage", do pacote de mesmo nome, capaz de criar sistemas de arquivos híbridos com ISO9660/Joliet/HFS e opcionalmente com atributo Rock Ridge. Esta ferramenta possui uma vasta variedade de parâmetros, bem documentada em sua página manual, e permite obter qualquer sistema que desejar. Segue um exemplo de uma linha de comando com os parâmetros comentados:

genisoimage -r -J -joliet-long -iso-level 4 -l -V nome -o imagem.iso diretório/

-r: Adiciona a extensão Rock Ridge para o sistema de arquivos e setando os arquivos e diretórios com permissões e modos em valores mais proveitosos, como dono e grupo setados em zero, permissão de escrita removida etc. Reconhecido no Linux apenas.

-J: Adiciona a extensão Joliet para o sistema de arquivos, permitindo nomes com até 64 caracteres.

-joliet-long: Permite nomes de arquivos Joliet com até 103 caracteres.

-iso-level: Especifica o nível do ISO9660, de 1 a 4, que vai do modo mais compatível, com nomes de no máximo 8.3 caracteres, ao mais relaxado, o nível 4, usando o padrão ISO-9660:1999, onde os nomes dos arquivos podem ter até 207 caracteres e não há mais o limite de 8 níveis para os subdiretórios.

-l: Permite 31 caracteres para o nome dos arquivos, relaxando as restrições do padrão ISO9660.

-V: Especifica um nome para o volume, de até 32 caracteres.

-o: Especifica o arquivo de saída para a imagem gerada.

Neste exemplo será gerado o arquivo "imagem.iso" contendo tudo que estiver dentro do "diretório/", excluindo o próprio, ou seja, na raiz do sistema de arquivo gerado ficarão os arquivos e subdiretórios existentes dentro do diretório especificado.

Uma outra forma de gerar uma imagem é em um processo de cópia de um DVD, onde utiliza-se a ferramenta "dd", do pacote "coreutils", para copiar o conteúdo da mídia e gerar a imagem. Segue um exemplo:

dd if=/dev/dvd of=imagem.iso

Este comando simplesmente faz uma cópia idêntica do sistema de arquivo do DVD para a imagem especificada.

Antes de gravar a imagem em uma mídia vazia convém testar se os arquivos foram copiados corretamente para a imagem, utilizando o comando "mount" como no exemplo abaixo:

mount -o loop -t iso9660 imagem.iso /mnt/iso/

Todo o sistema de arquivo contido na imagem será aberto em modo somente leitura no diretório "/mnt/iso/". Se os arquivos não estiverem corrompidos, tudo estará certo. O comando "umount /mnt/iso/" fechará esta montagem.

Arquivo imagem correto, tudo pronto para gravar na mídia. Um programa muito bom para isso é o "growisofs" do pacote "dvd+rw-tools". Este programa suporta todos os tipos de mídias DVD inclusive mídias Blu-ray.

Para que este comando funcione é necessário saber o nome do dispositivo do gravador, usando o comando abaixo:

wodim --devices

Como retorno aparece uma informação semelhante a que está abaixo:

wodim: Overview of accessible drives (2 found) :
----------------------------------------------------------------
0 dev='/dev/scd0' rwrw-- : 'HL-DT-ST' 'DVD-RAM GSA-H50N'
1 dev='/dev/scd1' rwrw-- : 'HL-DT-ST' 'DVD-ROM GDR8163B'
----------------------------------------------------------------

Neste exemplo percebe-se que o gravador é o dispositivo "/dev/scd0". Então um exemplo de linha de comando para o growisofs fica assim:

growisofs -dvd-compat -speed=4 -Z /dev/scd0=imagem.iso

-dvd-compat: Proporciona o máximo de compatibilidade com o resultado da mídia DVD, necessário para filmes e em DVD de dados faz com que a sessão fique fechada.

-speed: Determina a velocidade de gravação, em x.

-Z: Especifica o dispositivo do gravador, que por sua vez recebe o nome do arquivo da imagem.

Como podem perceber, são comandos simples que fazem muito. Consultem as páginas manuais destas ferramentas e vejam o quanto elas são capazes de fazer.