Skip to content

Instantly share code, notes, and snippets.

@staybuzz
Last active August 18, 2019 07:24
Show Gist options
  • Save staybuzz/620e383bd2ae0312550de474780d03b6 to your computer and use it in GitHub Desktop.
Save staybuzz/620e383bd2ae0312550de474780d03b6 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
int main(){
int width, height, level;
int x,y; // X軸、Y軸
int i;
char s[10]; // ヘッダのファイル形式を格納
char nl[2]; // 改行記号を格納
unsigned char *data; // 画像データ
unsigned char *gray; // グレースケールデータ (Y,X)
unsigned int histgram[256] = {0}; // グレースケールデータのヒストグラム格納用。課題プリントでいうnf相当
FILE *fp;
/* ファイルを開く */
char filename[255] = "04_origsize.ppm";
//char filename[255] = "02.ppm";
if((fp = fopen(filename,"rb")) == NULL){
fprintf(stderr, "%s\n", "error: can't read file.");
return EXIT_FAILURE;
}
/* 画像の読み込み */
// ヘッダの格納(コメントは考慮していない)
fscanf(fp, "%s %d %d %d ", s, &width, &height, &level);
// 画像バイナリの格納
// 画像サイズ×RGB分だけ動的確保
if ((data = malloc(3*width*height)) == NULL){
fprintf(stderr, "%s\n", "error: can't malloc (data).");
return EXIT_FAILURE;
}
fread(data, 1, 3*width*height, fp);
fclose(fp);
// 確認用
printf("%s, %d, %d, %d\n",s, width, height, level);
printf("%d %d %d\n",data[0],data[1],data[2]);
/* RGBからグレースケールへの変換 */
if ((gray = malloc(width*height)) == NULL){// グレースケール用の領域を確保
fprintf(stderr, "%s\n", "error: can't malloc (gray).");
return EXIT_FAILURE;
}
for(y=0; y<height; y++){
for(x=0; x<width; x++){
i = y*width + x;
gray[i] = (char)( ((double)data[(i*3)+0])*0.299 + ((double)data[(i*3)+1])*0.587 + ((double)data[(i*3)+2])*0.114 );
//printf("%d ",gray[i]);
}
}
/* ヒストグラムの作成 */
int sum = 0; // 全体の(輝度x画素数)
int m = 0; // 全体の平均輝度値
for(y=0; y<height; y++){
for(x=0; x<width; x++){
i = y*width + x;
histgram[(int)gray[i]]++;
sum += i*(int)gray[i];
}
}
m = sum/(width*height);
// ヒストグラム確認用
//for(i=0;i<256;i++)
// printf("%d ",histgram[i]);
/* 判別分析法 */
int n1 = 0, n2 = 0; // クラス1,2の画素数
int sum1 = 0, sum2 = 0; // クラス1,2の(輝度x画素数)
int m1 = 0, m2 = 0; // クラス1,2の平均
int d1 = 0, d2 = 0; // クラス1,2の分散
int t, result_t; // しきい値
double separate = 0.0; // 分離度
double max = 0.0; // 分離度の最大値
// しきい値総当たり
for(t=0; t<256; t++){
// クラス1の処理
for(i=0; i<t; i++){
n1 += histgram[i];
sum1 += i*histgram[i];
}
// クラス2の処理
for(i=t; i<256; i++){
n2 += histgram[i];
sum2 += i*histgram[i];
}
// 0除算防止
if(n1==0 || n2==0)
continue;
m1 = sum1/n1; // クラス1の平均輝度値
m2 = sum2/n2; // クラス2の平均輝度値
for(i=0; i<t; i++){
d1 += ( histgram[i]*(i-m1)*(i-m1) ) / n1;
}
for(i=t; i<256; i++){
d2 += ( histgram[i]*(i-m2)*(i-m2) ) / n2;
}
separate = ( (n1*(m1-m)*(m1-m)) + (n2*(m2-m)*(m2-m)) ) / ( (n1*d1)+(n2*d2) ); // 分離度の計算
if (max < separate*separate){
max = separate*separate;
result_t = t; // 分離度の最大値&しきい値の更新
}
printf("separate%d: %f\n", t,separate);
}
printf("result_t: %d\n", result_t);
for(i=0; i<width*height; i++){
if(gray[i] < result_t)
gray[i] = 0;
else
gray[i] = 255;
}
/* 画像の保存 */
char filename2[255] = "mod_04.pgm";
//char filename2[255] = "mod_02.pgm";
if((fp = fopen(filename2,"w")) == NULL){
fprintf(stderr, "%s\n", "error: can't read file.");
return EXIT_FAILURE;
}
fputs("P5\n", fp);
fprintf(fp, "%d %d\n", width, height);
fputs("255\n", fp); // 色深度 8bit
for(y=0; y<height; y++){ // 画像データの書き込み
for(x=0; x<width; x++){
putc(gray[(y*width + x)], fp);
}
}
fclose(fp);
free(data);
free(gray);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment