Fujitsu Scansnap ix500 mit Raspbian (Raspberry Pi) als Scanserver nutzen

Ich träume schon lange von einem papierlosen Büro. Alle meine Dokumente habe ich damit zu jeder Zeit digital, überall und vor Allem ohne lästiges Suchen griffbereit. Zum Beispiel benötige ich ein mal im Jahr alle Unterlagen, um meine Steuererklärung erstellen zu können. Mit nur einem Klick liefert mir mein Digitales Zuhause alle notwendigen Unterlagen.

Dazu habe ich mir den Fujitsu Scansnap ix500 gekauft. Dieses Gerät hat eine WLAN-Anbindung und ich habe gehofft, damit direkt (ohne zusätzlichen Rechner) auf mein NAS (N54L) zu scannen. Leider ist das so trotz WLAN nicht möglich, es wird immer eine Windows-Software von Fujitsu benötigt. Zusätzlich kann man nicht einfach einen beliebigen Rechner mit dem Scann „koppeln“. Ist ein Rechner per WLAN verbunden, so verhindert das, dass man einen anderen Rechner „koppelt“.

Damit ich dennoch meine Scans ohne einen Rechner auf ein SMB Share speichern kann, nehme ich den Raspberry Pi zur Hilfe. Folgender Plan: Über USB wird der ix500 an den RPi angeschlossen und der RPi speichert die Scans zuerst auf der SD-Karte und schiebt diese auf ein NAS.

Benötigte Technologie:

  • Fujitsu Scansnap ix500
  • Raspberry Pi (Model B, B+ oder RPi 2)
  • SD-Karte (besser als 8 Gb Class 10, z. B. 16 Gb)
  • Stromanschluss für den RPi

Die ersten (schematischen) Schritte sind also:

  • SD-Karte beschreiben mit Raspbian Wheezy
    • Bspw. Verwendung von Win32DiskImager
  • sudo raspi-config
    • Expand Filesystem
    • Ggf. overclocking
  • sudo rpi-update
  • aktivieren der sourcen in der sources.list ( sudo nano /etc/apt/sources.list ). Wir benötigen später den Quellcode einiger Pakete zusätzlich
  • apt-get update && apt-get upgrade
  • Upgrade von Wheezy auf Jessie (Howto hier)

Installation von sane für den Fujitsu Scansnap ix500

Ist alles vorbereitet, so muss sane (die Bibliothek für den Zugriff auf Scanner unter Linux) installiert werden. Für den ix500 wird eine sehr aktuelle Version benötigt, also installieren wir diese von den aktuellen Sourcen (Sourcecode).

Wir loggen uns dazu in den RPi über SSH ein und werden für die nächsten Schritte root

sudo -s

Der user pi soll den Scanner nutzen dürfen. Dazu muss die Gruppe scanner erstellt werden und der Benutzer pi hinzugefügt werden.

addgroup scanner
adduser pi scanner

Installation der Pakete für die Installation von sane

apt-get install libusb-dev

In das Arbeitsverzeichnis wechseln, dann den Quelltext aus dem Git Repository holen

cd /usr/local/src
git clone git://git.debian.org/sane/sane-backends.git

Jetzt wechseln wir in das heruntergeladene sane-backends-Verzeichnis und konfigurieren die Dateien. Das kann nun auf dem RPi eine kleine Weile dauern =)

cd sane-backends
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var

Jetzt kann sane kompiliert und installiert werden. Auch das kann wieder einige Minuten dauern =)

make
make install

Nicht mehr benötigt werden die Pakete aus dem Repository, die können entfernt werden:

apt-get remove libsane

Jetzt noch schnell testen, ob die korrekte Library präferiert wird. Wichtig ist hier, dass die 1.0.25 oben steht (sollte mehr als eine libsane library vorhanden sein)

ldconfig -v | grep libsane
		         libsane.so.1 -> libsane.so.1.0.25
         libsane.so.1 -> libsane.so.1.0.23

Sind zwei Libraries vorhanden und die Reihenfolge ist nicht korrekt, hilft folgender Befehl. Danach nochmals mit dem Vorigen testen, ob die Reihenfolge nun korrekt ist.

echo "/usr/local/lib" | sudo tee -a /etc/ld.so.conf.d/1-sane.conf

