화상 처리 100개 노크 C언어로 도전해 보자아래 준비

9339 단어 C이미지 처리

이미지를 볶는 아래 준비



조속히 화상 처리 개시,,, 라고 말하고 싶은 곳입니다만, 조금 아래 준비가 필요하다고 생각했습니다.
개인적인 방침으로서는 이미지의 각 픽셀의 값을 한번 배열에 저장하고 나서 놀리게 하고 싶기 때문에, 우선은 이미지를 읽어들여 각 픽셀의 값을 배열에 저장해, 그것을 새롭게 출력하는 프로그램 을 병아리로 준비하려고 합니다.

원래 ppm 형식의 이미지란?



ppm 형식이라는 말을 나는 최근이 되어 알았습니다.
그래서 일단 ppm 형식에 대해 가볍게 적어 두려고 생각합니다.



ppm 형식의 이미지를 텍스트 편집기에서 보면 위와 같은 구조로 되어 있습니다.
ppm 형식은 RBG로 풀 컬러를 표현할 수 있는 'pixmap'입니다.
처음 2바이트가 매직 넘버가 되어 있어 파일 형식과 데이터가 텍스트인지 바이너리인지를 나타냅니다.

전회의 기사에서 jpg 형식에서 ppm 형식으로의 변환을 web상의 서비스를 이용해 실시했습니다만, web 서비스에서는 P6의 형식으로 변환되어 버렸습니다.
나는 바이너리가 아닌 텍스트 형식으로 픽셀을 만지기를 원했기 때문에 P6 형식의 ppm 이미지가 아니라 P3 형식의 ppm 이미지를 얻어야했습니다.
그래서 이번에는 ImageMagick이라는 응용 프로그램을 이용하여 P3 형식의 ppm 이미지로 변환했습니다.

ImageMagick은 명령줄에서 작동하는 응용 프로그램입니다.
brew install imagemagick

위의 명령으로 설치합니다(Mac).
설치가 끝나면 다음 명령으로 실제로 이미지를 변환합니다.
convert -compress none imori.jpg imori.ppm

이것만으로 완료됩니다.

병아리 프로그램 만들기



여기부터는 드디어 C 언어로 프로그램을 써 갑니다.
【주의】필자의 코드는 언제나 빌어 먹을 코드이므로 양해 바랍니다. 코드를 작성하는 방법이나 사용할 함수를 선택하는 등 앞으로의 기사를 포함하여 뭔가 조언을 주시면 기쁩니다!

다음은 이번 프로그램입니다.

ex0.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
    int image[height][width*3];
    for(int i = 0; i < height; i ++){
        for(int j = 0; j < width*3; j ++){
            fscanf(infp, "%d", &image[i][j]);
        }
    }

    outfp = fopen("imori.ppm", "w");

    fprintf(outfp, "%s", magic);
    fprintf(outfp, "%d ", width);
    fprintf(outfp, "%d\n", height);
    fprintf(outfp, "%d\n", max);

    for(int i = 0; i < height; i ++){
        for(int j = 0; j < width*3; j ++){
            fprintf(outfp, "%d ", image[i][j]);
        }
        fprintf(outfp, "\n");
    }
    return 0;
}

비교적 정말 빌어 먹을 코드입니다.
좀 더 예쁘게 쓸 수 있는 부분이 있을 것 같습니다만, 우선 신경쓰지 않습니다.

프로그램 내용



꾸준히 한 줄씩 읽고 변수에 저장하기만 하면 됩니다.
입출력의 함수에 대해서는, 이것들을 선택한 이유는 특별히 없습니다만, 별로 추천되지 않는 것도 있는 것 같아 무언가 어드바이스 있으면 교수 부탁합니다.

메인이 되는 픽셀의 값은 2차원 배열에 격납하고 있습니다.
만지지 않아도 좋을까 생각합니다만, 화상의 사이즈는 height × width입니다만, ppm 형식의 화상은 각 픽셀의 색을 RBG로 나타내므로, 실제로 격납해야 할 값의 수는 세로가 height, 가로 가 width*3입니다.

이 프로그램에서는 픽셀의 값이 엉망이 아니기 때문에 입력한 이미지와 같은 이미지가 현재 디렉토리에 출력됩니다.

그런데, 이것으로 준비는 할 수 있었으므로 다음부터 드디어 100개 노크, 풀어 갑니다!

좋은 웹페이지 즐겨찾기