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);
}
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,c++,前端,开发语言)