Testen von Scanimage – hier soll bei beiden Versionsangaben die Version 1.0.25 stehen

scanimage -V
scanimage (sane-backends) 1.0.25git; backend version 1.0.25

Als nächstes die Sprachdateien (Deutsch = de) verlinken

cd /usr/share/locale/de/LC_MESSAGES
ln -sf /usr/local/share/locale/de/LC_MESSAGES/sane-backends.mo .
cd -

Die udev Regeln müssen aktualisiert werden. Danach den Scanner kurz abstecken und wieder anstecken (USB-Port)

cd /usr/local/src/sane-backends
cp tools/udev/libsane.rules /etc/udev/rules.d

Der erste Test kann nun erfolgen, ob der Scanner erkannt wird. Dazu muss der Scanner an sein, das bedeutet, dass das blaue Licht leuchten muss.

scanimage -L
device `fujitsu:ScanSnap iX500:40404' is a FUJITSU ScanSnap iX500 scanner

Als nächster Test loggen wir uns als Administrator aus und führen den Test als unprivilegierter Benutzer „pi“ durch. Hier sollte das selbe Ergebnis angezeigt werden. Eventuell hilft hier zuvor ein beherzter reboot.

exit
scanimage -L
device `fujitsu:ScanSnap iX500:40404' is a FUJITSU ScanSnap iX500 scanner

Test erfolgreich. Jetzt wissen wir, dass der Scanner funktioniert.

Installation und Konfiguration von scanbd

Scanbd ist dafür zuständig die Buttons des Scanners zu überwachen und bei Status-Änderungen ein Skript zu starten. Die Voraussetzungen für das bauen dieses Daemon sind:

sudo -s
cd /usr/local/src
ln -s /bin/sed /usr/bin/sed
apt-get install gawk libconfuse-dev libsane-dev libudev-dev libusb-dev -y

Als root die Dateien für scanbd des letzten Releases (aktuell 1.4.3) downloaden, entpacken, konfigurieren und installieren.

wget -O scanbd-1.4.3.tgz http://downloads.sourceforge.net/project/scanbd/releases/scanbd-1.4.3.tgz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fscanbd%2Ffiles%2Freleases%2F&ts=1438690952&use_mirror=netcologne
tar xvzf scanbd-*.tgz
cd 1.4.3
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
USE_SANE=yes make -e clean all
USE_SANE=yes make install

Dann werden die Konfigurationsdateien kopiert (scanbd wird client, sane wird server)

cp /etc/sane.d/dll.conf /etc/scanbd/

In der dll.conf von sane: alles entfernen außer net

nano /etc/sane.d/dll.conf

