VTK判断dcm文件是否损坏
bool IsDicomFile(string filePath)
{
//返回值 0(no),1(yes)
//verify it is a valid DICOM file
bool bIsDicomFile = false;
FILE *fp = fopen( filePath.c_str(), "r" );
if ( fp ) {
char signature[DCM_MagicLen];
//#define DCM_MagicLen 4; #define DCM_PreambleLen 128 序言长度; #define SEEK_SET 0; #define DCM_Magic "DICM"
bIsDicomFile = fseek( fp, DCM_PreambleLen, SEEK_SET ) >= 0
&& fread( signature, 1, DCM_MagicLen, fp ) == DCM_MagicLen && strncmp( signature, DCM_Magic, DCM_MagicLen ) == 0;
fclose(fp);
}
return bIsDicomFile;
}
bool isDICOMbad(string process ,const string fileDir)
{
/*功能:
* (1)根据形参,判断一个dicom文件是否损坏
* (2)如果传入是非dicom文件,不做判断,直接返回0
* 返回值:0(正常文件),1(文件有损坏)
*/
long int resultCode = 0;
if(IsDicomFile(fileDir))
{
resultCode = vtkDICOMParserCode(fileDir.c_str());
std::cout << getTimeZZ() << " [坏文件]: "<<fileDir<<" ["<<process<<"] "<<" errorCode:"<< resultCode << std::endl;
}
return resultCode;
}
void isDirDicomBad(const string dataDir,string process)
{
/*
* 功能:
* (1)检查某个目录(递归)下(形参:dataDir)的所有文件是否损坏
* (2)若某个文件损坏,则会自动移动到目录(BadFiledirPath)中去
*/
//递归获取指定目录的所有文件夹名称
QVector<QString> folderList;
GetAllFileFolder(QString(dataDir.c_str()), folderList);
folderList.append(QString(dataDir.c_str()));
for(auto subFolderList:folderList)
{
QList<QString> list = subFolderList.split("/");//subFolderList="/data/testa/00000001/st01"和"/data/testa/00000001/"
//以下是处理目录,使目录后面都有"/"
QString out_file_name = "/";
if(list.size() > 1)
{
for (int i = 0; i < list.size(); i++)
{
if(list[i].size() > 1)
out_file_name += list[i] + "/";
}
}
else
{
out_file_name = subFolderList + "/";
}
//遍历每个目录下的所有文件进行判断
std::vector<string> searchFileDir;
searchFileDir.clear();
searchFileDir = getDirFilesList(out_file_name.toStdString()); //searchFileDir[j]="/data/testa/99900001/st01/t9990000101mr.dcm"
for(int j = 0;j < searchFileDir.size();j++)
{
if(isDICOMbad(process,searchFileDir[j]))
{
MovefiletoDirectory(searchFileDir[j],BadFiledirPath);
continue;
}
}
}
}
//vtkDICOMParser获取错误码
long int vtkDICOMParserCode(const char *fileName_str)
{
vtkSmartPointer<vtkStringArray> files =
vtkSmartPointer<vtkStringArray>::New();
char fileName[128]; //the file max length
sprintf(fileName,fileName_str, 1);
files->InsertNextValue(fileName);
vtkSmartPointer<vtkDICOMDirectory> sorter =
vtkSmartPointer<vtkDICOMDirectory>::New();
sorter->RequirePixelDataOff();
sorter->SetScanDepth(0);
sorter->IgnoreDicomdirOn();
// sorter->SetFindQuery(query);
sorter->SetInputFileNames(files);
sorter->Update();
vtkDICOMCharacterSet charset;
vtkSmartPointer<vtkDICOMParser> parser =
vtkSmartPointer<vtkDICOMParser>::New();
parser->SetDefaultCharacterSet(charset);
vtkSmartPointer<vtkDICOMMetaData> data =
vtkSmartPointer<vtkDICOMMetaData>::New();
parser->SetMetaData(data);
int m = sorter->GetNumberOfStudies();
for (int j = 0; j < m; j++)
{
int k = sorter->GetFirstSeriesForStudy(j);
int kl = sorter->GetLastSeriesForStudy(j);
for (; k <= kl; k++)
{
vtkStringArray *a = sorter->GetFileNamesForSeries(k);
vtkIdType l = a->GetNumberOfValues();
std::string fname = a->GetValue(0);
// print the first and last filenames (sorted)
vtkSmartPointer<vtkSortFileNames> fsort =
vtkSmartPointer<vtkSortFileNames>::New();
fsort->NumericSortOn();
fsort->IgnoreCaseOn();
fsort->GroupingOff();
fsort->SetInputFileNames(a);
fsort->Update();
data->Clear();
data->SetNumberOfInstances(static_cast<int>(l));
unsigned int pixelDataVL = 0;
for (vtkIdType i = 0; i < l; i++)
{
fname = a->GetValue(i);
parser->SetIndex(i);
parser->SetFileName(fname.c_str());
parser->Update();
pixelDataVL = parser->GetPixelDataVL();
}
}
}
return parser->GetErrorCode ();
}
std::vector<string> getFileNameFromFilesList(std::vector<string> names)
{
/*
* 功能:从包含绝对路径的文件路径取出文件名出来
*/
std::vector<string> fileNames;
for(int i = 0; i < names.size(); i++)
{
string fileName = names[i];
fileName = fileName.substr(fileName.find_last_of("/") + 1);
fileNames.push_back(fileName);
}
return fileNames;
}
std::vector<string> getDirFilesList(string dirName)
{
/*
* 功能:获取制定目录下所有文件的绝对路径(不递归)
*/
std::vector<string> vFiles;
cout << "[getDirFilesList:]dirName= " << dirName << endl;
DIR *pDir = opendir(dirName.c_str());//dirName= /home/nishome/lvjunrong/spmFile/PACS/Post/Pending/
if(pDir)
{
struct dirent *pDirEnt = NULL;
while(pDirEnt = readdir(pDir))
{
string dirEntName = pDirEnt->d_name;//dirEntName= m20200327165341dcm/m20200327165341png
if(!IsDirectory(dirName + dirEntName))
{
vFiles.push_back(dirName + dirEntName);
}
}
closedir(pDir);
}
return vFiles;
}
void GetAllFileFolder(QString dirPath, QVector<QString> &folderList)
{
/*
* 功能:获取文件夹下的所有文件夹绝对路径(递归)
*/
QDir dir(dirPath);
dir.setFilter(QDir::Dirs);
foreach(QFileInfo fullDir, dir.entryInfoList())
{
if(fullDir.fileName() == "." || fullDir.fileName() == "..") continue;
folderList.push_back(fullDir.absoluteFilePath());
GetAllFileFolder(fullDir.absoluteFilePath(), folderList);
}
return ;
}
//将文件移动到目标文件夹下
void MovefiletoDirectory(const string Srcfile ,const string desPath)
{
if (FileExists( Srcfile) && FileExists(desPath))
{
string mvFile = "mv -f " + Srcfile + " " + desPath;
cout << getTimeZZ() << " [移动文件]:mv " << Srcfile << " to " << desPath << endl;
bool moveCmdResult = checkShellCm(mvFile.c_str());
if(moveCmdResult == 0)
cout << "移动文件:" << Srcfile << "到目录:" << desPath << "成功" <<endl;
else
{
cout << "移动文件:" << Srcfile << "到目录:" << desPath << "失败" << endl;
return;
}
}
}
检测损坏dcm文件
最新推荐文章于 2024-01-31 09:16:11 发布