extracting slice from 3D image

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

extracting slice from 3D image

Maarten
Hi all,

I have a 3d medical image and I would like to apply OpenCV algorithms to it. I managed to convert the image into a cv::Mat object, but have the impression that some algorithms (like cv::GaussianBlur or cv::SIFT) only work on 2d images.
How do I extract a slice from a cv::Mat?
I have tried:

cv::Mat image3d; // filled with image data
cv::Range ranges[3];
ranges[0] = cv::Range::all();
ranges[1] = cv::Range::all();
ranges[2] = cv::Range( 18, 19 );
cv::Mat slice = image3d(ranges);

But this still gives a 3d image (slice.dims = 3).
So I manually set:
slice.dims = 2;
slice.rows = slice.size[0];
slice.cols = slice.size[1];

This makes an algorithm like cv::GaussianBlur work, but the result is not correct. I would expect a smooth image, but I get unrecognizable noise. Looks like the image data is not correctly transfered.

Btw: when I load a 2d image, skip the slice extraction, the code works as expected.

Thanks - Maarten

Reply | Threaded
Open this post in threaded view
|

Re: extracting slice from 3D image

Maarten
Hi all,

I seem to have found a solution myself.
I am posting it in case someone else might have the same issue or someone can come up with a better solution.

Thanks - Maarten

static void extractZSliceOBL( const cv::Mat& image3d, const int z, cv::Mat& slice )
{
        // create the roi
        cv::Range ranges[3];
        ranges[0] = cv::Range::all();
        ranges[1] = cv::Range::all();
        ranges[2] = cv::Range( z, z+1 );
                       
        // get the roi from the image;
        // calling clone() makes sure the data is continuous
        slice = image3d(ranges).clone();

        // create a temporarily 2d image and copy its size
        // to make our image a real 2d image
        cv::Mat temp2d;
        temp2d.create( 2, &(image3d.size[0]), image3d.type() );
        slice.copySize( temp2d );
}

--- In [hidden email], "Maarten" <beekmaarten@...> wrote:

>
> Hi all,
>
> I have a 3d medical image and I would like to apply OpenCV algorithms to it. I managed to convert the image into a cv::Mat object, but have the impression that some algorithms (like cv::GaussianBlur or cv::SIFT) only work on 2d images.
> How do I extract a slice from a cv::Mat?
> I have tried:
>
> cv::Mat image3d; // filled with image data
> cv::Range ranges[3];
> ranges[0] = cv::Range::all();
> ranges[1] = cv::Range::all();
> ranges[2] = cv::Range( 18, 19 );
> cv::Mat slice = image3d(ranges);
>
> But this still gives a 3d image (slice.dims = 3).
> So I manually set:
> slice.dims = 2;
> slice.rows = slice.size[0];
> slice.cols = slice.size[1];
>
> This makes an algorithm like cv::GaussianBlur work, but the result is not correct. I would expect a smooth image, but I get unrecognizable noise. Looks like the image data is not correctly transfered.
>
> Btw: when I load a 2d image, skip the slice extraction, the code works as expected.
>
> Thanks - Maarten
>