2016-10-28 8 views
1

私は最初に、私が仕事を始めようとしている物理学者であることを警告したいと思います。私のC++知識は基本的に存在しません。BMPグレースケールヘッダーを追加する

私は現在GATEでCTスキャナのシミュレーションを行っています。出力をbmpファイルに変換する必要があります。

Gateは一連のfile_xxx.datを作成します。ここで、xxxは000から投影の数までの範囲で、それぞれに検出器の各ピクセルごとに1つの32bit floatの配列が含まれています。

グレースケールbmpヘッダーを追加して別のプログラムで再構築できるように、それぞれを1つずつ取る必要があります。このプロセスでは、ピクセルからの情報を失わないように32ビットの精度を維持したいので、可能であれば32ビットのグレースケールになります。

私はbmpヘッダーを動作させるために、Gateが持っている別の出力であるルートファイルを扱っています。私はむしろルートファイルの使用を避けたいのです。なぜなら、私は必要のない膨大な量の情報を処理しなければならず、処理が遅くなるからです。

私はこのコードの一部を書きました。コピー貼り付けしたものもあり、同僚が行ったものもあります。ほとんどの場合、ほとんど何をしているのか分かりません。

#include <iostream> 
#include <fstream> 
#include <ostream> 
#include <cerrno> 
#include <cstdlib> 
#include <set> 
#include <cmath> 
#include "TApplication.h" 
#include "TFile.h" 
#include "TTree.h" 
using namespace std; 

#define MAX_ANGLES 180 
#define PIXELS_X 100 
#define PIXELS_Y 100 
#define MAX_PIXELS 10000 

struct SDataA 
{ 
    float A[MAX_ANGLES][MAX_PIXELS]; 

    void Reset() 
    { 
    for (int a=0; a<MAX_ANGLES; a++) 
    { 
     for (int p=0; p<MAX_PIXELS; p++) 
     { 
     A[a][p] = 0.0; 
     } 
    } 
    } 
}; 

int main(int argc, char* argv[]) 
{ 

if(argc < 2) 
{ 
    cerr << "arguments missing" << endl; 
    cerr << "Usage : AnalyzeCT myFile.root " << endl; 
    exit(EXIT_FAILURE); 
} 

// Store the root file name in 'fileName' variable 
char* const FILENAME = argv[ 1 ]; 

// parameters for the histograms 

float a; 

SDataA *dataA=NULL; 
dataA = new SDataA; 
dataA->Reset(); 

int maxangles=MAX_ANGLES; 
int pixelsx=PIXELS_X; 

TApplication app("Application", &argc, argv); 

// Open (check) and read the root file 
TFile* file = new TFile(FILENAME); 
if(!file->IsOpen()) 
{ 
    cerr << "problem opening the root file : '" << FILENAME << "'" << endl; 
    cerr << strerror(errno) << endl; 
    exit(EXIT_FAILURE); 
} 

// Take the single tree, where is the position, the energy and the runID 
TTree* singlesTree = (TTree*)file->Get("Singles"); 
Int_t runID, pixelID; 
singlesTree->SetBranchAddress("runID", &runID); 
singlesTree->SetBranchAddress("pixelID", &pixelID); 

// Number of entries in the single tree 
Int_t entriesSingleTree = (Int_t)singlesTree->GetEntries(); 
cout << "Number of detected photons : " << entriesSingleTree << endl; 

for(Int_t i = 0; i != entriesSingleTree; ++i) 
{ 
    singlesTree->GetEntry(i); 

    if ((runID < MAX_ANGLES) && (pixelID < MAX_PIXELS)) 
    { 
    dataA->A[runID][pixelID] += 1; 
    a=dataA->A[runID][pixelID]; 
    // cout << "A[" << runID <<"]["<< pixelID<<"] ="<< a << endl; 
    } 

} 

std::ofstream ofile("Slice.bin", std::ios::binary); 
int currangle=0; 
short BM=19778; 
short bfReserved=0,biPlanes=1,biBitCount=32; 
int bfSize=54+40000, bfOffBits=54, biSize=40, biWidth=PIXELS_X, biHeight=PIXELS_Y,Zero=0,biClrUsed=1; 

ofile.write((char*) &BM, sizeof(short)); 
ofile.write((char*) &bfSize, sizeof(int)); 
ofile.write((char*) &bfReserved, sizeof(short)); 
ofile.write((char*) &bfReserved, sizeof(short)); 
ofile.write((char*) &bfOffBits, sizeof(int)); 

ofile.write((char*) &biSize, sizeof(int)); 
ofile.write((char*) &biWidth, sizeof(int)); 
ofile.write((char*) &biHeight, sizeof(int)); 
ofile.write((char*) &biPlanes, sizeof(short)); 
ofile.write((char*) &biBitCount, sizeof(short)); 
ofile.write((char*) &Zero, sizeof(int)); 
ofile.write((char*) &Zero, sizeof(int)); 
ofile.write((char*) &Zero, sizeof(int)); 
ofile.write((char*) &Zero, sizeof(int)); 
ofile.write((char*) &biClrUsed, sizeof(int)); 
ofile.write((char*) &Zero, sizeof(int)); 

for (Int_t k =currangle ; k<currangle+1; k++){ 
    for (Int_t j=0; j<MAX_PIXELS; j++){ 
    a=dataA->A[k][j]; 
    //cout<< dataA->A[k][j]<< endl; 
    ofile.write((char*) &a, sizeof(float)); //s1 
    } 

} 
ofile.close(); 

cout << "Done" << endl; 

delete singlesTree; 
delete gateTree; 

app.Run(); 


return 0; 
} 

