グレースケールのRAW画像を、RGB合成するプログラムについて。
グレースケールのRAW画像を、RGB合成するプログラムについて。
現在、3枚のグレースケールRAW画像を読み込み、「ヒストグラム伸張化」を行ってから、RGB合成を行う画像処理プログラムを作成しています。
そこで、合成したカラー画像が、どうしても紫がかった色になってしまい困っています。
3枚の原画像それぞれに、ヒストグラム伸張化の処理を行うのですが…
この処理では、画像の輝度値の最大レベルmaxと最小レベルminを設定し
a' = (a-min)*255/(max-min)
という式で、輝度値aをa'に補正しています。
この処理を行うと、ヒストグラムが無理やり引き延ばされて、ある輝度値と、次の輝度値とに間ができてしまいます。(伝わりにくければすみません)
3枚の原画像それぞれでmaxとminの値が違うので、作成するRGB画像の、ある画素には例えばRの値しか入っていないということになってしまうと思うのです。
これが、原因かと考えたのですが、どうなのでしょうか。
いろいろと調べてみたところヒストグラム伸張化を行ってカラー画像を作成できるらしいのですが…何度確認してもプログラムのおかしいところを見付けることができません。
非常にわかりにくい文章であるとは思いますが、アドバイスだけでもいただけると嬉しいです。
どうかよろしくお願いします。
そこで、合成したカラー画像が、どうしても紫がかった色になってしまい困っています。
3枚の原画像それぞれに、ヒストグラム伸張化の処理を行うのですが…
この処理では、画像の輝度値の最大レベルmaxと最小レベルminを設定し
a' = (a-min)*255/(max-min)
という式で、輝度値aをa'に補正しています。
この処理を行うと、ヒストグラムが無理やり引き延ばされて、ある輝度値と、次の輝度値とに間ができてしまいます。(伝わりにくければすみません)
3枚の原画像それぞれでmaxとminの値が違うので、作成するRGB画像の、ある画素には例えばRの値しか入っていないということになってしまうと思うのです。
これが、原因かと考えたのですが、どうなのでしょうか。
いろいろと調べてみたところヒストグラム伸張化を行ってカラー画像を作成できるらしいのですが…何度確認してもプログラムのおかしいところを見付けることができません。
非常にわかりにくい文章であるとは思いますが、アドバイスだけでもいただけると嬉しいです。
どうかよろしくお願いします。
Re: グレースケールのRAW画像を、RGB合成するプログラムについて。
元のプログラムとRAW画像がないので一般的な回答しかできませんが、
・ヒストグラム伸長化を行わずにRGB合成(Rチャネル、Gチャネル、Bチャネルのグレースケール画像からRGB画像を作るということですよね?)を行った場合に紫がかった状態になっていないか
→何もせずに紫がかった状態ならば、ヒストグラム伸長化の処理は原因でないと考えます
・上で問題なかった場合、ヒストグラム伸長化したあとのグレースケール画像が明暗のくっきりしたグレースケール画像になっているか
→この時点で明暗のくっきりしていない画像になっていない場合、ヒストグラム伸長化の処理がおかしい可能性があります
ここからは推測ですが、ヒストグラム伸長を行う計算においてint型を使って計算しているために誤差が発生している可能性はないでしょうか。
挙げていただいた式でいうと、a、max、minをそれぞれfloatなりdoubleにキャストして小数での演算を行い、
最後にint型に丸めて最終画素値とする感じです(たとえば以下のような感じに)
#あまり効果はないかもしれませんが^^;
・ヒストグラム伸長化を行わずにRGB合成(Rチャネル、Gチャネル、Bチャネルのグレースケール画像からRGB画像を作るということですよね?)を行った場合に紫がかった状態になっていないか
→何もせずに紫がかった状態ならば、ヒストグラム伸長化の処理は原因でないと考えます
・上で問題なかった場合、ヒストグラム伸長化したあとのグレースケール画像が明暗のくっきりしたグレースケール画像になっているか
→この時点で明暗のくっきりしていない画像になっていない場合、ヒストグラム伸長化の処理がおかしい可能性があります
ここからは推測ですが、ヒストグラム伸長を行う計算においてint型を使って計算しているために誤差が発生している可能性はないでしょうか。
挙げていただいた式でいうと、a、max、minをそれぞれfloatなりdoubleにキャストして小数での演算を行い、
最後にint型に丸めて最終画素値とする感じです(たとえば以下のような感じに)
#あまり効果はないかもしれませんが^^;
Advanced Supporting Developer
無理やりこじつけ(ぉ
無理やりこじつけ(ぉ
Re: グレースケールのRAW画像を、RGB合成するプログラムについて。
>>ホヅミさん
返信ありがとうございます。
失礼しました。
ソースコードを下に記します。
>>asdさん
RAW画像は、衛星画像です。
先ほど新しい事実が発覚したのですが… ><;;
以前、同じプログラムを作成した方のものも実行してみたのですが、以前はきちんとカラー画像が作成できていたプログラムとまったく同じものを使用しても、色みのおかしい画像ができてしまいました。
PCが違うのですが、これは原因のうちに入るのでしょうか。
キャストですか…あまり問題はないと思ったのですが、どうでしょうか。
プログラムを確認していただけるとうれしいです。
よろしくお願いします。
返信ありがとうございます。
失礼しました。
ソースコードを下に記します。
>>asdさん
RAW画像は、衛星画像です。
先ほど新しい事実が発覚したのですが… ><;;
以前、同じプログラムを作成した方のものも実行してみたのですが、以前はきちんとカラー画像が作成できていたプログラムとまったく同じものを使用しても、色みのおかしい画像ができてしまいました。
PCが違うのですが、これは原因のうちに入るのでしょうか。
キャストですか…あまり問題はないと思ったのですが、どうでしょうか。
プログラムを確認していただけるとうれしいです。
よろしくお願いします。
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
static unsigned char buf_1[800*800], buf_2[800*800], buf_3[800*800] ,buf[800*800*3];
FILE *file_1,*file;
int i,max,min;
file_1=fopen("sample1.gray","rb");
max=201;
min=85;
for(i=0;i<800*800;i++)
{
fread(&buf_1[i],1,1,file_1);
buf_1[i]=(255/(max-min))*(buf_1[i] - min);
}
fclose(file_1);
file_1=fopen("sample2.gray","rb");
max=106;
min=27;
for(i=0;i<800*800;i++)
{
fread(&buf_2[i],1,1,file_1);
buf_2[i]=(255/(max-min))*(buf_2[i] - min);
}
fclose(file_1);
file_1=fopen("sample3.gray","rb");
max=138;
min=24;
for(i=0;i<800*800;i++)
{
fread(&buf_3[i],1,1,file_1);
buf_3[i]=(255/(max-min))*(buf_3[i] - min);
}
fclose(file_1);
for(i=0;i<800*800;i=i+1)
{
buf[i*3]=buf_3[i];
buf[i*3+1]=buf_2[i];
buf[i*3+2]=buf_1[i];
}
file= fopen("RGB.rgb","wb");
for(i=0;i<800*800*3;i++)
{
fwrite(&buf[i],1,1,file);
}
fclose(file);
return EXIT_SUCCESS;
}
Re: グレースケールのRAW画像を、RGB合成するプログラムについて。
例えばココが怪しいと思います。
max, min, buf_1はいずれも整数型です。そこで、計算時にはint型へ昇格されます。
従って、255と(max-min)、(buf_1 - min)はすべてint型として扱われます。
特に割り算が問題で、整数/整数は小数点以下が「切り捨てられ」て、整数として結果が求まります。
max-minが256以上ですと、255/(max-min)が常に0となります。
そうでなくとも、かなりの誤差が出ることが予想されます。
今回のmax-minは116, 79, 114なので、255/(max-min)が常に0になるということはないみたいですね。
従って、255と(max-min)、(buf_1 - min)はすべてint型として扱われます。
特に割り算が問題で、整数/整数は小数点以下が「切り捨てられ」て、整数として結果が求まります。
max-minが256以上ですと、255/(max-min)が常に0となります。
そうでなくとも、かなりの誤差が出ることが予想されます。
今回のmax-minは116, 79, 114なので、255/(max-min)が常に0になるということはないみたいですね。
Re: グレースケールのRAW画像を、RGB合成するプログラムについて。
>>beatleさん
返信ありがとうございます。
なるほどです…ではfloat型で宣言して計算するのがよいのでしょうか…><;;
また、buf[]自体はcharですが、計算後代入するのは、文字型に明示的にキャストしてからのほうがよいでしょうか?
返信ありがとうございます。
なるほどです…ではfloat型で宣言して計算するのがよいのでしょうか…><;;
また、buf[]自体はcharですが、計算後代入するのは、文字型に明示的にキャストしてからのほうがよいでしょうか?
Re: グレースケールのRAW画像を、RGB合成するプログラムについて。
良いのかどうか、聞く前にやってみてください。
僕だって、floatにして計算したら症状が改善するかなんて分かりません。
変更は簡単ですよね?
僕だって、floatにして計算したら症状が改善するかなんて分かりません。
変更は簡単ですよね?
Re: グレースケールのRAW画像を、RGB合成するプログラムについて。
この質問にも無視せず答えて下さいね。asd さんが書きました:・ヒストグラム伸長化を行わずにRGB合成(Rチャネル、Gチャネル、Bチャネルのグレースケール画像からRGB画像を作るということですよね?)を行った場合に紫がかった状態になっていないか
→何もせずに紫がかった状態ならば、ヒストグラム伸長化の処理は原因でないと考えます
・上で問題なかった場合、ヒストグラム伸長化したあとのグレースケール画像が明暗のくっきりしたグレースケール画像になっているか
→この時点で明暗のくっきりしていない画像になっていない場合、ヒストグラム伸長化の処理がおかしい可能性があります
Re: グレースケールのRAW画像を、RGB合成するプログラムについて。
>>beatleさん
返信ありがとうございます。
それについては、
まず補正を行う前に合成を行うと、正しいはずの出力画像よりも青っぽい感じで出力されてしまいました。
また、伸張化を行ったあとのGRAY画像は、明暗のくっきりした画像になっていました。
これにより、原画像ファイルのデータが壊れているかもしれないと思い、新しく画像を取ってきたのですが、実行結果は変わりませんでした。
返信ありがとうございます。
それについては、
まず補正を行う前に合成を行うと、正しいはずの出力画像よりも青っぽい感じで出力されてしまいました。
また、伸張化を行ったあとのGRAY画像は、明暗のくっきりした画像になっていました。
これにより、原画像ファイルのデータが壊れているかもしれないと思い、新しく画像を取ってきたのですが、実行結果は変わりませんでした。
Re: グレースケールのRAW画像を、RGB合成するプログラムについて。
>>beatleさん
返信ありがとうございます。
それについても確認しましたが、正しいはずです。
3つの画像は衛星画像で、sample1はバンド1、sample2はバンド2、sample3はバンド3の画像です。
トゥルーカラーに合成したいので、Rにはバンド3、Gにはバンド2、Bにはバンド1を割り当てました。
返信ありがとうございます。
それについても確認しましたが、正しいはずです。
3つの画像は衛星画像で、sample1はバンド1、sample2はバンド2、sample3はバンド3の画像です。
トゥルーカラーに合成したいので、Rにはバンド3、Gにはバンド2、Bにはバンド1を割り当てました。
Re: グレースケールのRAW画像を、RGB合成するプログラムについて。
後考えられるのは、画像の閲覧アプリが当時と違っていて、RGBの順番が実は違う、という感じでしょうか。
Re: グレースケールのRAW画像を、RGB合成するプログラムについて。
>>beatleさん
返信ありがとうございます。
閲覧アプリには「ImageMagick」を使用しています。
RGBの順番は間違っていないはずです。
今のコードは下のようになっています。
アドバイスだけでもよいので、どなたかお願い致します。
返信ありがとうございます。
閲覧アプリには「ImageMagick」を使用しています。
RGBの順番は間違っていないはずです。
今のコードは下のようになっています。
アドバイスだけでもよいので、どなたかお願い致します。
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
static unsigned char buf_1[800*800], buf_2[800*800], buf_3[800*800] ,buf[800*800*3];
FILE *file_1,*file;
int i;
float max,min,a;
file_1=fopen("sample1.gray","rb");
max=201.0;
min=85.0;
for(i=0;i<800*800;i++)
{
fread(&buf_1[i],1,1,file_1);
a=buf_1[i]-0.0;
buf_1[i]=(char)((255.0/(max-min))*(a - min));
}
fclose(file_1);
file_1=fopen("sample2.gray","rb");
max=106.0;
min=27.0;
for(i=0;i<800*800;i++)
{
fread(&buf_2[i],1,1,file_1);
a=buf_2[i]-0.0;
buf_2[i]=(char)((255.0/(max-min))*(a - min));
}
fclose(file_1);
file_1=fopen("sample3.gray","rb");
max=138.0;
min=24.0;
for(i=0;i<800*800;i++)
{
fread(&buf_3[i],1,1,file_1);
a=buf_3[i]-0.0;
buf_3[i]=(char)((255.0/(max-min))*(a - min));
}
fclose(file_1);
for(i=0;i<800*800;i++)
{
buf[i*3]=buf_3[i];
buf[i*3+1]=buf_2[i];
buf[i*3+2]=buf_1[i];
}
file= fopen("RGB.rgb","wb");
for(i=0;i<800*800*3;i++)
{
fwrite(&buf[i],1,1,file);
}
fclose(file);
return EXIT_SUCCESS;
}
Re: グレースケールのRAW画像を、RGB合成するプログラムについて。
RGBの順番が合ってると仰っているので余計なお世話かもしれませんが、本当にそうなのかを確認するために、
buf_3の全要素を255、buf_2,buf_1の全要素を0として、真っ赤な画像になることを確認する。
同様に、buf_2, buf_1それぞれを255に、他を0にした画像を作り、それぞれ緑、青の画像になることを確認する。
という作業をやってみたら如何でしょうか。
最後のあたりでbufにbuf_3, buf_2, buf_1を書き込むところを、buf_3の代わりに255を使い、buf_2とbuf_1の代わりに0を使えばいいでしょう。
buf_3の全要素を255、buf_2,buf_1の全要素を0として、真っ赤な画像になることを確認する。
同様に、buf_2, buf_1それぞれを255に、他を0にした画像を作り、それぞれ緑、青の画像になることを確認する。
という作業をやってみたら如何でしょうか。
最後のあたりでbufにbuf_3, buf_2, buf_1を書き込むところを、buf_3の代わりに255を使い、buf_2とbuf_1の代わりに0を使えばいいでしょう。
Re: グレースケールのRAW画像を、RGB合成するプログラムについて。
しばらく離れている間に大分進んでるっΣ(´д`|||
以下のような感じでピクセル単位でfreadしたものを一旦float型に変換し、キャストでcharに戻したということでよいでしょうか。
上記の推測で正しいならば、float型変数aを”介さずに”そのままbuf_1のデータを格納してトルゥーカラー画像を合成してもらえないでしょうか。
これで色がおかしくならないのならば、float型に変換している時点で値がおかしくなっているのではと疑っています。
この部分でbuf_1であらわされている本来の値と変換後のaが実は違っているのではないかなと。
#そうでないとヒストグラム伸張化なしでも色がおかしくなる原因が謎になってしまうので。freadした時点で壊れてる?
実際のrawデータがあればこちらでも試して見られるのですが(ノ∀`)
beatleさんも指摘しているように、元の画像をただ読みこんでそのまま書き出し、それをRGB合成したときに
正しくRGB合成された画像が得られないと、ヒストグラム伸張化の結果も正しく表示できないので、
まずはRGB合成が正しくできるところまでこぎつけたいですね(`・ω・´)
念のため確認ですが、補正を行う前に合成した方法としては、いちこ さんが書きました:>>beatleさん
返信ありがとうございます。
それについては、
まず補正を行う前に合成を行うと、正しいはずの出力画像よりも青っぽい感じで出力されてしまいました。
以下のような感じでピクセル単位でfreadしたものを一旦float型に変換し、キャストでcharに戻したということでよいでしょうか。
file_1=fopen("sample1.gray","rb");
max=201.0;
min=85.0;
for(i=0;i<800*800;i++)
{
fread(&buf_1[i],1,1,file_1);
a=buf_1[i]-0.0;
//buf_1[i]=(char)((255.0/(max-min))*(a - min));
buf_1[i]=(char)a;//手を入れずにそのまま格納
}
/*以下、残りのチャネルも同様*/
file_1=fopen("sample1.gray","rb");
max=201.0;
min=85.0;
for(i=0;i<800*800;i++)
{
fread(&buf_1[i],1,1,file_1);//読み込んだままを使う
}
/*以下、残りのチャネルも同様*/
この部分でbuf_1であらわされている本来の値と変換後のaが実は違っているのではないかなと。
#そうでないとヒストグラム伸張化なしでも色がおかしくなる原因が謎になってしまうので。freadした時点で壊れてる?
実際のrawデータがあればこちらでも試して見られるのですが(ノ∀`)
beatleさんも指摘しているように、元の画像をただ読みこんでそのまま書き出し、それをRGB合成したときに
正しくRGB合成された画像が得られないと、ヒストグラム伸張化の結果も正しく表示できないので、
まずはRGB合成が正しくできるところまでこぎつけたいですね(`・ω・´)
Advanced Supporting Developer
無理やりこじつけ(ぉ
無理やりこじつけ(ぉ
Re: グレースケールのRAW画像を、RGB合成するプログラムについて。
>>asdさん
返信ありがとうございます!
どうやら、RGBへの各バンドの対応がおかしかったようです…。
「.rgb」の画像のフォーマットどおりに組んだつもりだったのですが…今、フォーマットについて調べ直しているところです。
気にかけてくださってありがとうございます。
返信ありがとうございます!
どうやら、RGBへの各バンドの対応がおかしかったようです…。
「.rgb」の画像のフォーマットどおりに組んだつもりだったのですが…今、フォーマットについて調べ直しているところです。
気にかけてくださってありがとうございます。
Re: グレースケールのRAW画像を、RGB合成するプログラムについて。
動くようになってよかったですね。
いちこさんのソースコードにはいくつか問題があります。
(紫になってしまう問題とは大幅に異なる質問ですから、新規スレッドを建てたほうがいいかもしれません。「プログラムの改善策を教えて下さい」とか。)
ただし、いちこさんがプログラムの勉強はあまりする気はなく、動けばいいや、という気持ちなら質問しないでください。
「プログラムの改善には正直興味がないが、聞けるんだったら一応聞いておくか」という気持ちで質問すると回答者の皆様に失礼です。
よろしくお願いします。
いちこさんのソースコードにはいくつか問題があります。
- 重複が多い。実質的にsample1, sample2, sample3の処理は同じです。
- fread, fwiteが1バイトずつの処理しかしておらず、普通でない書き方になっている。速度的にもあまり良くない。
(紫になってしまう問題とは大幅に異なる質問ですから、新規スレッドを建てたほうがいいかもしれません。「プログラムの改善策を教えて下さい」とか。)
ただし、いちこさんがプログラムの勉強はあまりする気はなく、動けばいいや、という気持ちなら質問しないでください。
「プログラムの改善には正直興味がないが、聞けるんだったら一応聞いておくか」という気持ちで質問すると回答者の皆様に失礼です。
よろしくお願いします。
Re: グレースケールのRAW画像を、RGB合成するプログラムについて。
>>beatleさん
返信ありがとうございます。
勉強したい気持ちはおおいにあります。
しかしまずはもう少し自分で考えてから、質問させていただきます。
気にかけてくださってありがとうございます。
いろいろ考えてくださってありがとうございました。
精進します!
返信ありがとうございます。
勉強したい気持ちはおおいにあります。
しかしまずはもう少し自分で考えてから、質問させていただきます。
気にかけてくださってありがとうございます。
いろいろ考えてくださってありがとうございました。
精進します!