Friday, December 14, 2007

djvumake oppure script

I vantaggi dello script sono diversi il risultato dovrebbe essere lo stesso che utilizzando BGSUB=3 e FGSUB=6 ma in realtà spesso le immagini spesso sono migliori con lo script, secondo me il rpoblema e' nel cropping. Per utilizzare un fattore di subsampling di 3 è necessario ridurre di 3 volte le dimensioni della pagina ma se le dimensioni dei lati non sono divisibili per 3 a causa dell`errore di arrotondamento (le dimensioni sono intere) si ottiene una immagine leggermente sfalsata, dividendo ulteriormente per 2 per fare il foreground si può introdurre un ulteriore errore di arrotondamento che porta ad avere una immagine leggermente distorta. lo script fa in modo che le diemnsioni siano divisibili per 6 e' poi necessario adattare i parametri, lo script non e' ancora finito ovviamente.

Il problema più grosso resta la creazione della maschera iniziale comunque, lì ci sono ancora sicuramente migliorie da apportare.
Ultimissima versione dello script di conversione, dai test fatti djvumake usa backsub=3 e fgsub=6 usando 2 e 4 si incrementa notevolmente la qualita su pagine complesse incrementando di poco le dimensioni.

#!/bin/bash
DPI=300
THRESHOLD=0.75
FGSUB=4
BACKSUB=2
DIVIDE=1
DITHER=0
CLASSIC=1

gs -sDEVICE=jpeg -dUseCropBox -sOutputFile='myfile%04d.jpg' -r$DPI -dPrinted -dNOPAUSE -dBATCH -dDOINTERPOLATE -dJPEGQ=99 -f "$1"
if [[ $CLASSIC == "1" ]] ; then
for i in *.jpg;do
jpegtopnm $i>temp.pnm
if [[ $DITHER == "0" ]] ; then
ppmtopgm temp.pnm |pamthreshold -simple -threshold $THRESHOLD|pamtopnm>mask.pbm
else
ppmdither -red 2 -green 2 -blue 2 temp.pnm |pamditherbw -threshold -value $THRESHOLD|pamtopnm>mask.pbm
fi
cjb2 -clean -lossy -dpi $DPI mask.pbm mask.djvu
djvumake `basename $i .jpg`.djvu Sjbz=mask.djvu PPM=$i
done
else
for i in *.jpg; do
split=$DIVIDE
jpegtopnm $i>temp.pnm
while [[ "$split" -ge "1" ]] ; do
iden=`identify temp.pnm`
left=`echo $iden|awk '{print substr($3,1,index($3,"x")-1)/2}'`
if [[ "$split" == "1" && $DIVIDE -gt "1" ]] ; then
pamcut -right $left temp.pnm>tmp.pnm
mv -f tmp.pnm temp-$split.pnm
elif [[ "$split" == "2" && $DIVIDE -gt "1" ]] ; then
pamcut -left $left temp.pnm>tmp.pnm
mv -f tmp.pnm temp-$split.pnm
else
mv -f temp.pnm temp-$split.pnm
fi
iden=`identify temp-$split.pnm`
left=`echo $iden|awk '{print substr($3,1,index($3,"x")-1)%6}'`
top=`echo $iden temp-$split.pnm |awk '{print substr($3,index($3,"x")+1)%6}'`
if [[ "$left" != "0" && "$top" != "0" ]] ; then
echo "Odd sized. Cropping $iden $left $top"
pamcut -left $left -top $top temp-$split.pnm>tmp.pnm
mv -f tmp.pnm temp-$split.pnm
elif [[ "$left" != "0" ]] ; then
echo "Odd sized. Cropping $iden $left $top"
pamcut -left $left temp-$split.pnm>tmp.pnm
mv -f tmp.pnm temp-$split.pnm
elif [[ "$top" != "0" ]] ; then
echo "Odd sized. Cropping $iden $left $top"
pamcut -top $top temp-$split.pnm>tmp.pnm
mv -f tmp.pnm temp-$split.pnm
else
echo "No cropping needed"
fi
if [[ $DITHER == "0" ]] ; then
ppmtopgm temp.pnm |pamthreshold -simple -threshold $THRESHOLD|pamtopnm>mask.pbm
else
ppmdither -red 2 -green 2 -blue 2 temp.pnm |pamditherbw -threshold -value $THRESHOLD|pamtopnm>mask.pbm
fi
cjb2 -lossy -clean -dpi $DPI mask.pbm mask.djvu
pamscale -reduce $BACKSUB temp-$split.pnm>temp2.pnm
pamscale -reduce $BACKSUB mask.pbm>mask2.pbm
pamscale -reduce $FGSUB temp-$split.pnm>temp3.pnm
pamscale -reduce $FGSUB mask.pbm>mask3.pbm
pnminvert mask3.pbm>maskinvert.pbm
c44 -crcbhalf -mask mask2.pbm temp2.pnm back.djvu
c44 -crcbfull -slice 100 -mask maskinvert.pbm temp3.pnm fore.djvu
djvuextract back.djvu BG44=back.iw44
djvuextract fore.djvu BG44=fore.iw44
djvumake `basename $i .jpg`-$split.djvu Sjbz=mask.djvu FG44=fore.iw44 BG44=back.iw44
split=$(($split-1))
done
done
fi
djvm -c "`basename \"$1\" .pdf`.djvu" myfile*.djvu

