加重平滑化フィルタ
加重平滑化は単純な平均値でなく、ターゲットとなる中心からの距離に応じて重みを付けています。
加重平滑化を行った画像を以下に載せておきます。単純な平滑化より、ぼかしが弱くかかっていると思います。
原画
|
加重平滑化
|
サブルーチン
以下は加重平滑化フィルタのサブルーチンです。
ターゲットである $org[$i][$j] とその周辺の画素を RGB に分解してそれぞれに加重を掛けながら和算して、整数化した後に RGB をまとめた画素値としてを返しています。
lib/gaussian.pm :
1 sub gaussian {
2
3 my $color;
4
5 ($r[0], $g[0], $b[0]) = split /\,/, $org[$i-1][$j-1]; # up left
6 ($r[1], $g[1], $b[1]) = split /\,/, $org[$i][$j-1]; # up center
7 ($r[2], $g[2], $b[2]) = split /\,/, $org[$i+1][$j-1]; # up right
8 ($r[3], $g[3], $b[3]) = split /\,/, $org[$i-1][$j]; # center left
9 ($r[4], $g[4], $b[4]) = split /\,/, $org[$i][$j]; # center center
10 ($r[5], $g[5], $b[5]) = split /\,/, $org[$i+1][$j]; # center right
11 ($r[6], $g[6], $b[6]) = split /\,/, $org[$i-1][$j+1]; # down left
12 ($r[7], $g[7], $b[7]) = split /\,/, $org[$i][$j+1]; # down center
13 ($r[8], $g[8], $b[8]) = split /\,/, $org[$i+1][$j+1]; # down right
14 $r_sum = ($r[0]/16)+($r[1]/8)+($r[2]/16)+($r[3]/8)+($r[4]/4)+($r[5]/8)+($r[6]/16)+($r[7]/8)+($r[8]/16);
15 $g_sum = ($g[0]/16)+($g[1]/8)+($g[2]/16)+($g[3]/8)+($g[4]/4)+($g[5]/8)+($g[6]/16)+($g[7]/8)+($g[8]/16);
16 $b_sum = ($b[0]/16)+($b[1]/8)+($b[2]/16)+($b[3]/8)+($b[4]/4)+($b[5]/8)+($b[6]/16)+($b[7]/8)+($b[8]/16);
17 $r_sum_i = int($r_sum);
18 $g_sum_i = int($g_sum);
19 $b_sum_i = int($b_sum);
20 $color = "$r_sum_i" . ',' . "$g_sum_i" . ',' . "$b_sum_i";
21 return $color;
22 }
23
24 1;
親プログラム
上の加重平滑化フィルタのサブルーチンを使って、実際の画像処理をするのが以下のプログラムです。前ページの平滑化フィルタと同じ構造で、サブルーチンとして averaging となっていた箇所を gaussian に書き換えただけです。
gaussian.pl :
1 #!/usr/bin/perl
2
3 use Getopt::Long;
4
5 use lib '/home/user/Lab/ImageProcessing/Perl/lib';
6 require read_jpg;
7 require gaussian;
8
9 sub print_synopsis {
10 print "Options : \n";
11 print " --input_file : \n";
12 print " input original file name. \n";
13 print " --nodisplay : \n";
14 print " do not display convertion result.\n";
15 }
16
17 &GetOptions(
18 'input_file=s' => \$in_file,
19 'nodisplay' => \$in_nodisp,
20 );
21
22 if (!defined($in_file)) {
23 print "##ERROR## input file is not defined\n";
24 &print_synopsis;
25 exit;
26 }
27
28 &read_jpg($in_file);
29
30 print "gaussian\n";
31 for ($j = 0; $j < $size_y; $j++) {
32 for ($i = 0; $i < $size_x; $i++) {
33 if (($i < 1) || ($i >= ($size_x - 1)) || ($j < 1) || ($j >= ($size_y - 1))) {
34 $gaussian[$i][$j] = $org[$i][$j];
35 } else {
36 $gaussian[$i][$j] = &gaussian();
37 }
38 }
39 }
40
41 print "output text file\n";
42 open(OUT_TEXT, ">", "../Temp/gaussian.txt") or die "##ERROR## Could not open output file : ../Temp/gaussian.txt";
43 print OUT_TEXT "$header\n";
44 for ($y = 0; $y < $size_y; $y++) {
45 for ($x = 0; $x < $size_x; $x++) {
46 $state = "$x" . ',' . "$y" . ': ' . '(' . "$gaussian[$x][$y]" . ')';
47 print OUT_TEXT "$state\n";
48 }
49 }
50 close OUT_TEXT;
51
52 print "convert text to jpeg\n";
53 `convert ../Temp/gaussian.txt ../Temp/gaussian.jpg`;
54
55 if (!defined($in_nodisp)) {
56 if ( ($size_x <= 1920) && ($size_y <= 1080) ) {
57 print "display\n";
58 `display ../Temp/gaussian.jpg`;
59 } else {
60 print "jpeg size is too large, open with gimp\n";
61 }
62 }
親プログラムについての解説は、前ページの平滑化フィルタと同じですので省略します。
画像処理 実行環境
ここで画像処理を実行しているディレクトリ構造について説明しておこうと思います。
下記は tree コマンドで得たディレクトリツリーです。
.
├── Convert
│ ├── JPEG
│ └── TEXT
├── Perl
│ ├── averaging.pl
│ ├── gaussian.pl
│ ├── near_averaging.pl
│ ├── sharping.pl
│ └── lib
│ ├── averaging.pm
│ ├── gaussian.pm
│ ├── near_averaging.pm
│ ├── read_jpg.pm
│ └── sharping.pm
├── Run
├── Sample
│ ├── JPEG
│ │ ├── baobab.jpg
│ │ ├── beach_stone.jpg
│ │ ├── forest.jpg
│ │ ├── mountain.jpeg
│ │ ├── red_desert.jpg
│ │ ├── sanma.jpg
│ │ ├── venezia.jpg
│ │ └── yellowtail.jpg
│ └── TXT
└── Temp
├── averaging.jpg
├── averaging.txt
├── convert_from_jpg.txt
├── gaussian.jpg
├── gaussian.txt
├── near_averaging.jpg
├── near_averaging.txt
├── sharping.jpg
└── sharping.txt
Run というディレクトリは 画像処理Perl の実行ディレクトリとして設けています。時折 Run ディレクトリに複数個の 画像処理Perl を実行するための シェルスクリプト をおくこともあります。
Temp というディレクトリは 画像処理した結果を一時的におくディレクトリにしています。Perl で処理した結果は TEXT形式 ですので、 Temp ディレクトリで ImagiMagick で変換した JPEG形式 を一時的に保存して見ることにしています。
|
自己紹介
50才になる半導体エンジニアです。
大学で電子電気工学を学び、1990年にその分野のまま就職。ASICやマイコンの設計を長く続けてきましたが20年も同じ分野にいると業態も衰退したり変化するもので退職し、今は外資のIT系会社に再就職して設計請負業をやっております。
お問い合わせは
nakata.xianzhi@outlook.com
Linux と 小ネタ
デジタル回路設計
海外駐在後記
|