ich moechte ein eingescanntes BMP-Bild drehen. Eingescannt
wurde Millimeterpapier mit schwarzen Messlinien. Wie kann
ich mit meinem Programm das Bild so drehen, das das
Millimeterpapier genau waagerecht liegt. Der Scann ist in
Farbe und die Millimeterlinien in Rot zu sehen. Leider sind
sie nicht nur ein sondern 3 bis 5 Pixel breit, wobei das
äusserste Pixel immer sehr hell geraten ist.
Ich moechte damit mehrere hundert Scanns bearbeiten und
nicht bei jedem stundenlang das Papier auf dem Scanner
ausrichten....
Hab bis jetzt noch keine Idee wie ich den Winkel um den das
Bild gedreht werden muss herausbekomme :(
Ich hoffe es hat jemand eine tolle Ideeeeee :)))))
DANKE
Alexander
> ich moechte ein eingescanntes BMP-Bild drehen. Eingescannt
> wurde Millimeterpapier mit schwarzen Messlinien. Wie kann
> ich mit meinem Programm das Bild so drehen, das das
> Millimeterpapier genau waagerecht liegt. Der Scann ist in
> Farbe und die Millimeterlinien in Rot zu sehen. Leider sind
> sie nicht nur ein sondern 3 bis 5 Pixel breit, wobei das
> äusserste Pixel immer sehr hell geraten ist.
Da die Linien rot sind (und wahrscheinlich das einzig rote
in Deinem Bild), kannst Du sie doch leicht finden...
Du betrachtest das Bild als Binaerbild (rot ist schwarz
und alles andere weiss), somit hast Du nur noch das
Raster der Linien im Bild.
Falls das Millimeterpapier einen (duchgehenden) Rand hat
(und dieser auch in Deinem Bild zu sehen ist), solltest
Du versuchen diesen anzutasten (es ist erstmal egal, ob
dieser Rand senkrecht oder waagerecht ist).
Angenommen, der Rand ist senkrecht und links im Bild.
Weiterhin nehme ich an, dass die Bilder um weniger als
ca. 10-20° verdreht sind.
Du faengst am besten in halber Bildhoehe links an und
laeufst in der Zeile so weit nach rechts, bis Du
einen entsprechned hohen Rotanteil gefunden hast.
...
Z := Bitmap.ScanLine[Bitmap.height / 2];
x := 0;
while ((Rotanteil(Z[x])>SchwellWert) and (x < Bitmap.width -1)) do
Inc(x);
// X-wert merken (=Position der Kante)
// das Ganze fuer eine andere Zeile (eine weiter oben) wiederholen.
// wenn sich die gefundenen Kanten-Positionen in aufeinanderfolgenden
// Zeilen stark aendern, ist die Kante abgerissen.
// Dann mach das ganze für die untere Haelfte des Bildes.
// Nun hast Du die Position vieler Punkte an einer Kante.
...
Rotanteil() ist dabei eine function, die (wer haette es
vermutet?) den Rot-Anteil aus dem Farbwert extrahiert.
Bei RGB-codierten Bitmaps ist das einfach das R-Byte.
Um aus den Punkten eine Gerade zu machen, verwende eine lineare
Regressionsgerade oder berechne zwischen vielen Punkten die Steigung
und mittele oder ... kommt halt auf die geforderte Genauigkeit an.
Das beschriebene Verfahren stellt natuerlich nur eine Idee und
deren groben Verlauf dar. Weitere Vorgehensweisen sind
denkbar, aber stark von Anforderungs-Details abhaengig.
Zum Drehen des Bildes nimmst Du dann am Besten eine fertige
Komponente (oder programmierst die bilineare Interpolation
halt selbst).
Falls Du mehr Infos oder weitere Hilfe brauchst, kannst Du
Dich per e-mail bei mir melden.
> Ich moechte damit mehrere hundert Scanns bearbeiten und
> nicht bei jedem stundenlang das Papier auf dem Scanner
> ausrichten....
>
> Hab bis jetzt noch keine Idee wie ich den Winkel um den das
> Bild gedreht werden muss herausbekomme :(
>
> Ich hoffe es hat jemand eine tolle Ideeeeee :)))))
Viel Spass
TOM
Danke für die Tips, ich habe schon eine Komponente gefunden
die mir das Bild dreht. Jetzt muß ich nur noch den Winkel
berechnen. Leider ist der Rand des Millimeterpapiers nicht
mehr zu sehen, da die Scanns aus dem mittleren Teil von
DIN-A3 stammen. Aber wenn man die senkrechten und
waagerechten Linien isoliert kann man sicherlich auch den
Winkel bekommen.
Jedenfalls kann ich jetzt wieder hoffen das das Auswerten
der Scanns doch noch Spaß macht weil ich es nicht von Hand
machen muß ;-)
THANX Alexander
> Danke für die Tips, ich habe schon eine Komponente gefunden
> die mir das Bild dreht.
Kannst Du uns die URL geben?
Ich habe auch noch zwei Hinweise:
Nettes Beispiel mit Sourcecode...
http://www.efg2.com/lab/ImageProcessing/RotateScanline.htm
Und auf den Delphi-Pages ( http://www.delphipages.com/ ) ist eine
Komponente (Shareware), die neben vielen andern Funktionen auch
Rotation erlaubt (PixelGraphicLibrary 1.0 beta 5).
Habe ich eben mal kurz ausprobiert (D3). Funktioniert sehr gut!
So, schoenes Wochenende!
TOM
Simon Reinhardt schrieb in
<01be7226$f5232f00$2fe1...@ppp0.klaus-datentechnik.de>:
> Das findest Du auch auf Peter Haas' Heimseite. Die URL steht in meiner FAQ.
Mein Demo dreht aber nur in 90 Grad-Schritten, das ist hier nicht so gefragt.
Allerdings kann Alexander dort Hinweise finden, wie er schnell auf die Bitmap
zugreift.
MfG Peter
--
HomePage: http://home.t-online.de/home/PeterJHaas/delphi.htm
> Kannst Du uns die URL geben?
>
Ich habe dazu erst die Freeware-Komponente TFastBmp Version
0.05 (von Torry oder DSP... weiss nich mehr:) ) benutzt und
in mein Programm integriert. Die Komponente beschleunigt die
Bearbeitung der Grafik und besitzt dazu noch einige Routinen
unter anderem auch einen Rotate Algorithmus zur
Demonstration. Es gibt inzwischen eine neue Version 1.2
glaub ich, aber dort ist das Beispielprogramm nicht mehr als
Quellcode sondern nur noch als Exe Datei dabei.
Allerdings habe ich nun den Rotate-Algorithmus von
> http://www.efg2.com/lab/ImageProcessing/RotateScanline.htm
genommen. (Beispiel SIZER von 11/98 Datei: DI9811RS.ZIP ) Er
braucht zwar bedeutend laenger aber das Ergebnis sieht
wesentlich besser aus. (Kein Treppeneffekt)
War echt eine gute Adresse! Hätte ich nie gefunden :)
Ich werde wohl noch Versuchen beides zu Kombinieren, so dass
der Algorihmus ein FastBmp rotiert, damit es schneller geht.
Damit bin ich dann eigentlich voll zufrieden, falls nicht im
Laufe des Anwendens noch Fehler auftreten oder ich (wie so
oft) einen besonders verrückten Einfall habe und mal wieder
alles umändere... :)
>
> So, schoenes Wochenende!
>
Danke, hatte ich.
Allerdings auch platte Füsse nach zwei langen Tagen auf der
CeBit !
Alexander.