Tuesday, August 22, 2006

qualita doppia con djvumake

La qualita migliora sempre ecco come fare un djvu con foreground a 300dpi e background a 100 dpi (invece dei 50 di default) la qualita incrementa in modo notevole, anche le dimensioni purtoppo.


ermanno@localhost ~/.aMule/Incoming/work/dj $ for i in myfile*; do jpegtopnm $i|pamditherbw -threshold -value 0.85|pamtopnm>mask.pbm; cjb2 -lossy -clean mask.pbm mask.djvu; pnminvert mask.pbm>maskinv.pbm; c44 -dpi 100 $i -mask mask.pbm back.djvu; c44 -dpi 300 $i -mask maskinv.pbm fore.djvu; djvuextract back.djvu BG44=back.iw44; djvuextract fore.djvu BG44=fore.iw44; djvumake $i.djvu Sjbz=mask.djvu FG44=fore.iw44 BG44=back.iw44; done

I made a new version of the script this time the foreground is reduced 4 times and the background 2 times, this makes sense, I found out by myself that the previous script was crap becouse foreground and background were encoded at the same resolution ... It would be nice to have an option to djvumake to control the encoding of PPM=file ...

for i in ../myfile*.jpg; do jpegtopnm $i>temp.pnm; pamditherbw -threshold -value 0.85 temp.pnm|pamtopnm>mask.pbm; cjb2 -lossy -clean mask.pbm mask.djvu; pamscale -reduce 2 temp.pnm>temp2.pnm; pamscale -reduce 2 mask.pbm>mask2.pbm; pamscale -reduce 2 temp2.pnm>temp3.pnm; pamscale -reduce 2 mask2.pbm>mask3.pbm; pnminvert mask3.pbm>maskinvert.pbm; c44 -mask mask2.pbm temp2.pnm back.djvu; c44 -slice 100 -mask maskinvert.pbm temp3.pnm fore.djvu; djvuextract back.djvu BG44=back.iw44; djvuextract fore.djvu BG44=fore.iw44; djvumake test.djvu Sjbz=mask.djvu FG44=fore.iw44 BG44=back.iw44;done

Saturday, November 19, 2005

netpbm o imagemagik?

Certo che image magik è lento ...

Sto facendo dei test ma con netpbm si risparmia un po di tempo, specie se l'originale è già pulito. Utili i programmi per variare la gamma e il ditherbw che e' di ottima qualità. Non ho ancora trovato il modo di fare il threshold utilissimo per pulire scannerizzazioni veloci.

ermanno@localhost ~/work $ for i in myfile77*.jpg myfile780*.jpb myfile79*.jpg myfile8*.jpg; do jpegtopnm $i|pamditherbw|pamtopnm>test.pbm; cjb2 -lossy -clean test.pbm test.djvu; djvumake $i.djvu Sjbz=test.djvu PPM=$i; done

Meglio usare un thresholding semplice per ottenere risulati migliori:

for i in DollyWarden*; do jpegtopnm $i|pamditherbw -threshold -value 0.75|pamtopnm>test.pbm; cjb2 -lossy -clean test.pbm test.djvu; djvumake $i.djvu Sjbz=test.djvu PPM=$i; done

