修改、删除dicom图像tag信息

3 篇文章 0 订阅
1 篇文章 0 订阅

修改、删除dicom图像tag信息

描述

dicom图像文件头保存了大量患者、设备和图像等信息。如下图
在这里插入图片描述

其中设计部分隐私信息,可能需要删除或者修改。
本demo用于 清除指定dicom文件夹中序列文件的部分tag信息。

修改后tag信息如下图:
在这里插入图片描述

修改单个文件

以下给出修改单个文件的源码,序列文件先获取文件夹中文件名称,反复调用修改单个文件的修改tag信息即可。删除tag信息将对应的tag值设置为空字符串 “” 即可。

可通过外部设置的map一次性设置多个<tag,tagValue> 键值对,也可一次只修改一个。设置了输出文件名,则修改的图像将保存到指定的输出文件中,否则将直接覆盖源文件(慎用)。

头文件

//DicomSingleFileTagUpdater.h
#ifndef DICOMSINGLEFILETAGUPDATER_H
#define DICOMSINGLEFILETAGUPDATER_H

#include <map>
#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>
#include <itkGDCMImageIO.h>
#include <itkMetaDataObject.h>
#include <itkGDCMImageIOFactory.h>

class DicomSingleFileTagUpdater
{
public:
    DicomSingleFileTagUpdater();
    ~DicomSingleFileTagUpdater() = default;

private:

    using DicomPixelType = signed short;
    using ItkDicomImage2D = itk::Image<DicomPixelType, 2U>;
    using ItkDicomImageData2D = ItkDicomImage2D*;
    using ItkDictionaryType = itk::MetaDataDictionary;
    using ItkDicomImageIO = itk::GDCMImageIO;

    using ReaderType = itk::ImageFileReader<ItkDicomImage2D>;
    using WriterType = itk::ImageFileWriter<ItkDicomImage2D>;

public:
    void setInputFileName(const std::string& fileName);

    /** Function changeTagMetaDatas will excute befor changeATagMetaData, which means 
      * if they change a tag vaule meanwhile, the output tag value will be identified with 
      * changeATagMetaData function. */
    void changeTagMetaDatas(const std::map<std::string,std::string>& keyValueMap);

    /** This function can be called repeatedly.
      * If this function change the same tag for many times ,
      * the tag value will be identified with the last set one.
      */
    void changeATagMetaData(const std::string& tagKey, const std::string& tagValue);

    /** If this function dose not be called , the output name will be
    * set as the input file name. Which means the input file will 
    * be replaced by the output file.
    */
    void setOutputFileName(const std::string& outFileName);

    bool update(); 

private:
    DicomSingleFileTagUpdater(const DicomSingleFileTagUpdater&) = delete;
    DicomSingleFileTagUpdater& operator = (const DicomSingleFileTagUpdater&) = delete;

    bool updateATagMetaData(const std::string& tagKey, const std::string& tagValue);
    bool readTheImage();
    bool writeTheImage();

    ReaderType::Pointer m_reader;
    WriterType::Pointer m_writer;
    ItkDicomImageIO::Pointer m_dicomIO;
    std::string m_dicomFileName;
    std::string m_outPutFileName;
    bool m_isOutputFileNameBeSet;

    std::map<std::string, std::string> m_wholeTagMap;
    std::map<std::string, std::string> m_singleAddedTagMap;

    ItkDicomImageData2D m_itkImageData;
};

#endif


源文件

//DicomSingleFileTagUpdater.cpp
#include "DicomSingleFileTagUpdater.h"

DicomSingleFileTagUpdater::DicomSingleFileTagUpdater()
    : m_dicomFileName("")
    , m_reader(ReaderType::New())
    , m_writer(WriterType::New())
    , m_dicomIO(ItkDicomImageIO::New())
    , m_outPutFileName("")
    , m_isOutputFileNameBeSet(false)
    , m_wholeTagMap()
    , m_singleAddedTagMap()
    , m_itkImageData(nullptr)
{
    itk::GDCMImageIOFactory::RegisterOneFactory();
}

void DicomSingleFileTagUpdater::setInputFileName(
    const std::string& fileName)
{
    m_dicomFileName = fileName;
}

void DicomSingleFileTagUpdater::changeATagMetaData(
    const std::string& tagKey, const std::string& tagValue)
{
    m_singleAddedTagMap[tagKey] = tagValue;
}

void DicomSingleFileTagUpdater::changeTagMetaDatas(
    const std::map<std::string, std::string>& keyValueMap)
{
    m_wholeTagMap = keyValueMap;
}

void DicomSingleFileTagUpdater::setOutputFileName(
    const std::string& outFileName)
{
    m_outPutFileName = outFileName;
    m_isOutputFileNameBeSet = true;
}

bool DicomSingleFileTagUpdater::update()
{
    if(!readTheImage())
    {
        return false;
    }
    for (const auto& i : m_wholeTagMap)
    {
        updateATagMetaData(i.first, i.second);
    }
    for (const auto& i : m_singleAddedTagMap)
    {
        updateATagMetaData(i.first, i.second);
    }

    if (!writeTheImage())
    {
        return false;
    }
    return true;
}

bool DicomSingleFileTagUpdater::updateATagMetaData(
    const std::string& tagKey, const std::string& tagValue)
{
    if (!m_itkImageData)
    {
        std::cout << "ITK image data is invalid." << std::endl;
        return false;
    }
    std::string value;
    itk::EncapsulateMetaData<std::string>(
        m_itkImageData->GetMetaDataDictionary(), tagKey, tagValue);

    return true;
}

bool DicomSingleFileTagUpdater::readTheImage()
{
    m_itkImageData = nullptr;
    m_reader->SetFileName(m_dicomFileName);
 
    try 
    {
        m_reader->Update();
    }
    catch (const std::exception& e)
    {
        std::cout << e.what() << std::endl;
        return false;
    }

    m_itkImageData = m_reader->GetOutput();
    return true;
}

bool DicomSingleFileTagUpdater::writeTheImage()
{
    
    m_writer->SetImageIO(m_dicomIO);
    m_writer->SetInput(m_reader->GetOutput());
   
    if (m_isOutputFileNameBeSet)
    {
        m_writer->SetFileName(m_outPutFileName);
    }
    else
    {
        m_writer->SetFileName(m_reader->GetFileName());
    }

    try
    {
        m_writer->Update();
    }
    catch (const std::exception& e)
    {
        std::cout<<e.what()<<std::endl;
        return false;
    }
    return true;
}


测试文件

#include "DicomSingleFileTagUpdater.h"
#include <map>
//#include "importITKLib5_1.h" //import itk library

int main()
{
    std::map<std::string, std::string> keyValueMap;
    keyValueMap["0010|0010"] = "xuehanhan";
    keyValueMap["0008|0060"] = "ddr";
    keyValueMap["0008|0080"] = "yihuahuahau"; //change the tag value
    keyValueMap["0008|0030"] = "";//delete the tag value

   DicomSingleFileTagUpdater singleUpdater;
    		  singleUpdater.setInputFileName("raw_dicom1/1.3.12.2.1107.5.12.9.23114.30000020090913124560900000344.dcm");
    singleUpdater.setOutputFileName("outPut.dcm");
    singleUpdater.changeTagMetaDatas(keyValueMap);
    singleUpdater.changeATagMetaData("0010|0010", "zzzz");
    try
    {
        singleUpdater.update();
    }
    catch (const std::exception& e)
    {
        std::cout<<e.what()<<std::endl;
    }
     return 0;
}

序列文件tag信息一次性修改和清除的源码和测试,见附件。

https://download.csdn.net/download/assjaa/19960734

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值