ヒストグラム均等化処理プログラム
どなたか以下のヒストグラム均等化処理プログラムを解説して頂けないでしょうか。特にgetMinMax関数とgetHistEqu関数で、何がしたいのか訳がわかりません。
以下のプログラムは、ヒストグラム均等化処理部分のみですが、分かる範囲でいいので、解説お願いします。
-------------------------------------------------------
// ヒストグラム均等化による画素値の割り当てを決定する
// hist :入力画像のヒストグラム
// min :割り当てられる画素値の最小
// max :割り当てられる画素値の最大
// たとえば,min[5]=4 max[5]=6の場合,画素値5には4-6の範囲に割り当てられる
// pixs_min :最小値が割り当てられる画素数
// pixs_max :最大値が割り当てられる画素数
// ave :各画素値に割り当てられる画素数
//★★特にmin,max,pixs_min,pixs_maxの説明の意味が分からないのです。
int getMinMax(int *hist,int *min,int *max,int *pixs_min,int *pixs_max,int ave)
{
int i;
int rest;
int now;
int pixels;
int a,b;
rest=0;
now=0;
for(i=0;i<256;i++) {
pixels=rest+hist[i];
min[i]=now;
if(rest>0) pixs_min[i]=ave-rest;
else pixs_min[i]=ave+100;
a=pixels/ave;
rest=pixels%ave;
max[i]=now+a;
if(rest>0) pixs_max[i]=rest;
else pixs_max[i]=ave+100;
now+=a;
}
for(i=0;i<255;i++) {
if(min[i]>255) min[i]=255;
if(max[i]>255) max[i]=255;
}
max[255]=255;
pixs_max[255]=ave*10;
}
// ヒストグラム均等化による画素値の決定
// 割り当てられる画素値の最小,最大の間で順番に割り当てていく
// ただし,最小,最大については割り当てる画素数に制限がある
int getHistEqu(int x,int *now,int *min,int *max,int *pix_min,int *pix_max)
{
int res;
if(now[x]==max[x]) {
if(pix_max[x]<=0) now[x]=min[x];
else pix_max[x]--;
}
if(now[x]==min[x]) {
if(pix_min[x]<=0) now[x]=min[x]+1;
else pix_min[x]--;
}
if(now[x]>max[x]) now[x]=min[x];
res=now[x];
now[x]++;
return res;
}
int effect(ImageData *img,ImageData *outimg)
{
int x,y;
int rr,gg,bb;
int ro,go,bo;
int i;
int val;
int ave;
int histR[256],histG[256],histB[256]; // ヒストグラム
int omaxR[256],omaxG[256],omaxB[256]; // 変換後,割り当てられる画素値の最小
int ominR[256],ominG[256],ominB[256]; // 変換後,割り当てられる画素値の最大
int pix_maxR[256],pix_maxG[256],pix_maxB[256]; // 最小値が割り当てられる画素数
int pix_minR[256],pix_minG[256],pix_minB[256]; // 最大値が割り当てられる画素数
int onowR[256],onowG[256],onowB[256]; // 次に割り当てる画素値
Pixel pix;
for(i=0;i<256;i++) {
histR[i]=histG[i]=histB[i]=0;
}
ave= img->height * img->width /256; // 画像の全画素数/画素値の範囲
// ヒストグラム作成
for(y=0;y<img->height;y++) {
for(x=0;x<img->width;x++) {
getPixel(img,x,y,&pix); //画像上の画素情報を取得
rr=pix.r;
gg=pix.g;
bb=pix.b;
histR[rr]++;
histG[gg]++;
histB[bb]++;
}
}
// 画素値の割り当て決定
getMinMax(histR,ominR,omaxR,pix_minR,pix_maxR,ave);
getMinMax(histG,ominG,omaxG,pix_minG,pix_maxG,ave);
getMinMax(histB,ominB,omaxB,pix_minB,pix_maxB,ave);
for(i=0;i<256;i++) {
onowR[i]=ominR[i];
onowG[i]=ominG[i];
onowB[i]=ominB[i];
}
// ヒストグラム均等化処理
for(y=0;y<img->height;y++) {
for(x=0;x<img->width;x++) {
getPixel(img,x,y,&pix); //画像上の画素情報を取得
ro=pix.r;
go=pix.g;
bo=pix.b;
rr=getHistEqu(ro,onowR,ominR,omaxR,pix_minR,pix_maxR);
gg=getHistEqu(go,onowG,ominG,omaxG,pix_minG,pix_maxG);
bb=getHistEqu(bo,onowB,ominB,omaxB,pix_minB,pix_maxB);
pix.r=rr;
pix.g=gg;
pix.b=bb;
setPixel(outimg,x,y,&pix); // 画像に値をセットする
}
}
return 0;
}
お礼
ご返事ありがとうございます。 managerの結果は相互に影響しないので、上の方法でやってみます。 データの中身によっては、ある断面(z=10)しか値がない場合があるので x,yの範囲に分割してみまーす。