画像処理プログラム
プログラムどう改良していいか全然わかりません
教えてください
Sobel フィルタは垂直成分しか見ていないため、エッジ検出としては不十分である。任
意方向のエッジを検出するためには、図4 のような垂直方向と水平方向のオペレータを用いて各成分を抽出し、それらを合成する必要がある(図5 参照)。そこで、プログラムを次のように改良し、全方向のエッジに対応したプログラムにする。
<変更前> <変更後>
c =1 2 1 cy=-1 -2 -1 cx=-1 0 1
0 0 0 → 0 0 0 -2 0 2
1 2 1 1 2 1 -1 0 1
畳み込み演算 畳み込み演算
L = c・img → Ly = cy・img, Lx = cx・img
エッジの強さ エッジの強さ
|L| → |L|=√Lx^2+Ly^2
/** Sobel.c **/
#include <stdio.h>
#include <stdlib.h>
#define V_width 320
#define V_height 240
#define amp 1.0
int d[9];
int i, j, dat;
float L;
unsigned char img [V_height][V_width]; /* input image */
unsigned char work[V_height][V_width]={0}; /* work space */
/******* filter coefficients *******/
static int c[9] = {-1, -2, -1,
0, 0, 0,
1, 2, 1};
/*************************************/
int main(int argc, char *argv[])
{
FILE *fpi, *fpo;
unsigned char data;
char str[256];
int width, height;
/* check arg number */
if (argc != 3) {
fprintf(stderr, "Usage: %s [input] [output]\n", argv[0]);
exit(1);
}
/* open input file */
if ((fpi = fopen(argv[1], "rb")) == NULL) {
fprintf(stderr, "input file open error!\n");
exit(1);
}
/* open output file */
if ((fpo = fopen(argv[2], "wb")) == NULL) {
fprintf(stderr, "output file open error!\n");
exit(1);
}
/* read PGM header */
while(1){
fgets(str, 256, fpi);
if(str[0] == '#'){
fprintf( stderr, "%s", str);
}
else if( !strncmp( str, "P5", 2)){
fprintf( stderr, "This file is a PGM file.\n");
}
else if( !strncmp( str, "255", 3)){
fprintf( stderr, "The file is opened.\n");
break;
}
else{
sscanf( str, "%d %d", &width, &height);
fprintf( stderr, "SIZE: %3d x %3d\n", width, height);
}
}
/* read data */
for (i=0; i<height; i++) {
for (j=0; j<width; j++) {
fread( &data, 1, 1, fpi);
img[i][j] = data;
}
}
/* image processing */
for (i=1; i < height-1; i++) {
for (j=1; j < width-1; j++) {
d[0]=img[i-1][j-1]; d[1]=img[i-1][j]; d[2]=img[i-1][j+1];
d[3]=img[i][j-1]; d[4]=img[i][j]; d[5]=img[i][j+1];
d[6]=img[i+1][j-1]; d[7]=img[i+1][j]; d[8]=img[i+1][j+1];
L = (float)(c[0]*d[0] + c[1]*d[1] + c[2]*d[2]
+ c[3]*d[3] + c[4]*d[4] + c[5]*d[5]
+ c[6]*d[6] + c[7]*d[7] + c[8]*d[8]);
L = amp*L;
dat = (int)(L);
if (dat < 0) dat = -dat;
if (dat > 255) dat = 255;
work[i][j] = (unsigned char)dat;
}
}
/* write data */
fprintf(fpo,"P5\n %d %d\n 255\n", width, height);
for (i= 0; i<height; i++) {
for (j= 0; j<width; j++) {
fwrite( &work[i][j], 1, 1, fpo);
}
}
fclose(fpi);
fclose(fpo);
return 0;
}
お礼
アドバイスありがとうございます >一般にはエッジにも強度の概念があり、これを濃淡で表したものと考えれば納得いきませんか? 非常に納得がいきました. 一次微分を用いたもので閾値を使っていたのでどうも2値で出力されるという固定観念があったのですが,たしかに閾値を用いらなければ濃淡で表わされますね. 上記のことからクリップをした際の挙動がわかりました. そこで新たに出た疑問なのですが 一般的にエッジの強度を表す際に用いる色はどのようなものがあるのでしょうか? たとえば,グレースケール画像のラプラシアンフィルタについて言えば,取り得る値は-255*4~+255*4まであると思います これをどのように表現するのかということです. それは個人の好み,といわれてしまえば確かにそうなのですが,一般的にはどのような方法が用いられるのかが気になりました. また,利用目的は,画像処理の学習のためになればと思い行ってみました.