Il difficile e' trovare il giusto valore per il parametro value che deve essere tra 0 e 1 valori vicini ad 1 metteranno di piu' nel background e viceversa

Sunday, November 13, 2005

ottimizzare

Questa è una prima ottimizzazione dello script, la seconda parte:

ermanno@localhost ~/work $ for i in *.jpg; do echo $i; convert $i -geometry 2826x4047 -quality 99 temp.jpg; convert temp.jpg -threshold 50000 temp.pbm; cjb2 -dpi 300 -lossy -clean temp.pbm temp.djvu; djvumake $i.djvu Sjbz=temp.djvu PPM=temp.jpg; done

in questo modo si risparmiano i file temporanei. Un parametro di ghostscript se ho capito bene permette di riaprire il file di output ad ogni pagina, quindi forse di rieseguire unapipe ad ogni pagina, in questo modo si potrebbe eliminare il ciclo for e utilizzare uno script per fare tutte le conversioni senza nessun file temporaneo.

Che formato usare?

Dunque ricapitolando ci sono vari formati a disposizione:

jb2 bianco nero molto compresso
iw44 colori

una miscela dei due in formato separato, per creare il formato separato si può usare djvumake oppure cpaldjvu, la prima opzione da modo di controllare tutti i parametri e di ottimizzare la mask di foreground, cpaldjvu è più veloce di djvumake+imagemagik, più lento di djvumake+ghostscript-tiff.

Risparmiare tempo

ecco le due versioni dello script che sto usando adesso:

Versione normale con convert e threshold, si ottengono i migliori risultati adattando i parametri nello script, per ora non ci sono parametri.

#!/bin/bash
gsdjvu -sDEVICE=jpeg -dUseCropBox -sOutputFile='myfile%03d.jpg' -r900 -dPrinted -dNOPAUSE -dBATCH -dDOINTERPOLATE -dJPEGQ=99 -f "$1"
for i in *.jpg;do convert $i -threshold 61536 $i.pbm;done
for i in *.pbm;do cjb2 -clean $i $i.djvu;done
for i in *.jpg;do djvumake $i.djvu Sjbz=$i.pbm.djvu PPM=$i;done
djvm -c "$1.djvu" *.jpg.djvu

Modalità veloce, il foreground bianco/nero viene generato da ghostscript, su certi files funziona, il problema è che ghostscript ha un threshold molto alto e se lo scan è palliduccio (scan di fotocopie per esempio) il risultato è indecente, devo cercare bene nella documentazione, magari ci sono dei parametri per controllarlo. Sarebbe interessante perché è un metodo molto più veloce di imagemagik.

#!/bin/bash
gsdjvu -sDEVICE=jpeg -dUseCropBox -sOutputFile='myfile%03d.jpg' -r900 -dPrinted -dNOPAUSE -dBATCH -dDOINTERPOLATE -dJPEGQ=99 -f "$1"
gsdjvu -sDEVICE=tiffpack -dUseCropBox -sOutputFile='myfile%03d.tiff' -r900 -dPrinted -dNOPAUSE -dBATCH -dDOINTERPOLATE -dJPEGQ=99 -f "$1"
for i in *.tiff;do cjb2 -clean $i $i.djvu;done
for i in *.jpg;do djvumake $i.djvu Sjbz=$i.tiff.djvu PPM=$i;done
djvm -c "$1.djvu" *.jpg.djvu

Friday, November 11, 2005

Edge Detection

Oltre al thresholding si può utilizzare la edge detection per evidenziare il testo nella maschera foreground sono riuscito utilizzando gimp a trovare una edge detection che estrapoli ed evidenzi il testo. Purtroppo imagemagik non ha il tipo di edge detection che ha gimp, resta la speranza di utilizzarer cinepaint.
Ad ogni modo convert dura troppo bisogna trovare un tool che faccia lo stesso lavoro e piú velocemente.

Tempo e Spazio