は不完全なようですが、私は元のコードではコメントアウトされているいくつかの部分を削除してきたので、それはだ、いくつかのチャンクがあるかもしれませんし、それが今、本当にフランケンシュタインの怪物です。

実際には40054バイトの長さのファイル(ヘッダーから54、10000浮動小数点から40000)を取得しています。読み込み可能かどうかを確認するために.bmpに名前を変更していますがヘッダーには一貫しない定義があるかもしれないと思うが、私は全く手がかりがない。

は、私も自分のDATファイルを読むためにOpenCVのを使用しようとしましたが、私のマシンが台無しにされ、私はそれから抜け出すことができるすべては、エラー

EDITは:1) は、ここで私はそれらを開くhttps://ufile.io/86210 DATファイルがありますアミドでは、シミュレーションで生成された投影の1つが含まれています。浮動小数点数は現在の数値にはあまりにも大きいかもしれませんが、カウント数が多いほどシミュレーションに入る必要があるかもしれません。ここで

は、ルート・ファイルがhttps://ufile.io/a073

EDIT:2) 真、biSizeは今biSize = 40は、画像がすべて赤と黒のですが、何それが必要のように見える作品、設定されませんでした。リンクは/ 0a111の前の終わりのようになります(私はそれを投稿するためにもっと評判が必要です)私はそれはあまりにも愚かなことだった残念だった、私は数日間苦労してきたと私はフォーカスを失った

ファイルをリンクする方法私は

敬具、

+0

私はそれが間違っている見る最初の事はbisize'が初期化されていない 'ということです。 –

+0

私はあなたが32bitのグレースケール画像を得ることはできないと思っています。グレースケールは赤と青が等しく、単一のコンポーネントは256の値しか持たないことを意味します。 – alangab

+1

ソフトウェアを全く書かずにこれを行うことができます。あなたはサンプルデータファイルを提供できますか? –

答えて

2

ほとんどのLinuxディストリビューションにインストールされているImageMagickを使用すると、ソフトウェアを書き込まずにこのデータを従来のイメージ形式に変換することができ、macOSとWindowsで利用できます。

浮動小数点数である100x100ピクセルの画像に10,000浮動小数点が対応し、image.binというファイルにあると仮定すると、これをコマンドラインで入力すると正規化された浮動小数点TIFファイル:あなたは、データが完全な範囲を埋めるために正規化したくない場合は

convert -size 100x100 -depth 32 -define quantum:format=floating-point gray:image.bin -normalize result.tif 

enter image description here

  • -normalizeを省略します。

  • あなたはPNGファイルではなく、TIFがちょうどresult.tifあなたのデータはリトル/ビッグエンディアンの場合

  • result.pngに、-endian lsbまたは-endian msbに追加変更をしたい場合。

私はあなたの大きなファイルをダウンロードするように見えることはできませんが、あなたは削除する54バイトのヘッダーを持っている場合、あなたはこのような何かにコマンドを変更することができますいずれか

convert -size 100x100+54 -depth 32 -define quantum:format=floating-point gray:image.bin -normalize result.tif 

または使用54バイトのヘッダーを切り落とすためにそのようなddなどの外部ユーティリティ:

dd if=image.bin bs=54 skip=1 | convert -size 100x100 -depth 32 -define quantum:format=floating-point gray:- -normalize result.tif 
0

BMPファイルは、浮動小数点値をサポートしていないと、彼らは32ビットグレースケールのピクセルをsuppportません

ASanchをお知らせください。 BMPを使用して得ることができる最も近いのは10ビットのグレースケールです。このため、32ビット/ピクセルとBI_BITFIELDS圧縮を使用し、赤、緑、青の各チャネルに10ビット(32ビットモードはグレースケールをサポートしないため、すべてのRGBチャネルのビットを複製する必要があります)を使用します。

ファイル形式を拡大すると、BI_BITFIELDS圧縮を使用して32ビットすべてを使用して同じ赤、緑、および青のマスクを提供することができますが、96ビットRGBイメージを効果的にエンコードします。これは、RGBチャンネルのマスクが重ならないようにするという仕様に違反します。 (https://msdn.microsoft.com/en-us/library/windows/desktop/dd183381(v=vs.85).aspx

BTW:正しいエンコーディング(リトル/ビッグエンディアン)を使用していること、intをそのまま書いていること、プラットフォーム間で移植性がないことを確認してください。

+0

それを受け入れる画像フォーマットはありますか? – ASanch

+0

フロートが必要な場合は、FITSが動作します:https://en.wikipedia.org/wiki/FITS – Meixner

関連する問題