Electro-L衛星のL15形式の画像を表示する

こんにちは、ハバルゼリー。

ご存知のように、Electro-Lサテライトからの写真は2つの形式でFTPにアップロードされます。

1つはよく知られているjpgで、これには興味がありません。

2番目、 Zelenyikotが 書いたように

気象学者のみが利用できる「秘密」フォーマット。 ネットワーク上に開いて表示できるソフトウェアはありません。 確かに、彼らは写真の観点から、JPEGと同じであり、テキストのみの追加情報があることを保証しました-あらゆる種類のもの、高さ、温度、速度...


ここでそれを読もうとしています。

追加情報を読むことはできませんでしたが、写真は非常に読みやすく、JPGの場合とは異なり、単一チャネルあたりのビット数が異なります。 JPGに8(グレーの256階調)がある場合、L15には10(グレーの1024階調)があります。





ファイル内の画像が暗号化されていない場合、画像サイズはその中にあるはずです。 暗号化されていないことを期待しましょう。

jpg 2784x2784形式の衛星写真の画像サイズ。 2784を16進数に転送すると、0A E0が得られます。 このシーケンスを裏返して、E0 0Aを探す必要があります

見つかったe0 0a 00 00 e0 0a 00 00 10 00





このデータを4バイトでグループ化し、10進数として表示すると、 2784 2784 16



得られます



直前に挿入されたブロックの終わりから、ファイルの0xEC8800(15501312)バイトの終わりまで。

15501312 /(2784 * 2784)= 2。 これらの結果から、1つのピクセルが2バイトで記述されると仮定します。



しかし、画像を読み込もうとする前に、画像が始まる場所を探す方法を理解する必要があります。

L15ファイルで2日間、画像のあるエリアの直接アドレスまたはそれに近いサイトを検索するか、このアドレスへのオフセットを検索しても成功しませんでした。

したがって、このセクションを「真正面から」探し、2784または11136の番号が見つかるまでファイルを少しずつ読み取ります(これはRGBチャンネルからの画像の解像度です)。

次に、この番号が再度繰り返されるかどうかを確認し、繰り返される場合は、次の番号が16かどうかを確認します。

すべてが正しい場合、おめでとうございます、私たちは絵の始まりを見つけました。

 long Find_Image_Pos(FILE *EL_Data,int *res_out) { unsigned int int_data; int resolution; unsigned long filepos; filepos=0; while(!feof(EL_Data)) { fseek(EL_Data,filepos,SEEK_SET); fread((void*)&int_data,sizeof(unsigned int),1,EL_Data); if(int_data==2784||int_data==11136) { resolution=int_data; fread((void*)&int_data,sizeof(unsigned int),1,EL_Data); if(int_data==resolution) { fread((void*)&int_data,sizeof(unsigned int),1,EL_Data); if(int_data==16) { *res_out=resolution; return ftell(EL_Data); } } } filepos++; } return 0; }
      
      





このメソッドは松葉杖ですが、これまでのところエラーはありません。



次に、この画像を読み取り、何らかの方法で表示するかファイルに保存する必要があります。 画像を扱う必要がなかったため、 ポータブルanymap形式を使用してプロセスを高速化し、コードを簡単にすることにしました。

     2       . void Save_Image(FILE *EL_Data,FILE *EL_Image,long pos,int resolution) { #ifdef P5 char header[50]; sprintf(header,"P5\n%i %i\n1024\n",resolution,resolution); fwrite(&header,strlen(header),1,EL_Image); #else fprintf(EL_Image,"P2\n%i %i\n1024\n",resolution,resolution); #endif int progress=-1; int max=0; int x=0,y=0; int pixel=0; fseek(EL_Data,pos,SEEK_SET); for(y=0;y<resolution;y++) { if(progress<(y*100/resolution)) { progress=(y*100/resolution); cout<<progress<<"%"<<endl; } for(x=0;x<resolution;x++) { fread(&pixel,2,1,EL_Data); #ifdef P5 fwrite(&pixel,1,1,EL_Image); #else fprintf(EL_Image,"%i\n",pixel); #endif if(pixel>max) max=pixel; } } cout<<"100 %"<<endl; cout<<"max="<<max<<endl; }
      
      





P5形式では、明るさが255を超える(つまり1バイトを超える)ピクセルは黒になります。



結果:

P2:



P5





そして最後に、上記の機能を接続するコード

 #include <iostream>; #include <stdio.h> #include <tchar.h> #include <stdlib.h> #include <windows.h> //#define P5 using namespace std; long Find_Image_Pos(FILE *EL_Data,int *res_out); void Save_Image(FILE *EL_Data,FILE *EL_Image,long pos,int resolution); int _tmain(int argc, _TCHAR* argv[]) { FILE *EL_Data,*EL_Image; if(argc==1) return 0; EL_Data=_wfopen(argv[1],L"rb"); if(!EL_Data) return 0; wchar_t out_file[300]; #ifdef P5 wsprintf(out_file,L"%s.P5.pgm",argv[1]); EL_Image=_wfopen(out_file,L"wb"); #else wsprintf(out_file,L"%s.P2.pgm",argv[1]); EL_Image=_wfopen(out_file,L"wt"); #endif if(!EL_Image) return 0; int resolution=0; long pos=Find_Image_Pos(EL_Data,&resolution); if(!pos) return 0; Save_Image(EL_Data,EL_Image,pos,resolution); fclose(EL_Image); fclose(EL_Data); return 0; }
      
      







チャネルごとに10ビットの色深度を持つ画像を使用して、HDRi画像を作成できます。 ただし、これは別のトピックのトピックです。



UPD:テキストデータがwchar形式で保存されている疑いがあります。 確認する必要があります...



All Articles