[vtkusers] Urgent: vtkImageActor not rendering

David Gobbi david.gobbi at gmail.com
Wed Jul 30 22:33:43 EDT 2014


Did you forget imgFlip->Update()?

On Wed, Jul 30, 2014 at 5:02 PM, Citizen Snips <amb2189 at rit.edu> wrote:
> I'm currently stuck upon an issue with a deadline in a week and I could
> really use some assistance. I implemented, initially in Python now ported to
> C++, a program to display two side-by-side renders of a model overlayed on
> two webcam feeds. In Python, this was working wonderfully. The video filled
> the entire viewport on each side and the models rendered perfectly. However,
> now that I'm in C++, the videos do not render and I cannot figure out why.
>
> To first detail my class structure, I have written a vtk3DRender class that
> utilizes a vtkCallbackCommand to call a non-member function TimerCallback.
> The trigger for this callback is a timer attached to the
> vtkRenderWindowInteractor I'm using. All render elements are private members
> of the vtk3DRender object. All configuration of render elements is done in
> the constructor.
>
> I'm acquiring the video using OpenCV to obtain a cv::Mat in TimerCallback
> which I then use as the c array to pass to a vtkImageImport. This
> vtkImageImport then passes its output to my vtkImageActor through a
> vtkImageFlip. In Python this worked great. However, now I'm just getting
> black in the background where there should be my webcam feed.
>
> Here's the relevant code:
>
> TimerCallback function:
>
> void TimerCallback(vtkObject* caller, long unsigned int eventId, void*
> clientData, void* callData)
> {
>         // Set up reference to vtk3DRender object
>         vtk3DRender* v3DR       =
> reinterpret_cast<vtk3DRender*>(clientData);
>
>         // Configure frame acquisition
>         Mat frameL;
>         v3DR->webcamL.read(frameL);
>         if (frameL.empty())
>                 return;
>         //cvtColor(frameL, frameL, CV_BGR2RGB);
>
>         // Pass frame data to pipeline and set modification flag
>         v3DR->imgPort->SetImportVoidPointer(frameL.data);
>         v3DR->imgPort->Modified();
>         v3DR->imgPort->Update();
>
>         // Set and print output positions of cams
>         v3DR->camR->SetPosition(xyz[cur], xyz[cur+1], xyz[cur+2]);
>         v3DR->camL->SetPosition(xyz[cur]+40, xyz[cur+1], xyz[cur+2]);
>         cur+=3;
>
>         // Rerender
>         v3DR->iren->Render();
> }
>
>
> Related code within initializer (Anything with suffix ___BGL is related to
> left webcam renderer and ___BGR is to right):
> {
>         ...
>         //Initialize left webcam (Right not yet implemented)
>         webcamL = VideoCapture(0);
>         Mat tmp;
>         webcamL.read(tmp);
>
>         // Initialize image importer for conversion from OpenCV format to
> VTK
>         imgPort         = vtkSmartPointer<vtkImageImport>::New();
>         imgPort->SetDataSpacing(1,1,1);
>         imgPort->SetDataOrigin(0,0,0);
>         imgPort->SetWholeExtent(0, tmp.size().width-1, 0,
> tmp.size().height-1, 0, 0);
>         imgPort->SetDataExtentToWholeExtent();
>         imgPort->SetDataScalarTypeToUnsignedChar();
>         imgPort->SetNumberOfScalarComponents(tmp.channels());
>         imgPort->SetImportVoidPointer(tmp.data);
>         imgPort->Update();
>
>         // Initialize camera image inverter
>         imgFlip         = vtkSmartPointer<vtkImageFlip>::New();
>         imgFlip->SetInputData(imgPort->GetOutput());
>         imgFlip->SetFilteredAxis(1);
>
>         // Assign updated camera data to background actors
>         actorBGL->SetInputData(imgFlip->GetOutput());
>         actorBGR->SetInputData(imgFlip->GetOutput());
>
>         // Set image to fill screen
>         double* origin  = imgPort->GetOutput()->GetOrigin();
>         double* spacing = imgPort->GetOutput()->GetSpacing();
>         int* extent     = imgPort->GetOutput()->GetExtent();
>
>         double xc       = origin[0] + 0.5*(extent[0] +
> extent[1])*spacing[0];
>         double yc       = origin[1] + 0.5*(extent[2] +
> extent[3])*spacing[1];
>         double xd       = (extent[1] - extent[0] + 1)*spacing[0];
>         double yd       = (extent[3] - extent[2] + 1)*spacing[1];
>         double d        = camBGL->GetDistance();
>         camBGL->SetParallelScale(0.5*yd);
>         camBGL->SetFocalPoint(xc,yc,0.0);
>         camBGL->SetPosition(xc,yc,d);
>         camBGR->SetParallelScale(0.5*yd);
>         camBGR->SetFocalPoint(xc,yc,0.0);
>         camBGR->SetPosition(xc,yc,d);
>
>         // Begin rendering
>         renWin->Render();
>         iren->Initialize();
>
>         cbc = vtkSmartPointer<vtkCallbackCommand>::New();
>         functiontype func = &TimerCallback;
>         cbc->SetCallback(func);
>         cbc->SetClientData(this);
>         iren->AddObserver(vtkCommand::TimerEvent, cbc);
>         iren->CreateRepeatingTimer(50);
>         iren->Start();
> }
>
>
> Any ideas? I would be incredibly thankful as this deadline is really pushing
> me hard and I've spent a day on this problem already.


More information about the vtkusers mailing list