実現したいこと
画像に疑似カラーをつけるプログラムを作成したいです。
入力はグレースケール画像(.pgmファイル)で、それをRGBそれぞれの疑似カラー変換関数式で変換を行い、結果をRGBそれぞれのチャンネルへ出力する(.ppmファイル)方法で作成したいです。
変換式は疑似カラー変換関数を参考にします。
R=0 (I < 128), (I - 128)255/192-128 (128 < I <= 192), 255 (I > 192)
G=I*255/64 (I <= 64), 255(64 < I <= 192), (I-255)255/192-255(I > 192)
B=255(I<=64), (I - 128)255/64-128(64 < I <= 128), 0(I > 128)
また、ファイルを読み書き吸うためのヘッダファイルをppmpgm.hとします。
発生している問題・分からないこと
以下のようなプログラムを作って実行しましたが、GIMPで以下のようなエラーメッセージが出力され、画像が生成されませんでした。なお、画像自体は著作権の関係もあり、ここでは表示しません。
「GIMP エラーメッセージ
'(File)'のオープンに失敗しました。
PNM画像 plug-in could not open image
PNM画像 エラーメッセージ
不正な X解像度です」
おそらく、void equality 内の2重ループの中に記載した疑似カラー変換関数の書き方(if文の使い方)などが誤っていると考えています。
ヘッダファイルの内容は変更せずに、void equalityの中身をどのように書き換えれば、画像が正しく生成されるかを教えていただきたいです。
なお、実行すると下記のような画面になりました。
モノクロ階調画像入力ル-チン
file形式はpgm、バイナリ形式とします。
入力file名(*.pgm):farinfrared.pgm
横の画素数 = 811, 縦の画素数 = 607
最大階調値 = 255
デ-タは正しく読み込まれました。
カラ-画像(ppm形式)出力ル-チン
出力file名(*.ppm):farinfrared_1.ppm
デ-タは正しく出力されました。
続行するには何かキーを押してください . . .
該当のソースコード
C
1#include <stdio.h> 2#include <stdlib.h> 3#include "ppmpgm.h" 4 5void equality(void) 6{ 7 int x,y,k,p; 8 //画像の幅と高さを設定 9 pXdim2 = pXdim1; pYdim2 = pYdim1; 10 for(y=0;y<pYdim2;y++) 11 for(x=0;x<pXdim2;x++) 12 p = pimage1[0][y][x]; 13 if(p<128) 14 pimage2[0][y][x] = 0; 15 else if(p>192) 16 pimage2[0][y][x] = 255; 17 else 18 pimage2[0][y][x] = 255*(p-128)/(192-128); 19 20 p = pimage1[1][y][x]; 21 if(p<=64) 22 pimage2[1][y][x] = p*(255/64); 23 else if(p>192) 24 pimage2[1][y][x] = 255*(p-255)/(192-255); 25 else 26 pimage2[1][y][x] = 255; 27 28 p = pimage1[2][y][x]; 29 if(p<=64) 30 pimage2[2][y][x] = 255; 31 else if(p>128) 32 pimage2[2][y][x] = 0; 33 else 34 pimage2[2][y][x] = 255*(p-128)/(64-128); 35} 36 37 38void main(void) 39{ 40 load_image_pgm(); 41 equality(); 42 save_image_ppm(); 43 return; 44} 45
C
1/* ppmpgm.h */ 2 3#define MAX_IMAGESIZE 1024 4#define MAX_BRIGHTNESS 255 5#define GRAYLEVEL 256 6#define MAX_FILENAME 256 7#define MAX_BUFFERSIZE 256 8 9unsigned char pimage1[3][MAX_IMAGESIZE][MAX_IMAGESIZE], 10 pimage2[3][MAX_IMAGESIZE][MAX_IMAGESIZE]; 11float ptmp[3][MAX_IMAGESIZE][MAX_IMAGESIZE]; 12int pXdim1, pYdim1, 13 pXdim2, pYdim2; 14 15unsigned char gimage1[MAX_IMAGESIZE][MAX_IMAGESIZE], 16 gimage2[MAX_IMAGESIZE][MAX_IMAGESIZE]; 17float gtmp[MAX_IMAGESIZE][MAX_IMAGESIZE]; 18int gXdim1, gYdim1, 19 gXdim2, gYdim2; 20 21void load_image_ppm(void); 22void save_image_ppm(void); 23void load_image_pgm(void); 24void save_image_pgm(void); 25 26void load_image_ppm(void) 27{ 28 char file_name[MAX_FILENAME]; 29 char buffer[MAX_BUFFERSIZE]; 30 FILE *fp; 31 int max_gray; 32 int x,y,k; 33 34 35 printf("-------------------------------------\n"); 36 printf(" カラ-画像入力ル-チン\n"); 37 printf("-------------------------------------\n"); 38 printf("file形式はppm、バイナリ形式とします。\n"); 39 printf("入力file名(*.ppm):"); 40 scanf("%s",file_name); 41 fp=fopen(file_name,"rb"); 42 if(NULL==fp){ 43 printf("その名前のfileは存在しません。\n"); 44 exit(1); 45 } 46 47 48 fgets(buffer,MAX_BUFFERSIZE,fp); 49 if(buffer[0]!='P' || buffer[1]!='6'){ 50 printf("fileのフォ-マットがP6とは異ります。\n"); 51 exit(1); 52 } 53 54 /* pXdim1, pYdim1の代入(#から始まるコメントは読み飛ばす) */ 55 pXdim1 = 0; 56 pYdim1 = 0; 57 while(pXdim1 == 0 || pYdim1 == 0){ 58 fgets(buffer,MAX_BUFFERSIZE,fp); 59 if(buffer[0]!='#'){ 60 sscanf(buffer,"%d %d",&pXdim1,&pYdim1); 61 } 62 } 63 64 max_gray = 0; 65 while(max_gray == 0){ 66 fgets(buffer, MAX_BUFFERSIZE,fp); 67 if(buffer[0]!='#'){ 68 sscanf(buffer,"%d",&max_gray); 69 } 70 } 71 72 printf("横の画素数 = %d, 縦の画素数 = %d\n", pXdim1, pYdim1); 73 printf("最大階調値 = %d\n",max_gray); 74 if(pXdim1 > MAX_IMAGESIZE || pYdim1 > MAX_IMAGESIZE){ 75 printf("想定値 %d x %d を超えています。\n", 76 MAX_IMAGESIZE,MAX_IMAGESIZE); 77 printf("もう少し小さい画像を使って下さい。\n"); 78 exit(1); 79 } 80 if(max_gray != MAX_BRIGHTNESS){ 81 printf("最大階調値が不適切です。\n"); 82 exit(1); 83 } 84 85 for(y=0; y<pYdim1; y++){ 86 for(x=0;x<pXdim1; x++){ 87 for(k=0;k<3;k++) 88 pimage1[k][y][x] = (unsigned char)fgetc(fp); 89 } 90 } 91 92 printf("デ-タは正しく読み込まれました。\n"); 93 printf("--------------------------------------\n"); 94 fclose(fp); 95} 96 97void save_image_ppm(void) 98{ 99 char file_name[MAX_FILENAME]; 100 FILE *fp; 101 int x,y,k; 102 103 printf("------------------------------------\n"); 104 printf(" カラ-画像(ppm形式)出力ル-チン\n"); 105 printf("------------------------------------\n"); 106 printf("出力file名(*.ppm):"); 107 scanf("%s",file_name); 108 fp = fopen(file_name,"wb"); 109 110 fputs("P6\n",fp); 111 fputs("# Created by H.I.T\n",fp); 112 fprintf(fp,"%d %d\n",pXdim2,pYdim2); 113 fprintf(fp,"%d\n",MAX_BRIGHTNESS); 114 115 for(y=0; y<pYdim2; y++){ 116 for(x=0; x<pXdim2; x++){ 117 for(k=0;k<3;k++) 118 fputc(pimage2[k][y][x],fp); 119 } 120 } 121 122 printf("デ-タは正しく出力されました。\n"); 123 printf("------------------------------------\n"); 124 fclose(fp); 125} 126 127void load_image_pgm(void) 128{ 129 char file_name[MAX_FILENAME]; 130 char buffer[MAX_BUFFERSIZE]; 131 FILE *fp; 132 int max_gray; 133 int x,y; 134 135 printf("-------------------------------------\n"); 136 printf(" モノクロ階調画像入力ル-チン\n"); 137 printf("-------------------------------------\n"); 138 printf("file形式はpgm、バイナリ形式とします。\n"); 139 printf("入力file名(*.pgm):"); 140 scanf("%s",file_name); 141 fp=fopen(file_name,"rb"); 142 if(NULL==fp){ 143 printf("その名前のfileは存在しません。\n"); 144 exit(1); 145 } 146 147 fgets(buffer,MAX_BUFFERSIZE,fp); 148 if(buffer[0]!='P' || buffer[1]!='5'){ 149 printf("fileのフォ-マットがP5とは異ります。\n"); 150 exit(1); 151 } 152 153 gXdim1 = 0; 154 gYdim1 = 0; 155 while(gXdim1 == 0 || gYdim1 == 0){ 156 fgets(buffer,MAX_BUFFERSIZE,fp); 157 if(buffer[0]!='#'){ 158 sscanf(buffer,"%d %d",&gXdim1,&gYdim1); 159 } 160 } 161 162 max_gray = 0; 163 while(max_gray == 0){ 164 fgets(buffer, MAX_BUFFERSIZE,fp); 165 if(buffer[0]!='#'){ 166 sscanf(buffer,"%d",&max_gray); 167 } 168 } 169 170 printf("横の画素数 = %d, 縦の画素数 = %d\n", gXdim1, gYdim1); 171 printf("最大階調値 = %d\n",max_gray); 172 if(gXdim1 > MAX_IMAGESIZE || gYdim1 > MAX_IMAGESIZE){ 173 printf("想定値 %d x %d を超えています。\n", 174 MAX_IMAGESIZE,MAX_IMAGESIZE); 175 printf("もう少し小さい画像を使って下さい。\n"); 176 exit(1); 177 } 178 if(max_gray != MAX_BRIGHTNESS){ 179 printf("最大階調値が不適切です。\n"); 180 exit(1); 181 } 182 183 for(y=0; y<gYdim1; y++){ 184 for(x=0;x<gXdim1; x++){ 185 gimage1[y][x] = (unsigned char)fgetc(fp); 186 } 187 } 188 189 printf("デ-タは正しく読み込まれました。\n"); 190 printf("--------------------------------------\n"); 191 fclose(fp); 192} 193 194void save_image_pgm(void) 195{ 196 char file_name[MAX_FILENAME]; 197 FILE *fp; 198 int x,y; 199 200 printf("------------------------------------\n"); 201 printf(" モノクロ階調画像(pgm形式)出力ル-チン\n"); 202 printf("------------------------------------\n"); 203 printf("出力file名(*.pgm):"); 204 scanf("%s",file_name); 205 fp = fopen(file_name,"wb"); 206 207 fputs("P5\n",fp); 208 fputs("# Created by H.I.T\n",fp); 209 fprintf(fp,"%d %d\n",gXdim2,gYdim2); 210 fprintf(fp,"%d\n",MAX_BRIGHTNESS); 211 212 for(y=0; y<gYdim2; y++){ 213 for(x=0; x<gXdim2; x++){ 214 fputc(gimage2[y][x],fp); 215 } 216 } 217 218 printf("デ-タは正しく出力されました。\n"); 219 printf("------------------------------------\n"); 220 fclose(fp); 221} 222
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
疑似カラー変換関数を調べてプログラムに実装したが、うまく画像が生成されなかった。
また、ChatGPTを使って、プログラムをAIに作成してもらったが、疑似カラー変換関数を用いた実行方法は出てこなかった。
補足
特になし

回答2件
あなたの回答
tips
プレビュー