LoginSignup
3
0

More than 3 years have passed since last update.

画像処理100本ノックC言語で挑戦してみる #2

Last updated at Posted at 2019-05-08

Q.2. グレースケール化

画像をグレースケールにせよ。 グレースケールとは、画像の輝度表現方法の一種であり下式で計算される。
Y = 0.2126 R + 0.7152 G + 0.0722 B

入力 出力
imori.jpg answer_2.jpg

回答

グレースケール化する部分のコードです。
今回は出力部分にまとめてしまいました。

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;
}

リンク

画像処理100本ノックを作ったった
画像処理100本ノックC言語で挑戦してみる イントロダクション

3
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0