Unscharf ist sanfter
Bevor ein Skript die drei gesuchten Regionen in der Bildmitte fehlerfrei erkennen kann, sind noch einige Vorbereitungsschritte erforderlich. Abbildung 2 macht deutlich, dass der Graph stark schwankt, was die Erkennung der flachen Stellen erschwert. Das Erkennungsskript »cardfind« (Listing 2) nutzt daher einen Blur-Filter, um das Bild mit dem Verfahren Gaussian Blur und einem Radius von zehn Pixeln unscharf zu machen.
|
Listing 2: |
|---|
01 #!/usr/local/bin/perl -w
02 use strict;
03 use Imager;
04 use YAML qw(Dump);
05
06 my($file) = @ARGV;
07 die "No file given" unless defined $file;
08
09 my $img = Imager->new();
10 $img->read(file => $file) or
11 die "Can't read $file";
12
13 # Blur
14 $img->filter(
15 type => "gaussian",
16 stddev => 10 ) or die $img->errstr;
17
18 my $y = int( $img->getheight() / 2 );
19 my $width = $img->getwidth();
20
21 my @intens_ring = ();
22 my @diff_ring = ();
23 my $found = 0;
24 my @ctl_points = ();
25
26 for my $x (0..$width-1) {
27 my $color = $img->getpixel( x => $x,
28 y => $y );
29 my @components = $color->rgba();
30
31 # Save current intensity in ring buffer
32 my $intens = @components[0,1,2];
33 push @intens_ring, $intens;
34 shift @intens_ring if @intens_ring > 50;
35
36 # Store slope between x and x-50
37 push @diff_ring,
38 abs($intens - $intens_ring[0]);
39 shift @diff_ring if @diff_ring > 50;
40
41 if($found) {
42 # Inside flat region
43 if(avg(@diff_ring) > 10) {
44 $found = 0;
45 }
46 } else {
47 # Outside flat region
48 if($x > $width/3 and
49 $x < 2/3*$width and
50 avg(@diff_ring) < 3) {
51 $found = 1;
52 push @ctl_points,
53 [@components[0,1,2]];
54 }
55 }
56 }
57
58 my $out = {};
59 my @labels = qw(low medium high);
60
61 # Sort by intensity
62 for my $ctl_point (sort {
63 $a->[0] + $a->[1] + $a->[2] <=>
64 $b->[0] + $b->[1] + $b->[2] }
65 @ctl_points) {
66 my $label = shift @labels;
67 $out->{$label}->{red} = $ctl_point->[0];
68 $out->{$label}->{green}= $ctl_point->[1];
69 $out->{$label}->{blue} = $ctl_point->[2];
70 last unless @labels;
71 }
72
73 print Dump($out);
74
75 ###########################################
76 sub avg {
77 ###########################################
78 my($arr) = @_;
79
80 my $sum = 0;
81 $sum += $_ for @$arr;
82 return $sum/@$arr;
83 }
|
In einem unscharfen Bild (Abbildung 3) sind die Farbübergänge zwischen den einzelnen Pixeln weniger abrupt. Statt zum Beispiel direkt von einem weißen Pixel auf einen schwarzen Bildpunkt zu springen, enthält ein unscharfes Bild an dieser Stelle mehrere Grautönen als Übergang. Entsprechend geglättet stellt sich der Graph in Abbildung 4 dar, der die Pixelwerte entlang der gleichen horizontalen Linie visualisiert. Dieses Verfahren erleichtert die Erfassung der drei gesuchten Regionen erheblich.
Abbildung 3: Der Blur-Filter mit der Einstellung Gaussian Blur und einem Radius von zehn Pixeln erzeugt Unschärfe und glättet die Wogen der Pixelwerte. Die Farbflächen der Karten sind damit leichter auszumachen.
Abbildung 4: Das mit dem Blur-Filter unscharf gemachte Bild weist glattere Kurvenverläufe auf, an denen sich die ins Bild gehaltenen Karten an den flachen Stellen erkennen lassen.
In der Schule aufgepasst?
In diesen Bereichen verläuft die Kurve über Hunderte von Pixeln recht flach. Wer sich noch an die Schulmathematik erinnert, dem fällt vielleicht ein, dass die erste Ableitung eines solchen Graphen an flachen Stellen konstant und etwa gleich null ist, während sie sonst deutlich höhere Werte aufweist und stark schwankt. Abbildung 5 zeigt die erste Ableitung der Intensitätswerte, die sich aus der Addition der Pixelwerte für den roten, grünen und blauen Kanal ergeben.
Abbildung 5: Die erste Ableitung des Intensitätsgraphen weist für die flachen (also homogenen) Bildstellen Werte nahe null auf.
Die aufgezeichneten Werte stellen ein Maß für die Schwankungen der ursprünglichen Kurve dar und bewegen sich über lange Strecken nahe des Nullpunkts. Dies sind die Stellen, an denen im ursprünglichen Bild die Karten mit ihren homogenen Grauwerten liegen. Das Skript muss nur an diesem Graphen entlangwandern, einen Ringpuffer von etwa 50 beobachteten Werten anlegen und Alarm schlagen, falls die dort liegenden Werte durchschnittlich etwa gleich null sind. Dann befindet es sich über einer Karte.
Diesen Artikel als PDF kaufen
Als digitales Abo
Weitere Produkte im Medialinx Shop »
Versandartikel
Onlineartikel
Alle Rezensionen aus dem Linux-Magazin
- Buecher/07 Bücher über 3-D-Programmierung sowie die Sprache Dart
- Buecher/06 Bücher über Map-Reduce und über die Sprache Erlang
- Buecher/05 Bücher über Scala und über Suchmaschinen-Optimierung
- Buecher/04 Bücher über Metasploit sowie über Erlang/OTP
- Buecher/03 Bücher über die LPI-Level-2-Zertifizierung
- Buecher/02 Bücher über Node.js und über nebenläufige Programmierung
- Buecher/01 Bücher über Linux-HA sowie über PHP-Webprogrammierung
- Buecher/12 Bücher über HTML-5-Apps sowie Computer Vision mit Python
- Buecher/11 Bücher über Statistik sowie über C++-Metaprogrammierung
- Buecher/10 Bücher zu PHP-Webbots sowie zur Emacs-Programmierung
Insecurity Bulletin
Im Insecurity Bulletin widmet sich Mark Vogelsberger aktuellen Sicherheitslücken sowie Hintergründen und Security-Grundlagen. mehr...





