• c++使用dcmtk读取dicom数据和获取tag值和图像值


    void getFileName(const char* path, char* file_name)
    {
        const char* lastSlash = strrchr(path, '\\');
        if (lastSlash != nullptr)
        {
            strcpy(file_name, lastSlash + 1);
        }
        else
        {
            strcpy(file_name, path);
        }
    }
    
    // char数组的路径转string的路径
    void charArrayPath2string(char char_array_path[MAX_PATH], std::string& string_path)
    {
        std::stringstream ss;
        ss << char_array_path;
        string_path = ss.str();
        ss.str("");
    }
    
    // start_index: 截取文件名字符串的开始位置
    // count: 截取字符串的个数
    void getSliceIndex(
        std::string& file_path, int& slice_index, const int start_index, const int count)
    {
        // 获取文件名
        char fileName[256];
        getFileName(file_path.c_str(), fileName);
        //std::cout << "fileName = " << fileName << std::endl;
    
        // char* => string
        std::string fileNameStr;
        charArrayPath2string(fileName, fileNameStr);
        //std::cout << "fileNameStr = " << fileNameStr << std::endl;
    
        // 截取index
        std::string indexStr = fileNameStr.substr(start_index, count);
        //show_msg_str(indexStr.c_str());
        //std::cout << "indexStr = " << indexStr << std::endl;
    
        // 转int
        slice_index = std::stoi(indexStr);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    char szPath[256];
    char szMsg[256];
    
    std::string MRIDir("G:\\qian_lie_xian\\MRI_test_experiment\\t2\\dicom");
    int nT2 = 0;
    OFList<OFString> fileList;
    OFStandard::searchDirectoryRecursively(MRIDir.c_str(), fileList, "");
    /*sprintf(szMsg, "cnt = %d\r\n", fileList.size());
    show_msg_str(szMsg);*/
    
    nT2 = fileList.size();
    
    mn_slicedata_MRI_t2 = nT2;
    
    int i = 0;
    for (auto it = fileList.begin(); it != fileList.end(); ++it)
    {
    	SLICE_DATA& sd = ms_slicedata_MRI_t2[i];
    
    	DcmFileFormat fileformat;
    	std::string filePath = (*it).c_str();
    	OFCondition status = fileformat.loadFile(filePath.c_str());
    	if (status.bad()) {
    		sprintf(szMsg, "Error: cannot read DICOM file:\r\n\t%s\r\n", (*it).c_str());
    		show_msg_str(szMsg);
    		continue;
    	}
    	DcmDataset* dataset = fileformat.getDataset();
    
    	/// hdr [ begin ] /
    	// index
    	getSliceIndex(filePath, sd.hdr.index, 9, 5);
    
    	// data size
    	Uint16 dataSize_w = 0;
    	if (dataset->findAndGetUint16(DCM_Columns, dataSize_w).good())
    	{
    		sd.hdr.data_size.x = dataSize_w;
    	}
    	else { show_msg_str("data_size.x not found.\r\n"); }
    	Uint16 dataSize_h = 0;
    	if (dataset->findAndGetUint16(DCM_Rows, dataSize_h).good())
    	{
    		sd.hdr.data_size.y = dataSize_h;
    	}
    	else { show_msg_str("data_size.y not found.\r\n"); }
    
    	// dataarray_size
    	sd.hdr.dataarray_size = dataSize_w * dataSize_h;
    
    	// voxel_size
    	OFString pixelSpacingStr;
    	double pixelSpacing[2];
    	if (dataset->findAndGetOFStringArray(DCM_PixelSpacing, pixelSpacingStr).good())
    	{
    		std::vector<std::string> values;
    		std::istringstream iss(pixelSpacingStr.c_str());
    		std::string value;
    		while (std::getline(iss, value, '\\')) {
    			values.push_back(value);
    		}
    
    		for (int i = 0; i < values.size(); ++i)
    		{
    			pixelSpacing[i] = std::stod(values[i]);
    		}
    
    		sd.hdr.voxel_size.x = pixelSpacing[0];
    		sd.hdr.voxel_size.y = pixelSpacing[1];
    	}
    	else {
    		show_msg_str("pixelSpacing not found.\r\n");
    	}
    	double thickNess = 0.0;
    	if (dataset->findAndGetFloat64(DCM_SliceThickness, thickNess).good())
    	{
    		sd.hdr.voxel_size.z = thickNess;
    	}
    	else { show_msg_str("thickNess not found.\r\n"); }
    
    	// data_origin
    	OFString dataOriginStr;
    	double dataOrigin[3];
    	if (dataset->findAndGetOFStringArray(DCM_ImagePositionPatient, dataOriginStr).good())
    	{
    		std::vector<std::string> values;
    		std::istringstream iss(dataOriginStr.c_str());
    		std::string value;
    		while (std::getline(iss, value, '\\')) {
    			values.push_back(value);
    
    		}
    
    		for (int i = 0; i < values.size(); ++i)
    		{
    			dataOrigin[i] = std::stod(values[i]);
    		}
    
    		sd.hdr.data_origin.x = dataOrigin[0];
    		sd.hdr.data_origin.y = dataOrigin[1];
    		sd.hdr.data_origin.z = dataOrigin[2];
    
    		// slice_location
    		sd.hdr.slice_location = dataOrigin[2];
    
    	}
    	else { show_msg_str("dataOrigin not found.\r\n"); }
    
    	// orient_0, orient_1
    	OFString orientationStr;
    	double orientation[6];
    	if (dataset->findAndGetOFStringArray(DCM_ImageOrientationPatient, orientationStr).good())
    	{
    		std::vector<std::string> values;
    		std::istringstream iss(orientationStr.c_str());
    		std::string value;
    		while (std::getline(iss, value, '\\')) {
    			values.push_back(value);
    
    		}
    
    		for (int i = 0; i < values.size(); ++i)
    		{
    			orientation[i] = std::stod(values[i]);
    		}
    
    		sd.hdr.orient_0.x = orientation[0];
    		sd.hdr.orient_0.y = orientation[1];
    		sd.hdr.orient_0.z = orientation[2];
    		sd.hdr.orient_1.x = orientation[3];
    		sd.hdr.orient_1.y = orientation[4];
    		sd.hdr.orient_1.z = orientation[5];
    	}
    	else { show_msg_str("orientation not found.\r\n"); }
    
    	// user_name
    	OFString patientName;
    	if (dataset->findAndGetOFString(DCM_PatientName, patientName).good())
    	{
    		strcpy(sd.hdr.user_name, patientName.c_str());
    
    		/*sprintf(szMsg, "user_name=%s\r\n", sd.hdr.user_name);
    		show_msg_str(szMsg);*/
    
    	}
    	else { show_msg_str("patientName not found.\r\n"); }
    
    	// user_id
    	OFString patientId;
    	if (dataset->findAndGetOFString(DCM_PatientID, patientId).good())
    	{
    		strcpy(sd.hdr.user_id, patientId.c_str());
    	}
    	else { show_msg_str("patientId not found.\r\n"); }
    	
    	// series_inst_uid
    	OFString seriesInstanceUid;
    	if (dataset->findAndGetOFString(DCM_SeriesInstanceUID, seriesInstanceUid).good())
    	{
    		strcpy(sd.hdr.series_inst_uid, seriesInstanceUid.c_str());
    	}
    	else { show_msg_str("seriesInstanceUid not found.\r\n"); }
    
    	//series_desc
    	OFString seriesDesc;
    	if (dataset->findAndGetOFString(DCM_SeriesDescription, seriesDesc).good())
    	{
    		strcpy(sd.hdr.series_desc, seriesDesc.c_str());
    	}
    	else { show_msg_str("series_desc not found.\r\n"); }
    
    	//ref_frame_uid
    	OFString refFrameUid;
    	if (dataset->findAndGetOFString(DCM_FrameOfReferenceUID, refFrameUid).good())
    	{
    		strcpy(sd.hdr.ref_frame_uid, refFrameUid.c_str());
    	}
    	else { show_msg_str("ref_frame_uid not found.\r\n"); }
    
    	// window_center
    	double windowCenter = 0.0;
    	if (dataset->findAndGetFloat64(DCM_WindowCenter, windowCenter).good())
    	{
    		sd.hdr.window_center = windowCenter;
    	}
    	else { show_msg_str("windowCenter not found.\r\n"); }
    
    	// window_width
    	double windowWidth = 0.0;
    	if (dataset->findAndGetFloat64(DCM_WindowWidth, windowWidth).good())
    	{
    		sd.hdr.window_width = windowWidth;
    	}
    	else { show_msg_str("windowWidth not found.\r\n"); }
    
    	// 图像数据
    	const Uint16* pixelData = nullptr;
    	unsigned long numPixels = 0;
    	status = dataset->findAndGetUint16Array(DCM_PixelData, pixelData, &numPixels);
    	if (status.bad())
    	{
    		sprintf(szMsg, "i = %d, cannot get pixelData\r\n", i);
    		show_msg_str(szMsg);
    	}
    	else {
    		/*sprintf(szMsg, "num_pixels = %d\r\n", numPixels);
    		show_msg_str(szMsg);*/
    	}
    
    	if (pixelData == nullptr) { show_msg_str("pixelData is nullptr\r\n"); }
    
    	sd.data_array_s32 = new s32[sd.hdr.data_size.x * sd.hdr.data_size.y];
    
    	cv::Mat img = cv::Mat::zeros(sd.hdr.data_size.y, sd.hdr.data_size.x, CV_8UC1);
    
    	int maxValue = INT_MIN, minValue = INT_MAX;
    	for (int i = 0; i < dataSize_w * dataSize_h; ++i)
    	{
    		if (pixelData[i] > maxValue) maxValue = pixelData[i];
    		if (pixelData[i] < minValue) minValue = pixelData[i];
    	}
    	
    	/*sprintf(szMsg, "maxValue=%d, minValue=%d\r\n", maxValue, minValue);
    	show_msg_str(szMsg);*/
    
    	for (int row = 0; row < dataSize_h; ++row)
    	{
    		uchar* rowPtr = img.ptr<uchar>(row);
    
    		for (int col = 0; col < dataSize_w; ++col)
    		{
    			int index = dataSize_w * row + col;
    			uchar value = (pixelData[index] - minValue)*1.0 / (maxValue - minValue) * 255;
    			rowPtr[col] = value;
    
    			*(sd.data_array_s32+index) = int(value);
    		}
    
    	}
    	//cv::imwrite("./mri_"+ std::to_string(sd.hdr.index)+".jpg", img);
    
    	i += 1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
  • 相关阅读:
    C#程序到底从哪里开始看,从Main函数开始,那么Main函数是什么?
    [RK3568 Android11]火焰图详解
    1523_AURIX TC275存储分布_上
    vue3.2学习笔记
    luffy-(7)
    第九章《字符串》第3节:String类对象的存储方式
    锂电回收行业硫酸镍溶液除硅
    统一监听Vue组件报错
    网络编程学习笔记❤️
    MySQL数据库
  • 原文地址:https://blog.csdn.net/sdhdsf132452/article/details/134457913