2016-10-28 3 views
1

나는 먼저 일을 시작하려고하는 물리학 자라고 경고하고 싶습니다. C++ 지식은 기본적으로 존재하지 않습니다.BMP 그레이 스케일 헤더 추가

현재 GATE가있는 CT 스캐너의 시뮬레이션 작업을하고 있으며 출력을 bmp 파일로 변환해야합니다.

게이트는 일련의 file_xxx.dat를 만듭니다. 여기서 xxx는 000에서부터 투영 수까지의 범위이며, 각각은 감지기에있는 각 픽셀에 대해 하나씩 32 비트 부동 소수점 배열을 포함합니다.

다른 프로그램으로 재구성 할 수 있도록 각 프로그램을 가져 와서 회색조 bmp 헤더를 추가해야합니다. 이 과정에서 픽셀의 정보를 잃지 않도록 32 비트 정밀도를 유지하여 32 비트 회색조가 될 수도 있습니다.

나는 게이트 파일의 루트 파일 인 bmp 헤더를 작동 시키려고 노력하고있다. 나는 루트 파일을 사용하는 것을 피하고 싶다. 왜냐하면 내가 필요로하지 않는 엄청난 양의 정보를 처리해야하고 프로세스 속도가 느려지 기 때문이다.

이 코드의 일부를 작성했으며 다른 사람이 복사하여 붙여 넣었으며 일부는 동료들에 의해 수행되었으므로 대부분의 시간을 거의 알지 못합니다.

#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를 사용하려고했지만 내 컴퓨터가 엉망이되고 나는 그것을 밖으로 얻을 수있는 모든 오류

편집 : 1) 여기 내가 그들을 열 https://ufile.io/86210 은 DAT 파일의 아마드와 함께, 그들은 시뮬레이션으로 생성 된 투영 중 하나를 포함합니다. float가 현재 포함 된 숫자에 비해 너무 많을 수도 있지만 더 많은 수의 시뮬레이션을 수행해야 할 수도 있습니다. 여기

는 루트 파일을 https://ufile.io/a073

편집이다 : 2) 사실은 biSize은 biSize = 40이 이미지는 모든 빨간색과 검은 색입니다 작동 현재 설정하지만 무엇을해야처럼 보인다되지 않았습니다. 링크는/0a111의 이전 결말과 같을 것입니다. (나는 그것을 게시하는 데 더 많은 평판이 필요합니다.) 미안합니다. 어리석은 일이었습니다. 며칠 동안 고생했습니다. 초점을 잃었습니다.

더 좋은 점이 있다면 파일을 연결하는 방법 나를

안부,

+0

내가 그 잘못 볼 수있는 첫 번째 일은 bisize'가 초기화되지'이다. –

+0

32 비트 그레이 스케일 이미지를 얻을 수 있다고 생각하지 않습니다. 그레이 스케일은 빨간색과 파란색이 같고 하나의 구성 요소가 256 개만 가질 수 있음을 의미합니다. – alangab

+1

소프트웨어를 전혀 쓰지 않고도이 작업을 수행 할 수 있습니다. 샘플 데이터 파일을 제공해 주시겠습니까? –

답변

2

대부분의 Linux 배포판에 설치된 ImageMagick을 사용하고 macOS 및 Windows에서 사용할 수있는 경우 소프트웨어를 작성하지 않고이 데이터를 일반적인 이미지 형식으로 변환 할 수 있습니다.

부동 소수점 숫자이고 각각 ​​image.bin이라는 파일에있는 10000 개의 부동 소수점 이미지에 해당한다고 가정하면이 값을 명령 줄에 입력하여 정규화 된 부동 소수점 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 

또는를 사용 외부 유틸리티와 같은 dd는 54 바이트의 헤더를 베다합니다 :

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

관련 문제