Q.3. 二値化
画像を二値化せよ。 二値化とは、画像を黒と白の二値で表現する方法である。 ここでは、グレースケールにおいて閾値を128に設定し、下式で二値化する。
y = { 0 (if y < 128)
255 (else)
入力 | 出力 |
---|---|
![]() |
![]() |
回答
二値化する部分のコードです。
今回も、出力部分とまとめました。
ex3.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];
if((int)image_gry[i][k] < 128){
fprintf(outfp, "0 ");
}else{
fprintf(outfp, "255 ");
}
k ++;
}
fprintf(outfp, "\n");
}
解説
第二問に少し手を加えただけです。
出力するときに0か255に分類するだけなので、fprintf
を場合分けの中に入れてあげて、image_gray
の値が128未満か否かで分岐させます。
完成したプログラム(全文)
ex3.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];
if((int)image_gry[i][k] < 128){
fprintf(outfp, "0 ");
}else{
fprintf(outfp, "255 ");
}
k ++;
}
fprintf(outfp, "\n");
}
return 0;
}