[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