in der dll.conf von scanbd: net Zeile deaktivieren (setzen einer # davor)

nano /etc/scanbd/dll.conf

Sane Konfigurieren (Aktivieren von connect_timeout = 60 und localhost in den Einstellungen)

nano /etc/sane.d/net.conf

Backend Dateien von sane nach scandb kopieren (ACHTUNG: Nichts überschreiben!!!)

cp -i /etc/sane.d/*.conf /etc/scanbd/

Zur besseren Übersicht aktivieren wir das debugging und setzen das Level auf 5. Zusätzlich muss dem Parameter group der Wert scanner zugewiesen werden, denn nur diese Gruppe darf scannen:

nano /etc/scanbd/scanbd.conf

Jetzt der erste Testlauf, ob Scanbd startet:

export SANE_CONFIG_DIR=/etc/scanbd
/usr/sbin/scanbd -f -d -c /etc/scanbd/scanbd.conf

Jetzt sollte die Konsole von Meldungen überflutet werden. Daran erkennt man, dass der Scanner abgefragt wird. Wie gewohnt kann mit STRG+C das Programm beendet werden.

Jetzt wird das Startscript kopiert und als Service registriert und aktiviert:

cp /usr/local/src/1.4.3/integration/scanbd.debian /etc/init.d/scanbd
chmod 755 /etc/init.d/scanbd
update-rc.d scanbd defaults
systemctl enable scanbd.service

Jetzt kann man mit /etc/init.d/scanbd start den Deamon starten und er wird auch beim Systemstart geladen. Eine kleine Einstellung muss in dieser Daemon-Datei vorgenommen werden, damit der Binäre Pfad zu diesem System passt: DAEMON=/usr/sbin/$NAME

nano /etc/init.d/scanbd

Nun kann der Daemon getestet werden:

/etc/init.d/scanbd start

[ ok ] Starting scanbd (via systemctl): scanbd.service.

Debug Level zurücksetzen in /etc/scanbd/scanbd.conf auf 2 und Umstellen vom Parameter scriptdir auf /etc/scanbd:

nano /etc/scanbd/scanbd.conf

Damit werden alle mit ausgelieferten Skripte, beispielsweise test.script aktiv. Ein tapferer Reboot, dann prüfen, ob alles funktioniert:

sudo /etc/init.d/scanbd status

scanbd.service – Scanner button polling Service
Loaded: loaded (/lib/systemd/system/scanbd.service; enabled)
Active: active (running) since Tue 2015-08-04 13:37:21 UTC; 4min 46s ago
Main PID: 497 (scanbd)
CGroup: /system.slice/scanbd.service
/usr/sbin/scanbd -f -c /etc/scanbd/scanbd.conf

tail -f /var/log/syslog

Noch schnell auf den Scan-Button drücken und man kann diese Ausgabe sehen:

Aug 4 13:38:42 raspberrypi systemd[1408]: Starting Timers.
Aug 4 13:38:42 raspberrypi systemd[1408]: Reached target Timers.
Aug 4 13:38:42 raspberrypi systemd[1408]: Starting Sockets.
Aug 4 13:38:42 raspberrypi systemd[1408]: Reached target Sockets.
Aug 4 13:38:42 raspberrypi systemd[1408]: Starting Basic System.
Aug 4 13:38:42 raspberrypi systemd[1408]: Reached target Basic System.
Aug 4 13:38:42 raspberrypi systemd[1408]: Starting Default.
Aug 4 13:38:42 raspberrypi systemd[1408]: Reached target Default.
Aug 4 13:38:42 raspberrypi systemd[1408]: Startup finished in 37ms.
Aug 4 13:38:42 raspberrypi systemd[1]: Started User Manager for UID 1000.
Aug 4 13:40:22 raspberrypi scanbd: /usr/sbin/scanbd: trigger action for scan for device fujitsu:ScanSnap iX500:40404 with script test.script
Aug 4 13:40:22 raspberrypi rsyslogd-2007: action ‚action 17‘ suspended, next retry is Tue Aug 4 13:40:52 2015 [try http://www.rsyslog.com/e/2007 ]
Aug 4 13:40:22 raspberrypi scanbd: /etc/scanbd/test.script: Begin of scan for device fujitsu:ScanSnap iX500:40404
Aug 4 13:40:23 raspberrypi scanbd: /etc/scanbd/test.script: End of scan for device fujitsu:ScanSnap iX500:40404

Übersetzt bedeutet das: Der Scanner wird gefunden und wenn auf den Scanbutton gedrückt wird, erkennt das scanbd und startet das Skript „test.script“ =)

Verwendung eines Scanner-Skripts

Jetzt kann mit dem Script gestartet werden. Damit eine Umwandlung von TIFF auf PDF durchgeführt werden kann, wird folgendes Paket benötigt.

sudo apt-get install libtiff-tools -y

Für OCR kann tesseract verwendet werden. Hier installieren wir auch gleich alle Sprachpakete mit (wegen korrekter Erkennung von Umlauten etc.)

sudo apt-get install tesseract\* -y

Damit Multi-Page Tiffs erkannt und mit OCR überprüft werden können, wird noch ein Paket benötigt:

sudo apt-get install libtiff-dev -y

Für die Bearbeitung (bspw. drehen von PDFs) wird folgendes Programm benötigt und installiert:

sudo apt-get install pdftk imagemagick -y

Jetzt kann mit diesen Paketen ein kleines Skript geschrieben werden, welches mehrere Seiten über den Fujitsu Scansnap ix500 in Lineart / S/W einscannen kann und daraus ein PDF mit Texterkennung erstellen kann.

#!/bin/bash

##########################################
## SCRIPT VERSION	1.0.3		##
## AUTHOR:		MARKUS		##
## Requires apt-get install:		##
##		libtiff-tools		##
##		tesseract\*		##
##		libtiff-dev		##
##		pdftk			##
##		imagemagick		##
##########################################

#startdir=$(pwd)
startdir=/home/pi
RANDOMNUMBER=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c${1:-16})
outname=$RANDOMNUMBER.pdf
tmpdir=scan-$RANDOMNUMBER
# For deleting blank pages
threshold=0.99
# Regex to check for orientation = 180 degree
regex="\s+Orientation in degrees: ([0-9]{3})\s+"

echo "####### TMPDIR $tmpdir ##########"
cd /tmp
mkdir $tmpdir
cd $tmpdir
echo "################## Scanning ###################"
sudo scanimage --page-width 221.121 --page-height 876.695 -l 0 -t 0 -x 221.121 -y 876.695 --ald=yes --overscan On --prepick=On -b --format=tiff --mode Lineart --resolution 600 --source 'ADF Duplex' --swcrop=yes --buffermode On --swdespeck 2 --swdeskew=yes --swskip 5% --offtimer 0
echo "################### OCRing ####################"
i=1
for page in $(ls -v *.tif); do
	x=`printf "%04d" $i`
	echo "---PAGE: $i -BEGIN-----"
	echo "---PAGE: $i -TIFF2PDF--"
	tiff2pdf -o tiff2pdf_$x.pdf -z -u m -p "A4" -F $page
	echo "---PAGE: $i -PDFTK-----"
	echo "---PAGE: $i -FLATTEN---"
	pdftk tiff2pdf_$x.pdf cat output pdftk_$x.pdf flatten
	pdftk pdftk_$x.pdf dump_data > pdftk_$x.info
	# Test if it is a blank page
	convert pdftk_$x.pdf -colorspace Gray greyscale_$x.tif
	test=`convert "greyscale_$x.tif" -format "%[fx:mean>$threshold?1:0]" info:`
	echo "---PAGE: $i is blank for %: " `convert greyscale_$x.tif -format "%[fx:mean]" info:`
	if [ $test -eq 1 ]; then
		echo "---PAGE: $i -SKIP------"
	else
		echo "---PAGE: $i -NORMALIZE-"
		convert -normalize -density 300 -depth 8 pdftk_$x.pdf $x.png
			echo "---PAGE: $i -TESSERACT-"
		tesseract -psm 0 -l deu+eng $x.png result_$x 1>tesseract_$x.info 2>&1
		tesseract -psm 1 -l deu+eng $x.png result_$x pdf quiet 1>/dev/null 2>&1
		echo "---PAGE: $i -METADATA--"
		pdftk result_$x.pdf dump_data > pdftk_$x.info2
		pdftk result_$x.pdf update_info pdftk_$x.info output final_$x.pdf
		# Orientation check
		file="tesseract_$x.info"
		file_content=$( cat "${file}" )
		if [[ " $file_content " =~ $regex ]]; then
			case "${BASH_REMATCH[1]}" in
				'180' | '270')
					# 180 is upside down - 270 is not readable from right side
					echo "Detected wrong orientation:" ${BASH_REMATCH[1]}
					mv final_$x.pdf wrong_orientation_$x.pdf
					pdftk wrong_orientation_$x.pdf rotate oddsouth output final_$x.pdf
				;;
				*)
					echo "---PAGE: $i has Orientation ${BASH_REMATCH[1]}"
				;;
			esac
		fi
	fi
	echo "---PAGE: $i -END------"
	i=$(expr $i + 1)
done


echo "############ Combine all pdf to one ###########"
pdftk final_*.pdf cat output $startdir/$outname


#echo "################ Cleaning Up ################"
cd ..
rm -rf $tmpdir
cd $startdir

Das Script muss ausführbar gemacht, in der scanbd.conf referenziert und über die scanbd.conf immer dann ausgeführt werden, wenn der Scan-Button gedrückt wird.

chmod +x /etc/scanbd/scnDuplex.script
nano /etc/scanbd/scanbd.conf

Fragen und Zusammenfassung

Mein Hauptproblem ist immer noch die Bildbearbeitung und OCR bei Farb-Scans. Beim Scanner ist die Windows-Lösung von ABBYY mit dabei und diese Funktioniert (auf Windows) hervorragend. Aber sie funktioniert leider nicht auf dem Raspberry Pi, da es ein Windows Programm ist. Die Linux Variante von ABBYY OCR hat genau das gleiche Problem – sie läuft nicht auf dem Raspberry Pi (wg der ARM Architektur).

Somit ist das Problem: Zuverlässige Texterkennung bei Scans in Farbe. Aktuell führe ich OCR auf Lineart (S/W) Bildern durch, was eine sehr gute Erkennungsrate hat. Bei Farbei ist das Ergebnis deutlich schlechter. Mein Gedanke wäre nun, OCR und Bilddrehung auf S/W-Ebene durchzuführen und dann die OCR Informationen zum eingescannten Farb-Bild zu migrieren. Hierfür habe ich jedoch leider noch nicht die passende Lösung gefunden.

Die Dateiablage kann in einem ersten Schritt über eine sinnvolle Ordner-Struktur (Beispielsweise „Rechnungen/Fahrzeuge/GolfV2004/“ oder „Rechnungen/Telekommunikation/Internet“). Im nächsten Schritt wird dann ein DMS verwendet, über das eine Mehrfachzuordnung möglich ist. Mein Anwendungsfall dazu ist die Steuererklärung. So kann ich eine Rechnung zum Fahrzeug zuordnen und mir für meine Steuererklärung vormerken – auch über mehrere Jahre der Abschreibung hinweg (beispielsweise für neu angeschaffte PCs).

Als Ergebnis meiner Tüftelei habe ich nun einen hervorragenden Scanner kombiniert mit dem Raspberry Pi. Ich kann meine Dokumente mit OCR in einem Zielsystem / DMS / Share ablegen und nach den Inhalten durchsuchen. Das Problem mit fehlender Farbe bei den Scans (was für Archivierung leider im Zweifel für Nachweise notwendig sein kann) kann nur organisatorisch gelöst werden: Alles gescannte behalten 🙁 Und damit ist der Traum des papierlosen Büro / Zuhause wieder etwas in die Ferne geschoben. Aber vielleicht hat ein Leser hier den zündenden Gedanken? Ich würde mich sehr darüber und auch über Feedback freuen!

Ein weiteres Thema, das es zu lösen gilt, ist die Verlinkung zwischen analoger und digitaler Ablage. Hier gibt es beispielsweise den Lösungsansatz eines Paginierstepels. Damit wird vor der Digitalisierung eine Fortlaufende Nummer auf das Dokument gestempelt und nach dem Scan werden alle Dokumente Chronologisch abgelegt und über die Nummer wieder gefunden werden. Die offene Frage hierzu sind die Aufbewahrungsfristen. Als Beispiel nehme ich eine Rechnung mit wenigen Jahren Erhaltungs- / Archivierungswert und der Vertrag einer Lebensversicherung über mehrere Jahrzente Laufzeit. Legt man beide Dokumente fortlaufend ab, sollte ein Ordner niemals entsorgt werden.

Quellen

  • http://www.morethantechnical.com/2013/11/21/creating-a-searchable-pdf-with-opensource-tools-ghostscript-hocr2pdf-and-tesseract-ocr/
  • http://blog.konradvoelkel.de/2013/03/scan-to-pdfa/
  • https://code.google.com/p/tesseract-ocr/wiki/FAQ#Does_it_support_multi-page_tiff_files?
  • http://www.mehr4u.de/mit-scanbd-scannertasten-an-einem-canon-mx700-nutzen.html
  • http://artem.gratchev.com/2015/01/home-scan-station-based-on-raspberry-pi/
  • https://wiki.archlinux.org/index.php/Scanner_Button_Daemon
  • http://sourceforge.net/projects/scanbd/
  • https://robinclarke.net/archives/the-paperless-office-with-linux
  • http://askubuntu.com/questions/10617/how-to-exchange-remove-overwrite-a-pdfs-background
  • http://thomasheinz.net/mit-einem-tastdruck-scannen-raspberry-pi-und-dokumentenarchivierung/
  • http://www.mehr4u.de/mit-scanbd-scannertasten-an-einem-canon-mx700-nutzen.html
  • http://www.michaelm.info/blog/?p=1375
  • https://ivanblatter.com/papierloses-buero-scannen/ & https://ivanblatter.com/papierloses-buero-namen/
  • http://www.schlosser.info/buero-papierlos-scanner-scanscap/

Gedanken und weiterführende Ansätze

  • http://oliver-amann.de/projekt-postsortierer/2/
  • Anderer Scanner: Scanner Brother ADS-2600WE auf Amazon