🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

2回答

1027閲覧

画像処理(バイリニア法)について

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2019/10/28 03:44

画像処理について学んでいて、バイリニア法をやっていたのですがうまくいきません。
アドバイスお願いします。

C

1/* 拡大・縮小画像を作成するプログラム scaling.c */ 2#include<stdio.h> 3#include<stdlib.h> 4#include<math.h> 5#include"mypgm.h" 6 7void make_bilinear_image() 8{ 9 int x, y; 10 int x1, y1; 11 12 double ratio; 13 14 printf("拡大・縮小画像を作成します.\n"); 15 printf("拡大・縮小する倍率を入力して下さい。"); 16 scanf("%lf", &ratio); 17 18 x_size2 = (int)(ratio * x_size1); /* 横画素数 */ 19 y_size2 = (int)(ratio * y_size1); /* 縦画素数 */ 20 if (x_size2 > MAX_IMAGESIZE || y_size2 > MAX_IMAGESIZE) { 21 printf("想定値 %d x %d を超えています.\n", 22 MAX_IMAGESIZE, MAX_IMAGESIZE); 23 printf("もう少し小さな画像を使って下さい.\n"); 24 exit(1); 25 } 26 27 for (y = 0; y < y_size2; y++) { 28 for (x = 0; x < x_size2; x++) { 29 double x0 = x / ratio; 30 double y0 = y / ratio; 31 int color[4]; 32 33 color[0] = image1[y][x]; 34 color[1] = image1[y][x+1]; 35 color[2] = image1[y+1][x]; 36 color[3] = image1[y+1][x+1]; 37 38 image2[y][x] = (1 - x0) * (1 - y0) * color[0] 39 + x0 * (1 - y0) * color[1] 40 + (1 - x0) * y0 * color[2] 41 + x0 * y0 * color[3]; 42 } 43 } 44} 45 46 47main( ) 48{ 49 load_image_data( ); /* 画像データを image1 に読み込む */ 50 //make_ratio_image(); /* 原画像 image1 を拡大・縮小して image2 へ */ 51 //make_nearest_image(); 52 make_bilinear_image(); 53 save_image_data( ); /* image2 を保存する */ 54 return 0; 55} 56
/* pgm ファイルを読み書きするためのヘッダファイル mypgm.h */ /* 定数宣言 */ #define MAX_IMAGESIZE 1024 /* 想定する縦・横の最大画素数 */ #define MAX_BRIGHTNESS 255 /* 想定する最大階調値 */ #define GRAYLEVEL 256 /* 想定する階調数(=最大階調値+1) */ #define MAX_FILENAME 256 /* 想定するファイル名の最大長 */ #define MAX_BUFFERSIZE 256 /* 利用するバッファ最大長 */ /* 大域変数の宣言 */ /* 画像用配列1,画像用配列2 */ unsigned char image1[MAX_IMAGESIZE][MAX_IMAGESIZE], image2[MAX_IMAGESIZE][MAX_IMAGESIZE]; int x_size1, y_size1, /* image1 の横画素数,縦画素数 */ x_size2, y_size2; /* image2 の横画素数,縦画素数 */ /* 関数のプロトタイプ宣言 */ void load_image_data( ); /* 画像読み込み用関数 */ void save_image_data( ); /* 画像書き込み用関数 */ /* 以下は関数の本体 */ void load_image_data( ) /* pgm 画像,横画素数,縦画素数のデータをファイルから読み込み,*/ /* image1[ ][ ],x_size1,y_size1 にそれぞれ代入する. */ { char file_name[MAX_FILENAME]; /* ファイル名用の文字配列 */ char buffer[MAX_BUFFERSIZE]; /* データ読み込み用作業変数 */ FILE *fp; /* ファイルポインタ */ int max_gray; /* 最大階調値 */ int x, y; /* ループ変数 */ /* 入力ファイルのオープン */ printf("-----------------------------------------------------\n"); printf(" モノクロ階調画像入力ルーチン\n"); printf("-----------------------------------------------------\n"); printf("ファイル形式は pgm, バイナリ形式とします.\n"); printf("入力ファイル名 (*.pgm) : "); scanf("%s",file_name); fp = fopen( file_name, "rb" ); if ( NULL == fp ){ printf("その名前のファイルは存在しません.\n"); exit(1); } /* ファイルタイプ(=P5)の確認 */ fgets( buffer, MAX_BUFFERSIZE, fp ); if ( buffer[0] != 'P' || buffer[1] != '5' ){ printf("ファイルのフォーマットが P5 とは異なります.\n"); exit(1); } /* x_size1, y_size1 の代入(#から始まるコメントは読み飛ばす) */ x_size1 = 0; y_size1 = 0; while ( x_size1 == 0 || y_size1 == 0 ){ fgets( buffer, MAX_BUFFERSIZE, fp ); if ( buffer[0] != '#' ){ sscanf( buffer, "%d %d", &x_size1, &y_size1 ); } } /* max_gray の代入(#から始まるコメントは読み飛ばす) */ max_gray = 0; while ( max_gray == 0 ){ fgets( buffer, MAX_BUFFERSIZE, fp ); if ( buffer[0] != '#' ){ sscanf( buffer, "%d", &max_gray ); } } /* パラメータの画面への表示 */ printf("横の画素数 = %d, 縦の画素数 = %d\n", x_size1, y_size1 ); printf("最大階調値 = %d\n",max_gray); if ( x_size1 > MAX_IMAGESIZE || y_size1 > MAX_IMAGESIZE ){ printf("想定値 %d x %d を超えています.\n", MAX_IMAGESIZE, MAX_IMAGESIZE); printf("もう少し小さな画像を使って下さい.\n"); exit(1); } if ( max_gray != MAX_BRIGHTNESS ){ printf("最大階調値が不適切です.\n"); exit(1); } /* 画像データを読み込んで画像用配列に代入する */ for ( y = 0; y < y_size1; y ++ ){ for ( x = 0; x < x_size1; x ++ ){ image1[y][x] = (unsigned char)fgetc( fp ); } } printf("データは正しく読み込まれました.\n"); printf("-----------------------------------------------------\n"); fclose(fp); } void save_image_data() /* image2[ ][ ], x_size2, y_size2 のデータを,それぞれ pgm 画像,*/ /* 横画素数,縦画素数としてファイルに保存する. */ { char file_name[MAX_FILENAME]; /* ファイル名用の文字配列 */ FILE *fp; /* ファイルポインタ */ int x, y; /* ループ変数 */ /* 出力ファイルのオープン */ printf("-----------------------------------------------------\n"); printf(" モノクロ階調画像(pgm形式)出力ルーチン\n"); printf("-----------------------------------------------------\n"); printf("出力ファイル名 (*.pgm) : "); scanf("%s",file_name); fp = fopen(file_name, "wb"); /* ファイル識別子 "P5" を先頭に出力する */ fputs( "P5\n", fp ); /* # で始まるコメント行(省略可能) */ fputs( "# Created by Image Processing\n", fp ); /* 画像の横幅,縦幅の出力 */ fprintf( fp, "%d %d\n", x_size2, y_size2 ); /* 最大階調値の出力 */ fprintf( fp, "%d\n", MAX_BRIGHTNESS ); /* 画像データの出力 */ for ( y = 0; y < y_size2; y ++ ){ for ( x = 0; x < x_size2; x ++ ){ fputc( image2[y][x], fp ); } } printf("データは正しく出力されました.\n"); printf("-----------------------------------------------------\n"); fclose(fp); }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ratioの値の意味を取り違えているようです。

