To the ITK code path added support for handling a whole directory of dicom files.
This commit is contained in:
parent
11d7d98e79
commit
1d320d3ca1
@ -101,6 +101,29 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
|
|||||||
|
|
||||||
virtual const char* className() const { return "DICOM Image Reader/Writer"; }
|
virtual const char* className() const { return "DICOM Image Reader/Writer"; }
|
||||||
|
|
||||||
|
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 readObject(std::istream& fin,const osgDB::ReaderWriter::Options* options =NULL) const
|
virtual ReadResult readObject(std::istream& fin,const osgDB::ReaderWriter::Options* options =NULL) const
|
||||||
{
|
{
|
||||||
return readImage(fin, options);
|
return readImage(fin, options);
|
||||||
@ -217,10 +240,125 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
|
|||||||
std::string ext = osgDB::getLowerCaseFileExtension(file);
|
std::string ext = osgDB::getLowerCaseFileExtension(file);
|
||||||
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
|
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
|
||||||
|
|
||||||
std::string fileName = osgDB::findDataFile( file, options );
|
std::string fileName = file;
|
||||||
|
if (ext=="dicom")
|
||||||
|
{
|
||||||
|
fileName = osgDB::getNameLessExtension(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName = osgDB::findDataFile( fileName, options );
|
||||||
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
|
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
|
||||||
|
|
||||||
info()<<"Reading DICOM file "<<fileName<<std::endl;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef std::vector< osg::ref_ptr<osg::Image> > Images;
|
||||||
|
Images images;
|
||||||
|
for(Files::iterator itr = files.begin();
|
||||||
|
itr != files.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
ReadResult result = readSingleITKImage(*itr, options);
|
||||||
|
if (result.success()) images.push_back(result.getImage());
|
||||||
|
else return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (images.empty()) return ReadResult::ERROR_IN_READING_FILE;
|
||||||
|
|
||||||
|
if (images.size()==1) return images[0].get();
|
||||||
|
|
||||||
|
|
||||||
|
typedef std::map<float, osg::ref_ptr<osg::Image> > DistanceImageMap;
|
||||||
|
typedef std::map<osg::Vec3, DistanceImageMap> OrientationDistanceImageMap;
|
||||||
|
OrientationDistanceImageMap orientationDistanceImageMap;
|
||||||
|
for(Images::iterator itr = images.begin();
|
||||||
|
itr != images.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
osg::Image* image = itr->get();
|
||||||
|
osg::RefMatrix* matrix = dynamic_cast<osg::RefMatrix*>(image->getUserData());
|
||||||
|
if (matrix)
|
||||||
|
{
|
||||||
|
osg::Vec3 p0 = osg::Vec3(0.0, 0.0, 0.0) * (*matrix);
|
||||||
|
osg::Vec3 p1 = osg::Vec3(0.0, 0.0, 1.0) * (*matrix);
|
||||||
|
osg::Vec3 direction = p1-p0;
|
||||||
|
direction.normalize();
|
||||||
|
float distance = p0 * direction;
|
||||||
|
info()<<" direction="<<direction<<" distance = "<<distance<<std::endl;
|
||||||
|
orientationDistanceImageMap[direction][distance] = image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orientationDistanceImageMap.empty()) return ReadResult::ERROR_IN_READING_FILE;
|
||||||
|
|
||||||
|
DistanceImageMap& dim = orientationDistanceImageMap.begin()->second;
|
||||||
|
|
||||||
|
double totalThickness = dim.rbegin()->first - dim.begin()->first;
|
||||||
|
|
||||||
|
int width = 0;
|
||||||
|
int height = 0;
|
||||||
|
int depth = 0;
|
||||||
|
for(DistanceImageMap::iterator itr = dim.begin();
|
||||||
|
itr != dim.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
osg::Image* image = itr->second.get();
|
||||||
|
if (image->s() > width) width = image->s();
|
||||||
|
if (image->t() > height) height = image->t();
|
||||||
|
depth += image->r();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Image> image3D = new osg::Image;
|
||||||
|
image3D->allocateImage(width, height, depth, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1);
|
||||||
|
int r = 0;
|
||||||
|
for(DistanceImageMap::iterator itr = dim.begin();
|
||||||
|
itr != dim.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
osg::Image* image = itr->second.get();
|
||||||
|
osg::copyImage(image, 0,0,0, image->s(), image->t(), image->r(),
|
||||||
|
image3D.get(), 0, 0, r,
|
||||||
|
false);
|
||||||
|
r += image->r();
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Image* firstImage = dim.begin()->second.get();
|
||||||
|
osg::RefMatrix* matrix = dynamic_cast<osg::RefMatrix*>(firstImage->getUserData());
|
||||||
|
if (matrix)
|
||||||
|
{
|
||||||
|
image3D->setUserData(
|
||||||
|
new osg::RefMatrix(osg::Matrix::scale(1.0,1.0,totalThickness) * (*matrix))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return image3D.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ReadResult readSingleITKImage(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
|
||||||
|
{
|
||||||
|
|
||||||
typedef unsigned short PixelType;
|
typedef unsigned short PixelType;
|
||||||
const unsigned int Dimension = 3;
|
const unsigned int Dimension = 3;
|
||||||
@ -354,28 +492,6 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const
|
||||||
|
Loading…
Reference in New Issue
Block a user