Q.2. グレースケール化
画像をグレースケールにせよ。 グレースケールとは、画像の輝度表現方法の一種であり下式で計算される。
Y = 0.2126 R + 0.7152 G + 0.0722 B
入力 | 出力 |
---|---|
![]() |
![]() |
回答
グレースケール化する部分のコードです。
今回は出力部分にまとめてしまいました。
ex2.c
double image_gry[height][width];
int k = 0;
for(int i = 0; i < height; i ++){
for(int j = 0; j < width*3-2; j = j+3){
image[i][j] = image[i][j] * 0.2126;
image[i][j+1] = image[i][j+1] * 0.7152;
image[i][j+2] = image[i][j+2] * 0.0722;
image_gry[i][k] = image[i][j] + image[i][j+1] + image[i][j+2];
fprintf(outfp, "%d ", (int)image_gry[i][k]);
k ++;
}
fprintf(outfp, "\n");
}
解説
問題文に記載されていた式をあてはめました。
少し、これはズルかなと思いましたが、ppm形式の画像からpgm形式の画像へと変換するプログラムにしました(RGBのままグレースケール化する方法を思いつかなかった)。
第一問と同様、ピクセルの値は3つで1組で処理を行います。
まず、新たにheight × widthサイズの二次元配列を用意し、R、G、Bそれぞれの値に計算式中の係数を掛け合わせてその和を格納しました。
計算式自体はdouble型の数値計算だったので、出力時にint型にキャストするという流れです。
完成したプログラム(全文)
ex2.c
# include <stdio.h>
# define N 256
int main(void) {
FILE *infp;
FILE *outfp;
char magic[64];
char str[256];
int width;
int height;
int max;
char readline[N] = {'\0'};
infp = fopen("../imori.ppm", "r");
//magic
fgets(magic, N, infp);
//width, height
int num[4];
for(int i = 0; i < 2; i ++){
fscanf(infp, "%d", &num[i]);
}
width = num[0];
height = num[1];
//max
fscanf(infp, "%d", &max);
//image
double image[height][width*3];
for(int i = 0; i < height; i ++){
for(int j = 0; j < width*3; j ++){
fscanf(infp, "%lf", &image[i][j]);
}
}
outfp = fopen("imori.pgm", "w");
fprintf(outfp, "P2\n");
fprintf(outfp, "%d ", width);
fprintf(outfp, "%d\n", height);
fprintf(outfp, "%d\n", max);
double image_gry[height][width];
int k = 0;
for(int i = 0; i < height; i ++){
for(int j = 0; j < width*3-2; j = j+3){
image[i][j] = image[i][j] * 0.2126;
image[i][j+1] = image[i][j+1] * 0.7152;
image[i][j+2] = image[i][j+2] * 0.0722;
image_gry[i][k] = image[i][j] + image[i][j+1] + image[i][j+2];
fprintf(outfp, "%d ", (int)image_gry[i][k]);
k ++;
}
fprintf(outfp, "\n");
}
return 0;
}