how can i load 4d medical image of type nifti?
how can i load 3d or 4d medical image of type nifti (.nii) in c++??
how can i load 3d or 4d medical image of type nifti (.nii) in c++??
The following code reads the .nii header and then the .nii body. It writes PNG images. Make sure that you mark this answer as correct if you find that it works for you. It handles input files of dimensions up to 7.
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include <strstream>
using namespace std;
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
int main(void)
{
// https://brainder.org/2012/09/23/the-nifti-file-format/
ifstream infile("example_func.nii", std::ios::binary);
if (infile.fail())
{
cout << "Could not read file example_func.nii" << endl;
return 0;
}
size_t bytes_read = 0;
cout << "Reading header" << endl;
int sizeof_header;
infile.read(reinterpret_cast<char*>(&sizeof_header), sizeof(sizeof_header));
bytes_read += infile.gcount();
if (sizeof_header != 348)
{
cout << "Invalid header size: should be 348 bytes" << endl;
return -1;
}
char data_type[10];
infile.read(reinterpret_cast<char*>(&data_type), sizeof(data_type));
bytes_read += infile.gcount();
char db_name[18];
infile.read(reinterpret_cast<char*>(&db_name), sizeof(db_name));
bytes_read += infile.gcount();
int extents;
infile.read(reinterpret_cast<char*>(&extents), sizeof(extents));
bytes_read += infile.gcount();
short session_error;
infile.read(reinterpret_cast<char*>(&session_error), sizeof(session_error));
bytes_read += infile.gcount();
char regular;
infile.read(reinterpret_cast<char*>(®ular), sizeof(regular));
bytes_read += infile.gcount();
char dim_info;
infile.read(reinterpret_cast<char*>(&dim_info), sizeof(dim_info));
bytes_read += infile.gcount();
short dim[8];
infile.read(reinterpret_cast<char*>(&dim), sizeof(dim));
bytes_read += infile.gcount();
cout << dim[0] << " dimensions" << endl;
cout << "Dim 1: " << dim[1] << endl;
cout << "Dim 2: " << dim[2] << endl;
cout << "Dim 3: " << dim[3] << endl;
cout << "Dim 4: " << dim[4] << endl;
cout << "Dim 5: " << dim[5] << endl;
cout << "Dim 6: " << dim[6] << endl;
cout << "Dim 7: " << dim[7] << endl;
float intent_p1;
infile.read(reinterpret_cast<char*>(&intent_p1), sizeof(intent_p1));
bytes_read += infile.gcount();
float intent_p2;
infile.read(reinterpret_cast<char*>(&intent_p2), sizeof(intent_p2));
bytes_read += infile.gcount();
float intent_p3;
infile.read(reinterpret_cast<char*>(&intent_p3), sizeof(intent_p3));
bytes_read += infile.gcount();
short intent_code;
infile.read(reinterpret_cast<char*>(&intent_code), sizeof(intent_code));
bytes_read += infile.gcount();
short datatype;
infile.read(reinterpret_cast<char*>(&datatype), sizeof(datatype));
bytes_read += infile.gcount();
if (datatype != 16)
{
cout << "Data type must be float" << endl;
return -1;
}
else
{
cout << "Data type: float" << endl;
}
short bitpix;
infile.read(reinterpret_cast<char*>(&bitpix), sizeof(bitpix));
bytes_read += infile.gcount();
if (bitpix != 32)
{
cout << "Bits per pixel must be 32-bit" << endl;
return -1;
}
else
{
cout << "Bits per pixel: " << bitpix << endl;
}
short slice_start;
infile.read(reinterpret_cast<char*>(&slice_start), sizeof(slice_start));
bytes_read += infile.gcount();
float pixdim[8];
infile.read(reinterpret_cast<char*>(&pixdim), sizeof(pixdim));
bytes_read += infile.gcount();
float vox_offset;
infile.read(reinterpret_cast<char*>(&vox_offset), sizeof(vox_offset));
bytes_read += infile.gcount();
float scl_slope;
infile.read(reinterpret_cast<char*>(&scl_slope), sizeof(scl_slope));
bytes_read += infile.gcount();
float scl_inter;
infile.read(reinterpret_cast<char*>(&scl_inter), sizeof(scl_inter));
bytes_read += infile.gcount();
short slice_end;
infile.read(reinterpret_cast<char*>(&slice_end), sizeof(slice_end));
bytes_read += infile.gcount();
char slice_code;
infile.read(reinterpret_cast<char*>(&slice_code), sizeof(slice_code));
bytes_read += infile.gcount();
char xyzt_units ...
(more)Asked: 2017-11-26 08:13:24 -0600
Seen: 2,208 times
Last updated: Nov 28 '17
OpenCV DescriptorMatcher matches
Conversion between IplImage and MxArray
Video On Label OpenCV Qt :: hide cvNamedWindows
Problems using the math.h class with OpenCV (c++, VS2012)
Remove buttons from their background so I can re-use button image
Classification of object from a video/Image ( human, animals, others(cars etc.,))
How to reduce false positives for face detection
Area of a single pixel object in OpenCV
build problems for android_binary_package - Eclipse Indigo, Ubuntu 12.04
Have you try to search on github ?
Can you spare some sample .nii files?
Here's another link found on GitHub: https://github.com/glaivesoft/biomedi...
It doesn't help when the government's implementation and sample files are offline for some unknown reason: https://nifti.nimh.nih.gov/nifti-1
I found these things by googling for "nifti nii".
This is a great URL, describing the .nii format: https://brainder.org/2012/09/23/the-n...
Do a search on that page for "Image dimensions". That part of the file header documentation tells you how many dimensions, as well as the size of each dimension in terms of pixels/voxels. That's all you need to know in order to successfully read in a .nii file. Please provide a sample .nii file, and I'll come up with a sample code on how to read and write a 3D or 4D .nii file.
Thanks for your effor i will check this out. and for sample this is 3d https://www.mediafire.com/file/bfxx0k...
Yes, I see now that it's 3D data, where the x and y size is 64 and the z size is 21, and the data are 32-bit floats. Thanks for the sample. I'll be working on it today.
@AhmedSh3ban Have you considered using something like Marching Cubes to convert the 3D data's isosurface into a triangle mesh?
One thing I noticed about the sample .nii files gotten from https://nifti.nimh.nih.gov/nifti-1 is that they use a different endianness than that used by Intel CPUs running Windows or Mac OS X. This causes havoc when you try to read them using the code given in the answer below on Windows or Mac OS X. One could go through the process of converting everything from one endianness to the other endianness, but it would be a royal pain. I figured this all out by opening the sample .nii files in a hex editor -- the first four bytes should encode the value 348 (I used Windows calculator in programmer mode to do the conversion from hexadecimal to decimal), but instead the bytes are reversed in order, and so encodes some unacceptably gigantic number.