今回XYZ値をL*a*b変換するプログラムを作っているのですが、L*a*b変換する際にうまく処理できず苦戦しています。
アドバイスよろしくお願いします。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
//画像データを保存する構造体
typedef struct tagImageData{
unsigned char *data; //各画素の濃度値
unsigned char header[54]; //画像のヘッダ
int width; //画像の横幅
int height; //画像の縦幅
}
ImageData;
//readImage:データの読み込み関数
//第一引数:読み出しファイルのファイルポインタ
//第二引数:読み出しデータの保存変数(ImageData型)
void readImage(FILE *fp, ImageData *img){
//ヘッダ情報を読み込む
fread(img->header, sizeof(unsigned char),54,fp);
//ヘッダから画像の横幅を読み込む
memcpy(&img->width,&img->header[18],4);
//ヘッダから画像の縦幅を読み込む
memcpy(&img->height,&img->header[22],4);
//各画素の濃度値を保存する領域を確保
img->data = (unsigned char *)malloc(sizeof(unsigned char) * img->width * img->height * 3);
//画像データお読み込む
fread(img->data,sizeof(unsigned char),img->width * img->height * 3,fp);
}
//writeImage:データの書き出し関数
//第一引数:書き出しファイルのファイルポインタ
//第二引数:書き出しデータの保存変数(ImageData型)
void writeImage(FILE *fp,ImageData *img){
//ヘッダデータの書き出し
fwrite(img->header, sizeof(unsigned char),54,fp);
//画像データの書き出し
fwrite(img->data,sizeof(unsigned char),img->width*img->height*3,fp);
}
void labImage(ImageData *img,ImageData *limg,ImageData *aimg,ImageData *bimg){
int i,j;
double l,a,b;
unsigned char R,G,B;
double X,Y,Z;
long p;
//X,Y,Zそれぞれの各画素の濃度値を保存する領域を確保
limg->data=(unsigned char *)malloc(sizeof(unsigned char)*img->width*img->height*3);
aimg->data=(unsigned char *)malloc(sizeof(unsigned char)*img->width*img->height*3);
bimg->data=(unsigned char *)malloc(sizeof(unsigned char)*img->width*img->height*3);
//X,Y,Z画像へヘッダ情報、横幅、縦幅の情報をコピーする
limg->width=img->width;
aimg->width=img->width;
bimg->width=img->width;
limg->height=img->height;
aimg->height=img->height;
bimg->height=img->height;
for(i=0;i<54;i++){
limg->header=img->header;
aimg->header=img->header;
bimg->header=img->header;
}
//各画素の濃度値を順番にコピーする
for(j=0;j<img->height;j++){
for(i=0;i<img->width;i++){
p=j*img->width*3+i*3; //元の位置
B=img->data[p]; //青
G=img->data[p+1]; //緑
R=img->data[p+2]; //赤
//XYZ表色系への変換
X=2.7689*R+1.7517*G+1.1302*B;
Y=1.0000*R+4.5907*G+0.0601*B;
Z=0.0000*R+0.0565*G+5.5943*B;
//L*a*b表色系への変換
if((X/99.09>0.008856) && (Y/100.00>0.008856) && (Z/85.32>0.008856)){
l=116*(pow(Y/100.00,1/3))-16;
a=500*(pow(X/99.09,1/3)-pow(Y/100.00,1/3));
b=200*(pow(Y/100.00,1/3)-pow(Z/85.32,1/3));
}
else{
l=116*(7.787*Y/100.00+16/116)-16;
a=500*(7.787*(X/99.09)+16/116-(7.787*Y/100.00+16/116));
b=200*(7.787*(Y/100.00)+16/116-(7.787*Z/85.32+16/116));
}
limg->data[p]=limg->data[p+1]=limg->data[p+2]=l;
aimg->data[p]=aimg->data[p+1]=aimg->data[p+2]=a;
bimg->data[p]=bimg->data[p+1]=bimg->data[p+2]=b;
}
}
}
int main(void){
FILE *fp;
ImageData inImg;
ImageData lImg, aImg, bImg;
int i,j;
//画像データを開く
if((fp=fopen("lenna.bmp","rb"))==NULL){
printf("file not found!!\n");
exit(1);
}
readImage(fp,&inImg);
fclose(fp);
labImage(&inImg,&lImg,&aImg,&bImg);
//出力画像ファイル(X)を開く
if((fp=fopen("L*-result.bmp","wb"))==NULL){
printf("file not found!!\n");
exit(1);
}
writeImage(fp,&lImg);
//出力画像ファイル(Y)を開く
if((fp=fopen("a*-result.bmp","wb"))==NULL){
printf("file not found!!\n");
exit(1);
}
writeImage(fp,&aImg);
//出力画像ファイル(Z)を開く
if((fp=fopen("b*-result.bmp","wb"))==NULL){
printf("file not found!!\n");
exit(1);
}
writeImage(fp,&bImg);
fclose(fp);
free(inImg.data);
free(lImg.data);
free(aImg.data);
free(bImg.data);
return 0;
}