Il tempo necessario per la conversione e lo spazio utilizzato sull'hard disk dai files temporanei sono un problema; le utility djvulibre accettano in input pochi formati e per le conversioni si perde un sacco di tempo. La parte piú complessa è trovare il valore di threshold giusto e purtroppo questo varia ogni volta, assumiamo che ce ne sia uno giusto per ogni libro scannerizzato comunque. Probabilmente la cosa piu' lenta sono è il threshold realizzato con imagemagik e ovviamente i jpg delle pagine sono la cosa che occupa piú spazio (sempre moolto meno che salvare nel formato lossless accettato da djvulibre, ppm).
file originale 541 pagine 34.516.195 bytes tantini direi
file risultante 2.902.529 bytes
leggibilità ottima, quasi indistinguibile dall'originale

file temporanei in kilobytes:
270.492 jpg pagine originali
128.516 jpg.pbm maschere b/w in formato pbm
4.156 jpg.pbm.djvu foreground con -clean
4.204 jpg.djvu pagine separate con djvumake

tempo complessivo su un pentium 2.200 Mhz 40 minuti

comandi usati

Sto cercando di utilizzare djvulibre per creare dei documenti djvu molto compressi e di buona qualità cosa abbastanza complessa.
ecco il metodo che sto usando:

ermanno@localhost ~/work $ gsdjvu -sDEVICE=jpeg -sOutputFile='myfile%03d.jpg' -r300 -dPrinted -dNOPAUSE -dBATCH -dDOINTERPOLATE -dJPEGQ=95 -f file_scannerizzato.pdf

Stampare tutte le pagine in formato jpg ad una risoluzione opportuna vartiando il parametro -r.

ermanno@localhost ~/work $ for i in *.jpg;do convert $i -threshold 35536 $i.pbm;done

Creare un threshold dell'immagine in formato pbm con Image Magik, variare il parametro -threshold in modo che si crei un pbm leggibile, questo sara il foregroung.

ermanno@localhost ~/work $ for i in *.pbm;do cjb2 $i $i.djvu;done

Convertire il foreground in djvu, è possibile utilizzare il parametro -clean per comprimere maggiormente.

ermanno@localhost ~/work $ for i in *.jpg;do djvumake $i.djvu Sjbz=$i.pbm.djvu PPM=$i;done

Creare il djvu separato per tutte le pagine.

ermanno@localhost ~/work $ djvm -c file_scannerizzato.djvu *.jpg.djvu

creare il djvu composto con tutte le pagine del libro.

Ma sí blogghiamolo!!

Chissa se blogghiamolo è la translitterazione giusta di blog this .....

Comunque, ho deciso di bloggare a riguardo dei tentativi che sto facendo con la suite djvu-libre per avere i miei appunti a portata di mano e permettere pure ad altri di leggerli.

Non intendo assolutamente spiegare che cosa e' djvu, in fondo sono i miei appunti e io lo so giá. In particolare sto cercando di utilizzare il formato per comprimere dei libri scannerizzati.

Comunque chi ha usato una soluzione djvu commerciale e poi e' passato a quella open-source sá che quella commerciale produce file molto piú compressi e di qualitá superiore (per quanto possa sembrare strano).
Esaminando i documenti prodotti dai prodotti commerciali ci si accorge che utilizzano il formato separato, cioè di ogni pagina vengono memorizzate due copie il foreground e il background, il foreground ad alta risoluzione compresso con jb2 e il background con iw44 o cpaldjvu a bassa risoluzione, quando l'immagine viene visualizzata le due immagini vengono combinate.
Se le cose sono state fatte bene nell'immagine jb2 c'è il testo e nell'altra le sfumature della carta e le immagini.

Ma come realizzare su linux tutto ciò? Mica facile, all'inizio si diceva che era perché un tool (gsdjvu) non era stato rilasciato perchè protetto da copyright, L'anno scorso è stato finalmente rilasciato ma probabilmente chi lo utilizzera rimarrà abbastanza deluso in quanto serve a convertire in djvu file pdf che non sono stati generati scannerizzando dei testi.
Inoltre la tanto decantata utility djvudigital utilizza delle pipe per trasmettere le immagini da gs a csepdjvu e se il file da convertire è grosso molto probabilmente esaurirà la memoria del Pc prima di riuscire a terminare il suo lavoro.
Quindi per quanto utile non risolve il problema, anche perché molto spesso il file che genera e' piu' grosso del file da convertire oppure di scarsa qualità. Il problema è che nei pdf scannerizzati ogni pagine viene memorizzata come una unica immagine jpg e il buon gsdjvu a seconda del threshold la metterà probabilmente o tutta nel background o tutta nel foreground.