BMP Reader

I havent used VTK in decades, so bear with me. It was a lot simpler C++ in the 90s! Or I am just too old!

Trying to read a series of BMP images into a volume and isosurface it. Somehow its seg faulting. So I want to look at the pixels in the individual BMP images. I can get the reader to work, but how do you go from the reader’s output to an ImageData object?

   -- krs

share your code.

Made some progress on getting the pixel data, but the values are incorrect (used a pnm reader):

vtkSmartPointer pnm_reader = vtkSmartPointer::New();
pnm_reader->SetFileName("…/…/ablation_data/vol1/tmp.pnm");
pnm_reader->SetDataByteOrderToLittleEndian();
pnm_reader->SetDataScalarTypeToUnsignedChar();

pnm_reader->Update();
vtkSmartPointer<vtkImageData> image =
        static_cast<vtkSmartPointer<vtkImageData>>(pnm_reader->GetOutput());

int dims[3];
image->GetDimensions(dims);
cout << "Dims:" << dims[0] << "," << dims[1] << "," << dims[2] << endl;

for (int k = 0; k < 10; k++) {
    int *val = (int *) image->GetScalarPointer(k, 0, 0);
    cout << "Val:" << (int) val[0] << "," << val[1] << "," << val[2] << endl;
}

Anything obviously incorrect in the above fragment? I should be getting values in the range of 0-255, but all values are much larger…

Hello, Kalpathi

First, please, edit your post by encolsing your code between two ```, one above the first line and another after the last line. By doing this, you won’t have the templates (those tag-like thingies such as vtkSmartPointer<vtkStructureGrid>) trimmed. So we can better read your code.

But the first suspicious line in your code is a static cast of a smart pointer. Generally you don’t do or need that.

cheers,

Paulo

Paul, thanks for the advice. Hopefully this can be copy/pasted by someone to test and helps debug my issue:

Here is the very simple pnm reader (I went to pnm) and trying to check the image pixel output:

#include <vtkPNMReader.h>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>


int main (int argc, char *argv[]) {

    vtkSmartPointer<vtkPNMReader> pnm_reader = 
                  vtkSmartPointer<vtkPNMReader>::New();
        pnm_reader->SetFileName("tmp.pnm");
        pnm_reader->SetDataByteOrderToLittleEndian();
        pnm_reader->SetDataScalarTypeToUnsignedChar();

        pnm_reader->Update();
    vtkSmartPointer<vtkImageData> image =  pnm_reader->GetOutput();

    int dims[3];
    image->GetDimensions(dims);
    cout << "Dims:" << dims[0] << "," << dims[1] << "," << dims[2] << endl;

    for (int k = 0; k < 10; k++) {
        int *val = (int *) image->GetScalarPointer(k, 0, 0);
        cout << "Val:" << (int) val[0] << "," << val[1] << "," << val[2] << endl;
    }

    return EXIT_SUCCESS;
}

But the output pixel values are way out of range. They should be in 0-255 range.

I suggest trying image->GetScalarComponentAsFloat( k, 0, 0, <number of component>). There is also GetScalarAsDouble(...) if you want to get the values as doubles.

So that works and gets me reasonable values. I am stil curious about why the GetScalarPointer () didnt work or what I was doing incorrectly.

Thanks.

GetScalarPointer() returns a void*. Thus, you have to know beforehand what is the underlying scalar type in the vtkImageData object. Perhaps casting it into int* is not an adequate cast. You could reverse back to using GetScalarPonter() and cast it to float* or double* and see which works instead of int*.

You could use GetScalarSize() to get the size of the scalar type in bytes. If it returns 4, scalars are float; 8 means double and 16 means long double.

Yeah, I did try casting to float* and try, but didnt help.

  Oh well, your suggestion is good enough for me to progress.. was

doing a sanity check on the reader… Thanks a bunch.

– krs

And double*?

Please, don’t forget to mark the answer of your choice as a solution so other people can skip straight to the sought answer.

Here is the program fragment for isolining from a BMP image… most of the issues were my learning curve after coming back to VTK after decades…

Tons of help from Paul Carvalho in answering my newbie questions! Thanks a ton.

int main(int, char*[])
{
    auto colors = vtkSmartPointer<vtkNamedColors>::New();
    auto renderer = vtkSmartPointer<vtkRenderer>::New();
    auto renWin = vtkSmartPointer<vtkRenderWindow>::New();
        renWin->AddRenderer(renderer);
    auto iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
        iren->SetRenderWindow(renWin);

  vtkSmartPointer<vtkBMPReader> bmp_reader = vtkSmartPointer<vtkBMPReader>::New();
        bmp_reader->SetFileName("example.bmp");
        bmp_reader->SetDataByteOrderToLittleEndian();
        bmp_reader->SetDataScalarTypeToFloat();
        bmp_reader->Update();


    auto contour = vtkSmartPointer<vtkMarchingSquares>::New();
        contour->SetInputConnection(bmp_reader->GetOutputPort());
        contour->SetValue(0, 30.0);

    auto volMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
        volMapper->SetInputConnection(contour->GetOutputPort());
        volMapper->ScalarVisibilityOff();
    auto volActor = vtkSmartPointer<vtkActor>::New();
        volActor->SetMapper(volMapper);
        volActor->GetProperty()->EdgeVisibilityOn();
        volActor->GetProperty()->SetColor(colors->GetColor3d("Salmon").GetData());
    renderer->AddActor(volActor);
    renderer->SetBackground(colors->GetColor3d("SlateGray").GetData());
    renWin->SetSize(512, 512);
    // interact with data
    renWin->Render();
    iren->Start();

    return EXIT_SUCCESS;
}

Well, according to yourself the solution was actually given by me (6th post). It is important to give credit to the people that spend their free time helping you as a way to stimulate more people to help.

My apologies, I just edited my solution post… Still getting
used to the mailing lists of this century! Different from the
news readers of the 90s…

  But yeah, I need to remember that in the future..  as I

definitely will have a lot more questions as I use VTK more and
more.

Big thanks for answering my questions so fast!

– krs

1 Like

You’re quite welcome! Feel free to ask more questions. But keep in mind that answers in open source communities often don’t come so fast, or even don’t come at all. So, if your business depend on fast responses, please consider purchasing services from Kitware: https://vtk.org/services/.