⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readerwriterdicom.cpp

📁 最新osg包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Released under the OSGPL license, as part of the OpenSceneGraph distribution.//// ReaderWriter for sgi's .rgb format.// specification can be found at http://local.wasp.uwa.edu.au/~pbourke/dataformats/sgirgb/sgiversion.html#include <osg/Image>#include <osg/Notify>#include <osg/Geode>#include <osg/GL>#include <osg/io_utils>#include <osgDB/FileNameUtils>#include <osgDB/FileUtils>#include <osgDB/Registry>#include <osgVolume/Volume>#include <osgVolume/Brick>#include <osgVolume/ImageUtils>#ifdef  USE_DCMTK    #define HAVE_CONFIG_H    #include <dcmtk/config/osconfig.h>     #include <dcmtk/dcmdata/dcfilefo.h>    #include <dcmtk/dcmdata/dcdeftag.h>    #include <dcmtk/dcmimgle/dcmimage.h>#endif#ifdef USE_ITK    #include <itkImageFileReader.h>    #include <itkImageFileWriter.h>    #include <itkImage.h>    #include <itkImageRegionConstIterator.h>    #include <itkMetaDataDictionary.h>    #include <itkMetaDataObject.h>    #include <itkGDCMImageIO.h>#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <memory>class ReaderWriterDICOM : public osgDB::ReaderWriter{    public:            ReaderWriterDICOM()        {            supportsExtension("mag","dicom image format");            supportsExtension("ph","dicom image format");            supportsExtension("ima","dicom image format");            supportsExtension("dic","dicom image format");            supportsExtension("dcm","dicom image format");            supportsExtension("dicom","dicom image format");            // supportsExtension("*","dicom image format");        }        std::ostream& warning() const { return osg::notify(osg::WARN); }        std::ostream& notice() const { return osg::notify(osg::NOTICE); }        std::ostream& info() const { return osg::notify(osg::NOTICE); }                template<typename T>        T* readData(std::istream& fin, unsigned int length, unsigned int& numComponents) const        {            numComponents = length/sizeof(T);            T* data = new T[numComponents];            fin.read((char*)data, numComponents*sizeof(T));                        // read over any padding            length -= numComponents*sizeof(T);            while(fin && length>0) { fin.get(); --length; }                        return data;        }        template<typename T>        void printData(std::ostream& out, T* data, unsigned int numComponents) const        {            if (sizeof(T)==1)            {                for(unsigned int i=0; i<numComponents; ++i)                {                    if (data[i]>32) out<<data[i];                    else out<<".";                }            }            else             {                                for(unsigned int i=0; i<numComponents; ++i)                {                    if (i==0) out<<data[i];                    else out<<", "<<data[i];                }            }        }            virtual const char* className() const { return "DICOM Image Reader/Writer"; }                virtual ReadResult readObject(std::istream& fin,const osgDB::ReaderWriter::Options* options =NULL) const        {            return readImage(fin, options);        }        virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const        {            return readImage(file, options);        }        virtual ReadResult readNode(std::istream& fin,const osgDB::ReaderWriter::Options* options =NULL) const        {            return readImage(fin, options);        }        virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const        {            ReadResult result = readImage(file, options);            if (!result.validImage()) return result;                        osg::ref_ptr<osgVolume::Volume> volume = new osgVolume::Volume;            osg::ref_ptr<osgVolume::Brick> brick = new osgVolume::Brick;            brick->setVolume(volume.get());            brick->setImage(result.getImage());            // get matrix providing size of texels (in mm)            osg::RefMatrix* matrix = dynamic_cast<osg::RefMatrix*>(result.getImage()->getUserData());                    if (matrix)            {                                        // scale up to provide scale of complete brick                osg::Vec3d scale(osg::Vec3(result.getImage()->s(),result.getImage()->t(), result.getImage()->r()));                matrix->postMultScale(scale);                brick->setLocator(matrix);                                result.getImage()->setUserData(0);                                notice()<<"Locator "<<*matrix<<std::endl;            }                        volume->addChild(brick.get());                                    return volume.release();        }        virtual ReadResult readImage(std::istream& fin,const osgDB::ReaderWriter::Options*) const        {            return 0;        }#ifdef USE_ITK        virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const        {            std::string ext = osgDB::getLowerCaseFileExtension(file);            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;            std::string fileName = osgDB::findDataFile( file, options );            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;            notice()<<"Reading DICOM file "<<fileName<<std::endl;            typedef unsigned short PixelType;            const unsigned int Dimension = 3;            typedef itk::Image< PixelType, Dimension > ImageType;            typedef itk::ImageFileReader< ImageType > ReaderType;            ReaderType::Pointer reader = ReaderType::New();            reader->SetFileName( fileName.c_str() );            typedef itk::GDCMImageIO           ImageIOType;            ImageIOType::Pointer gdcmImageIO = ImageIOType::New();            reader->SetImageIO( gdcmImageIO );            try            {                reader->Update();            }            catch (itk::ExceptionObject & e)            {                std::cerr << "exception in file reader " << std::endl;                std::cerr << e.GetDescription() << std::endl;                std::cerr << e.GetLocation() << std::endl;                return ReadResult::ERROR_IN_READING_FILE;            }                        ImageType::Pointer inputImage = reader->GetOutput();                        ImageType::RegionType region = inputImage->GetBufferedRegion();            ImageType::SizeType size = region.GetSize();            ImageType::IndexType start = region.GetIndex();                        //inputImage->GetSpacing();            //inputImage->GetOrigin();                        unsigned int width = size[0];            unsigned int height = size[1];            unsigned int depth = size[2];                        osg::RefMatrix* matrix = new osg::RefMatrix;                        notice()<<"width = "<<width<<" height = "<<height<<" depth = "<<depth<<std::endl;            for(unsigned int i=0; i<Dimension; ++i)            {                (*matrix)(i,i) = inputImage->GetSpacing()[i];                (*matrix)(3,i) = inputImage->GetOrigin()[i];            }                        osg::Image* image = new osg::Image;            image->allocateImage(width, height, depth, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1);            unsigned char* data = image->data();                        typedef itk::ImageRegionConstIterator< ImageType > IteratorType;            IteratorType it(inputImage, region);                        it.GoToBegin();            while (!it.IsAtEnd())            {                *data = it.Get();                ++data;                ++it;            }                        image->setUserData(matrix);            return image;        }#endif#ifdef USE_DCMTK        void convertPixelTypes(const DiPixel* pixelData,                                EP_Representation& pixelRep, unsigned int& numPlanes,                                GLenum& dataType, GLenum& pixelFormat, unsigned int& pixelSize) const        {            dataType = GL_UNSIGNED_BYTE;            pixelRep = pixelData->getRepresentation();            switch(pixelRep)            {                case(EPR_Uint8):                    dataType = GL_UNSIGNED_BYTE;                    pixelSize = 1;                    break;                case(EPR_Sint8):                    dataType = GL_BYTE;                    pixelSize = 1;                    break;                case(EPR_Uint16):                    dataType = GL_UNSIGNED_SHORT;                    pixelSize = 2;                    break;                case(EPR_Sint16):                    dataType = GL_SHORT;                    pixelSize = 2;                    break;                case(EPR_Uint32):                    dataType = GL_UNSIGNED_INT;                    pixelSize = 4;                    break;                case(EPR_Sint32):                    dataType = GL_INT;                    pixelSize = 4;                    break;                default:                    dataType = 0;                    break;            }            pixelFormat = GL_INTENSITY;            numPlanes = pixelData->getPlanes();            switch(numPlanes)            {                case(1):                    pixelFormat = GL_LUMINANCE;                    break;                case(2):                    pixelFormat = GL_LUMINANCE_ALPHA;                    pixelSize *= 2;                    break;                case(3):                    pixelFormat = GL_RGB;                    pixelSize *= 3;                    break;                case(4):                    pixelFormat = GL_RGBA;                    pixelSize *= 4;                    break;            }        }                typedef std::vector<std::string> Files;        bool getDicomFilesInDirectory(const std::string& path, Files& files) const        {            osgDB::DirectoryContents contents = osgDB::getDirectoryContents(path);            std::sort(contents.begin(), contents.end());            for(osgDB::DirectoryContents::iterator itr = contents.begin();                itr != contents.end();                ++itr)            {                std::string localFile = path + "/" + *itr;                info()<<"contents = "<<localFile<<std::endl;                if (acceptsExtension(osgDB::getLowerCaseFileExtension(localFile)) &&                    osgDB::fileType(localFile) == osgDB::REGULAR_FILE)                {                    files.push_back(localFile);                }            }                        return !files.empty();        }        virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const        {            notice()<<"Reading DICOM file "<<file<<" using DCMTK"<<std::endl;            std::string ext = osgDB::getLowerCaseFileExtension(file);            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;                        std::string fileName = file;            if (ext=="dicom")            {                fileName = osgDB::getNameLessExtension(file);            }            fileName = osgDB::findDataFile( fileName, options );            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;            Files files;                        osgDB::FileType fileType = osgDB::fileType(fileName);            if (fileType==osgDB::DIRECTORY)            {                getDicomFilesInDirectory(fileName, files);            }            else            {#if 1                files.push_back(fileName);#else                                            if (!getDicomFilesInDirectory(osgDB::getFilePath(fileName), files))                {                    files.push_back(fileName);                }#endif                        }            if (files.empty())            {                return ReadResult::FILE_NOT_FOUND;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -