Domanda

I am trying to copy a vtkImageData* class to a cv::Mat structure [my goal is to read an MHD file into OpenCV].. The file is essentially a 3D Matrix so I want to get a vector containing all the slices of the volume. So far, I have come up with this code,

reader->SetFileName(INPUT_DATA_1.c_str());
reader->Update();
imageData_1 = reader->GetOutput();
extractVOI->SetInput(imageData_1);

int dims[3];
imageData_1->GetDimensions(dims);
extractVOI->SetVOI(0, dims[0], 0, dims[1], 75, 75); // Set it to z=75
extractVOI->GetOutput()->SetScalarTypeToSignedChar();
imageExport->SetInputConnection(extractVOI->GetOutputPort());
imageExport->Update();

cv::Mat cvMat_test(dims[0], dims[1], CV_8UC1, imageExport->GetPointerToData());

Although this is working, it is not giving me the expected output (which are highlighted below).. Any help regarding this matter would be very helpful..

Thanks in advance, Sarthak

Expected output,

expected_output

The output I am getting right now,

actual_output

EDIT: I realize that the images aren't the same size. This is because I have just posted a snapshot of the data from the viewer that I am using.. There is an example in the dropbox link given HERE. Hope this clarifies things a bit more..

TAGS: vtk opencv bridge, vtkopencv, vtk opencv integrate

È stato utile?

Soluzione

Okay, so the GetPointerToData() function or GetScalarPointer() function used directly on the vtkImageData class are not appropriate for allocation (at least not in a way I could figure out).. So, I devised another method,

reader->SetFileName(INPUT_DATA_1.c_str());
reader->Update();
imageData_1 = reader->GetOutput();
extractVOI->SetInput(imageData_1);

int dims[3];
imageData_1->GetDimensions(dims);
extractVOI->SetVOI(0, dims[0], 0, dims[1], 75, 75); // Set it to z=75
extractVOI->GetOutput()->SetScalarTypeToSignedChar();
cv::Mat cvMat_test(dims[0], dims[1], CV_8UC1);

for (int i=0; i<dims[0]; ++i) {
    for (int j=0; j<dims[1]; ++j) {
        cvMat_test.at<unsigned char>(cv::Point(j,i)) = *static_cast<unsigned char*>(extractVOI->GetOutput()->GetScalarPointer(i,j,vol_dim));
    }
}

I am guessing this method can be extended to include the entire volume pretty easily..

EDIT:

I extended my code to do conversions to and from vtkImageData and cv::Mat and/or cv::gpu::Mat.. I have uploaded to the code here as vtkOpenCVBridge.

Cheers.!

Altri suggerimenti

First, the images are not of the same size. Even if the data is not stored properly, at least width and height of the images should be the same. This means that dims[0] and dims[1] is not really height and width of the image.

Second, are you sure that the data in vtk image is stored as array of unsigned char? I got patterns similar to yours when I tried to store image of ints in image of unsigned chars.

Third, are you sure that your vtk image is continuous in memory (you are not providing step between following rows)?

I never worked with VTK library so my answer is just a guess...

I have come across similar issue, after spending enormous time, I realized that I have swapped the dimensions, height to width and otherwise. Reinstating the dimensions correctly did give me a better result. I haven't worked with VTK library, but i think you can recheck the dimensions declarations.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top