https://algorithm.joho.info/image-processing/bi-linear-interpolation/

make_bilinear_image() 関数内でのratioは、画像の縮小率ではなく、縮小した結果の座標が隣接する4つの画素のなかでの距離の重みであるはずです。
(うーん、うまく表現できない・・・)

投稿2019/10/28 05:16

kazto

総合スコア7196

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2019/10/28 05:43

> 拡大・縮小する倍率を入力して下さい として入力させているし,コード内の用途を見てもratioとはここでは単に拡大率だと思うのですが. (変数名へのダメ出し?)
kazto

2019/10/28 05:47

私の意図としては、質問者様は画像の倍率と、距離の重みを混同している、という指摘です。 アルゴリズム的に、当該箇所で拡大率が出てくることはありえません。リンク先をご参照ください。
fana

2019/10/28 05:56

単なる表現の違い(?)かもですね. 私は「入力画像上のpixel座標位置(x0,y0)の算出まではratioも役割通り用いられた正当な処理になっていて,それより後の部分が全てカオスな(x0,y0が乗っかる4画素とそれらの重みを求める必要があるがそれが全くない)滅茶苦茶な状態」と見たので,ratio自体は問題ないと言う認識でコメント致しました.
guest

0

出力画像の位置(x,y)の色を決定するのに参照すべき入力画像上の4点の座標が間違っていると見えます.
(image1[y][x]とか書いてありますが,(x,y)というのは参照すべき座標ではないですよね.)


おっと,

image2[y][x] = ...

で使ってる重み値もすごい値になっていそう…

投稿2019/10/28 03:52

編集2019/10/28 05:37
fana

総合スコア11990

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問