赞
踩
- #include <itkImage.h>
- #include <itkGDCMImageIO.h>
- #include <itkImageSeriesReader.h>
- #include <itkGDCMSeriesFileNames.h>
- #include <itkImageToVTKImageFilter.h>
-
- #include <vtkCamera.h>
- #include <vtkProperty.h>
- #include <vtkMatrix4x4.h>
- #include <vtkImageData.h>
- #include <vtkPNGWriter.h>
- #include <vtkImageData.h>
- #include <vtkJPEGWriter.h>
- #include <vtkImageActor.h>
- #include <vtkLineSource.h>
- #include <vtkSmartPointer.h>
- #include <vtkImageViewer2.h>
- #include <vtkImageReslice.h>
- #include <vtkDataSetMapper.h>
- #include <vtkXMLImageDataWriter.h>
- #include <vtkInteractorStyleImage.h>
-
- #include <string>
- #include <vector>
- #include <cstdarg>
-
-
- #if defined(_WIN32)
- #include <io.h>
- #include <direct.h> // _mkdir
- #else
- #include <sys/stat.h> // stat
- #include <errno.h> // errno, ENOENT, EEXIST
- #include <stdio.h>
- #endif
-
- bool MakePath(const std::string& path)
- {
- #if defined(_WIN32)
- int ret = _mkdir(path.c_str());
- #else
- mode_t mode = 0755;
- int ret = mkdir(path.c_str(), mode);
- #endif
- if (ret == 0)
- return true;
-
- switch (errno)
- {
- case ENOENT:
- // parent didn't exist, try to create it
- {
- size_t pos = path.find_last_of('/');
- if (pos == std::string::npos)
- #if defined(_WIN32)
- pos = path.find_last_of('\\');
- if (pos == std::string::npos)
- #endif
- return false;
- if (!MakePath(path.substr(0, pos)))
- return false;
- }
- // now, try to create again
- #if defined(_WIN32)
- return 0 == _mkdir(path.c_str());
- #else
- return 0 == mkdir(path.c_str(), mode);
- #endif
-
- //case EEXIST:
- // // done!
- // return IsDirExist(path);
-
-
- default:
- return false;
- }
- }
-
-
- /**
- * @brief GetFileNames 利用寻找文件夹里所有dicom文件(跟后缀无关)
- * @param dicom_file_path 输入路径(文件)
- * @param file_names dicom_file_path同级文件所有dicom类型文件
- * @return
- */
- using FileNamesContainer = std::vector< std::string >;
- bool GetFileNames(const std::string &dicom_file_path,
- FileNamesContainer &file_names) {
- if (dicom_file_path.empty()) {
- return false;
- }
-
- //QFileInfo file_info(dicom_file_path);
- std::string extension = ".dcm";// file_info.path();
- std::string series_identifier;
- using NamesGeneratorType = itk::GDCMSeriesFileNames;
- using SeriesIdContainer = std::vector< std::string >;
- NamesGeneratorType::Pointer name_generator = NamesGeneratorType::New();
- name_generator->SetUseSeriesDetails(true);
- //name_generator->SetDirectory(extension.toLocal8Bit().data());
-
- std::string folder = dicom_file_path.substr(0, dicom_file_path.find_last_of("\\"));
- name_generator->SetDirectory(folder);
-
- const SeriesIdContainer &seriesUID = name_generator->GetSeriesUIDs();
- auto seriesItr = seriesUID.begin();
- auto seriesEnd = seriesUID.end();
- while (seriesItr != seriesEnd) {
- series_identifier = seriesItr->c_str();
- file_names = name_generator->GetFileNames(series_identifier);
- ++seriesItr;
- }
- return true;
- }
-
-
- /**
- * @brief ReadDicoms/ReadDicom 读取文件(3维/2维)
- */
- typedef signed short InputPixelType;
- typedef itk::Image< InputPixelType, 2 > InputImageType;
- typedef itk::Image< InputPixelType, 3 > InputImageTypes;
- bool ReadDicoms(const FileNamesContainer &file_names,
- InputImageTypes::Pointer &image) {
- typedef itk::ImageSeriesReader<InputImageTypes> ReaderType;
- using ImageIOType = itk::GDCMImageIO;
- ReaderType::Pointer reader = ReaderType::New();
- ImageIOType::Pointer dicomIO = ImageIOType::New();
- reader->SetImageIO(dicomIO);
- reader->SetFileNames(file_names);
- try {
- reader->Update();
- }
- catch (itk::ExceptionObject &) {
- return false;
- }
- image = reader->GetOutput();
- return true;
- }
- bool ReadDicom(const std::string &file_name,
- InputImageType::Pointer &image) {
- typedef itk::ImageFileReader<InputImageType> ReaderType;
- ReaderType::Pointer reader = ReaderType::New();
- typedef itk::GDCMImageIO ImageIOType;
- ImageIOType::Pointer gdcmImageIO = ImageIOType::New();
- reader->SetFileName(file_name);
- reader->SetImageIO(gdcmImageIO);
- try {
- reader->Update();
- }
- catch (itk::ExceptionObject &) {
- return false;
- }
- image = reader->GetOutput();
- return true;
- }
-
-
- void CopySingleFile(const std::string& input, const std::string& output)
- {
- #include <fstream>
- std::ifstream src(input, std::ios::binary);
- std::ofstream dst(output, std::ios::binary);
- dst << src.rdbuf();
- }
-
- inline std::string Trim(std::string& str)
- {
- str.erase(0, str.find_first_not_of(' ')); //prefixing spaces
- str.erase(str.find_last_not_of(' ') + 1); //surfixing spaces
- return str;
- }
-
-
-
- //missing string printf
- //this is safe and convenient but not exactly efficient
- inline std::string Format(const char* fmt, ...)
- {
- int size = 512;
- char* buffer = 0;
- buffer = new char[size];
- va_list vl;
- va_start(vl, fmt);
- int nsize = vsnprintf(buffer, size, fmt, vl);
- if (size <= nsize) { //fail delete buffer and try again
- delete[] buffer;
- buffer = 0;
- buffer = new char[nsize + 1]; //+1 for /0
- nsize = vsnprintf(buffer, size, fmt, vl);
- }
- std::string ret(buffer);
- va_end(vl);
- delete[] buffer;
- return ret;
- }
-
- /**
- * @brief CopyDicom 拷贝dicom到指定目录,根据Slice Location、Acquisition Number排序
- * @param dicom_path 输入路径
- * @param list 记录所有输出文件路径
- * @param out_paths 输出路径(拷贝)
- * @return
- */
- bool CopyDicom(const std::string &dicom_path,
- std::vector<std::string> &list,
- const std::string &out_paths) {
- // 读入dcm
- FileNamesContainer file_names;
- if (!GetFileNames(dicom_path, file_names)) {
- return false;
- }
- std::vector<std::string>::iterator the_iterator;
- for (the_iterator = file_names.begin(); the_iterator
- != file_names.end(); the_iterator++)
- {
- // 记录tags
- InputImageType::Pointer image = InputImageType::New();
- ReadDicom(the_iterator->c_str(), image);
- typedef itk::MetaDataDictionary DictionaryType;
- using MetaDataStringType = itk::MetaDataObject<std::string>;
- DictionaryType &dictionary = image->GetMetaDataDictionary();
- std::map<std::string, std::string> key_list;
- for (auto ite = dictionary.Begin(); ite != dictionary.End(); ++ite)
- {
- std::string id = (ite->first);
- itk::MetaDataObjectBase::Pointer entry = ite->second;
- MetaDataStringType::ConstPointer entry_value =
- dynamic_cast<const MetaDataStringType *>(ite->second.GetPointer());
- std::string key_string;
- itk::GDCMImageIO::GetLabelFromTag(id.c_str(), key_string);
- std::string key = (key_string);
- std::string value = (entry_value->GetMetaDataObjectValue());
- itk::EncapsulateMetaData<std::string>(dictionary, key_string, "value");
- key_list.insert(std::pair<std::string, std::string>(key, value));
- }
- // 根据Instance Number重命名拷贝文件
- std::string out_path = out_paths;// +key_list["Slice Location"];
- MakePath(out_path);
- // list << out_path;
- //(0020, 0013) IS 23 # 1, 2 Instance Number
- //std::string InstanceNumber = Format("%5d", atoi(Trim(key_list["Instance Number"]).c_str()));
-
- char str[7];
- snprintf(str, 7, "%04d", atoi(Trim(key_list["Instance Number"]).c_str()));
- out_path += "/" + std::string(str) + ".dcm";
- std::cout << out_path << "\n";
- CopySingleFile(the_iterator->c_str(), out_path);
- list.push_back(out_path);
- }
- return true;
- }
-
-
- /**
- * @brief GenerateVti 把输入路径里所有dcm写出为vti
- * @param path 输入dcm路径
- */
- void GenerateVti(std::vector<std::string> file_names)
- {
- vtkNew<vtkImageData> imagedata;
- // 读入dcm
- //FileNamesContainer file_names;
- InputImageTypes::Pointer input_image = InputImageTypes::New();
- //GetFileNames((path + "/1.dcm"), file_names);
-
- ReadDicoms(file_names, input_image);
- typedef itk::ImageToVTKImageFilter< InputImageTypes> itkTovtkFilterType;
- itkTovtkFilterType::Pointer itkTovtkImageFilter = itkTovtkFilterType::New();
- itkTovtkImageFilter->SetInput(input_image);
- itkTovtkImageFilter->Update();
- imagedata->DeepCopy(itkTovtkImageFilter->GetOutput());
- // 写出vti
- vtkNew<vtkXMLImageDataWriter> writer;
- writer->SetInputData(imagedata);
- writer->SetFileName("floor.vti");
- writer->Write();
- }
-
-
- int main(int, char *[])
- {
- std::string in_paths = "input/000001.dcm";
- std::string out_paths = "output/";
- std::vector<std::string> list;// 目标路径
- // 拷贝文件
- CopyDicom(in_paths, list, out_paths);
-
- // vti
- GenerateVti(list);
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。