pixels - DICOM Convert 16 bit to 8bit -


big trees: want find solution of follow question: want convert pixeldata of dicom file 8bit(byte[]) file bitsallocated 16bit. whatever it's grayscale or color. know color's simpleperpixel 3.

3q!!!!

you cannot take pixel data , transform 8 bit (unless sure values in range supported byte). because alter important data: dicom file may store pixel data in visual density units or hounsfield units, , modifying values may screw things.

you can apply transformation 8 bits presentation data, values resulting modality voi/lut , presentation voi/lut transformations.

this example uses imebra library uses presentation data obtain 8 bits per color channel image, saved in jpeg format. modify color space ybr_full rgb in both color transform , image allocation in order rgb image.

example (in case link changes):

/*  imebra 2011 build 2013-07-16_08-42-08  imebra: c++ dicom library  copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 paolo brandoli/binarno s.p. rights reserved.  program free software; can redistribute and/or modify  under terms of gnu general public license version 2 published  free software foundation.  program distributed in hope useful,  without warranty; without implied warranty of  merchantability or fitness particular purpose.  see  gnu general public license more details.  should have received copy of gnu general public license  along program; if not, write free software  foundation, inc., 51 franklin st, fifth floor, boston, ma  02110-1301  usa  -------------------  if want use imebra commercially have buy commercial  support available @ http://imebra.com  after buy commercial support can use imebra according  terms described in imebra commercial license version 1. copy of imebra commercial license version 1 available in  documentation pages.  imebra available @ http://imebra.com  author can contacted email @ info@binarno.com or mail @  following address:  paolo brandoli  rakuseva 14  1000 ljubljana  slovenia    */  #include <iostream>   #include "../../library/imebra/include/imebra.h" #include <sstream>  #ifdef puntoexe_windows #include <process.h> #else #include <spawn.h> #include <sys/wait.h> #endif  #include <memory> #include <list>  using namespace puntoexe; using namespace puntoexe::imebra;  int findargument(const char* argument, int argc, char* argv[]) {     for(int scanarg(0); scanarg != argc; ++scanarg)     {             if(std::string(argv[scanarg]) == argument)             {                     return scanarg;             }     }     return -1; }    int main(int argc, char* argv[]) {     std::wstring version(l"1.0.0.1");     std::wcout << l"dicom2jpeg version " << version << std::endl;      try     {              if(argc < 3)             {                 std::wcout << l"usage: dicom2jpeg dicomfilename jpegfilename [-ffmpeg ffmpegpath ffmpegopt]" << std::endl;                 std::wcout << "dicomfilename        = name of dicom file" << std::endl;                 std::wcout << "jpegfilename         = name of final jpeg file" << std::endl;                 std::wcout << "-ffmpeg ffmpegpath   = launches ffmpeg after generating jpeg images." << std::endl;                 std::wcout << " ffmpegpath path ffmpeg" << std::endl;                 std::wcout << " ffmpegopt options ffmpeg" << std::endl;                 std::wcout << " input images , frame rate added automatically options" << std::endl;                 return 1;             }              // separate extension file name             std::string outputfilename(argv[2]);             std::string extension;             size_t dotpos(outputfilename.rfind('.'));             if(dotpos != outputfilename.npos)             {                     extension = outputfilename.substr(dotpos);                     outputfilename.erase(dotpos);             }             else             {                     extension = ".jpg";             }              // check -ffmpeg flag             int ffmpegflag(findargument("-ffmpeg", argc, argv));             size_t framescount(0);             ptr<dataset> loadeddataset;              try             {                  // open file containing dicom dataset                 ptr<puntoexe::stream> inputstream(new puntoexe::stream);                 inputstream->openfile(argv[1], std::ios_base::in);                  // connect stream reader dicom stream. several stream reader                 //  can share same stream                 ptr<puntoexe::streamreader> reader(new streamreader(inputstream));                  // codec factory , let use right codec create dataset                 //  input stream                 ptr<codecs::codecfactory> codecsfactory(codecs::codecfactory::getcodecfactory());                 loadeddataset = codecsfactory->load(reader, 2048);                   // first image. use in case there isn't presentation voi/lut                 //  , have calculate optimal 1                 ptr<image> datasetimage(loadeddataset->getimage(0));                 imbxuint32 width, height;                 datasetimage->getsize(&width, &height);                   // build transforms chain                 ptr<transforms::transformschain> chain(new transforms::transformschain);                  ptr<transforms::modalityvoilut> modalityvoilut(new transforms::modalityvoilut(loadeddataset));                 chain->addtransform(modalityvoilut);                  ptr<transforms::colortransforms::colortransformsfactory> colorfactory(transforms::colortransforms::colortransformsfactory::getcolortransformsfactory());                 if(colorfactory->ismonochrome(datasetimage->getcolorspace()))                 {                     // convert monochrome2 if modality transform not present                     if(modalityvoilut->isempty())                     {                         ptr<transforms::colortransforms::colortransform> monochromecolortransform(colorfactory->gettransform(datasetimage->getcolorspace(), l"monochrome2"));                         if(monochromecolortransform != 0)                         {                             chain->addtransform(monochromecolortransform);                         }                     }                      ptr<transforms::voilut> presentationvoilut(new transforms::voilut(loadeddataset));                     imbxuint32 firstvoilutid(presentationvoilut->getvoilutid(0));                     if(firstvoilutid != 0)                     {                         presentationvoilut->setvoilut(firstvoilutid);                     }                     else                     {                         // run transform on first image                         ptr<image> temporaryimage = chain->allocateoutputimage(datasetimage, width, height);                         chain->runtransform(datasetimage, 0, 0, width, height, temporaryimage, 0, 0);                          // find optimal voilut                         presentationvoilut->applyoptimalvoi(temporaryimage, 0, 0, width, height);                     }                     chain->addtransform(presentationvoilut);                 }                  std::wstring initialcolorspace;                 if(chain->isempty())                 {                     initialcolorspace = datasetimage->getcolorspace();                 }                 else                 {                     ptr<image> startimage(chain->allocateoutputimage(datasetimage, 1, 1));                     initialcolorspace = startimage->getcolorspace();                 }                  // color transform ycrcb                 ptr<transforms::colortransforms::colortransform> colortransform(colorfactory->gettransform(initialcolorspace, l"ybr_full"));                 if(colortransform != 0)                 {                     chain->addtransform((colortransform));                 }                  ptr<image> finalimage(new image);                 finalimage->create(width, height, image::depthu8, l"ybr_full", 7);                  // scan through frames                 for(imbxuint32 framenumber(0); ; ++framenumber)                 {                     if(framenumber != 0)                     {                         datasetimage = loadeddataset->getimage(framenumber);                     }                       if(chain->isempty() && datasetimage->getdepth() != finalimage->getdepth() && datasetimage->gethighbit() != finalimage->gethighbit())                     {                         chain->addtransform(new transforms::transformhighbit);                     }                      if(!chain->isempty())                     {                         chain->runtransform(datasetimage, 0, 0, width, height, finalimage, 0, 0);                     }                     else                     {                         finalimage = datasetimage;                     }                      // open stream jpeg                     const std::wstring jpegtransfersyntax(l"1.2.840.10008.1.2.4.50");                     std::ostringstream jpegfilename;                     jpegfilename << outputfilename;                     if(framenumber != 0 || ffmpegflag >= 0)                     {                             jpegfilename << "_" << framenumber;                     }                     jpegfilename << extension;                     ptr<puntoexe::stream> jpegstream(new puntoexe::stream);                     jpegstream->openfile(jpegfilename.str(), std::ios_base::out | std::ios_base::trunc);                     ptr<puntoexe::streamwriter> jpegwriter(new streamwriter(jpegstream));                     ptr<codecs::codec> outputcodec(codecsfactory->getcodec(jpegtransfersyntax));                      // write jpeg image stream                     outputcodec->setimage(jpegwriter, finalimage, jpegtransfersyntax, codecs::codec::veryhigh,                             "ob", 8, false, false, false, false);                      ++framescount;                 }              }             catch(datasetimagedoesntexist&)             {                     // ignore exception. thrown when reach                     //  end of images list                     exceptionsmanager::getmessage();             }              // images have been generated.             // should launch ffmpeg?             if(ffmpegflag >= 0 && framescount != 0)             {                     // list of arguments passed ffmpeg                     typedef std::list<std::string> toptionslist;                     toptionslist options;                      // first argument application's name                     options.push_back(argv[ffmpegflag + 1]);                      // calculate frames per second available tags                     double framespersecond(0);                     double frametime(loadeddataset->getdouble(0x0018, 0, 0x1063, 0));                     if(frametime > 0.1)                     {                             framespersecond = 1000 / frametime;                     }                     if(framespersecond < 0.1)                     {                             framespersecond = loadeddataset->getunsignedlong(0x0018, 0x0, 0x0040, 0x0);                     }                     if(framespersecond < 0.1)                     {                             framespersecond = loadeddataset->getunsignedlong(0x0008, 0x0, 0x2144, 0x0);                     }                      // add ffmpeg argument frames per second                     if(framespersecond > 0.1)                     {                             options.push_back("-r");                             std::ostringstream framerate;                             framerate << framespersecond;                             options.push_back(framerate.str());                     }                      // add ffmpeg argument input files                     options.push_back("-i");                     options.push_back(outputfilename + "_%d" + extension);                      // add ffmpeg argument number of frames                     options.push_back("-dframes");                     std::ostringstream framecount;                     framecount << (unsigned long)framescount;                     options.push_back(framecount.str());                      // add arguments specified when dicom2jpeg launched                     for(int copyarguments(ffmpegflag + 2); copyarguments < argc; ++copyarguments)                     {                             options.push_back(argv[copyarguments]);                     }                      // build arguments array                     std::auto_ptr<const char*> ffargv(new const char*[options.size() + 1]);                     size_t insertposition(0);                     for(toptionslist::iterator scanoptions(options.begin()); scanoptions != options.end(); ++scanoptions, ++insertposition)                     {                             ffargv.get()[insertposition] = (*scanoptions).c_str();                     }                     ffargv.get()[options.size()] = 0;                      // launch ffmpeg #ifdef puntoexe_windows         return (int)_spawnvp(_p_wait , argv[ffmpegflag + 1], ffargv.get()); #else         char *environment[] = {0};          pid_t process_id;         posix_spawnp (&process_id, argv[ffmpegflag + 1],                         0, 0, (char* const*)ffargv.get(), (char* const*)environment);         wait(0); #endif              }              return 0;      }     catch(...)     {             std::wcout << exceptionsmanager::getmessage();             return 1;     } } 

Comments

Popular posts from this blog

java - activate/deactivate sonar maven plugin by profile? -

python - TypeError: can only concatenate tuple (not "float") to tuple -

java - What is the difference between String. and String.this. ? -