My vtk version is 9.2 .When I perform the flipping function of mpr reconstruction, everything is normal before flipping, and after flipping, the image rotated by the camera becomes abnormal,I found that before flipping, rotating vtkPlaneSource will not affect the rotation of the image. However, after flipping, the rotation of vtkPlaneSource will double or reverse the rotation of my image. Here is my code. thank you.
#include "vtkSmartPointer.h"
#include "vtkCamera.h"
#include "vtkCellPicker.h"
#include "vtkCommand.h"
#include "vtkImageActor.h"
#include "vtkImageReslice.h"
#include "vtkInteractorStyleImage.h"
#include "vtkImageMapToColors.h"
#include "vtkImagePlaneWidget.h"
#include "vtkImageReader.h"
#include "vtkInteractorEventRecorder.h"
#include "vtkLookupTable.h"
#include "vtkOutlineFilter.h"
#include "vtkDICOMImageReader.h"
#include "vtkPolyDataMapper.h"
#include "vtkProperty.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkImageData.h"
#include "vtkPointData.h"
#include "vtkPlaneSource.h"
#include "vtkPlane.h"
#include "vtkResliceCursorActor.h"
#include "vtkResliceCursorPolyDataAlgorithm.h"
#include "vtkResliceCursor.h"
#include "vtkResliceCursorWidget.h"
#include "vtkResliceCursorLineRepresentation.h"
#include "vtkBiDimensionalWidget.h"
#include"vtkAutoInit.h"
#include"vtkAxesActor.h"
#include"vtkTransform.h"
#include"vtkTextActor.h"
#include"vtkProperty2D.h"
#include<vtkActor2D.h>
#include<vtkResliceImageViewer.h>
#include<vtkImageFlip.h>
#include"vtkAutoInit.h"
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkRenderingFreeType)
class myrep :public vtkResliceCursorLineRepresentation {
public:
static myrep* New()
{
return new myrep;
}
void SetResliceParameters(
double outputSpacingX, double outputSpacingY, int extentX, int extentY)override
{
vtkImageReslice* reslice = vtkImageReslice::SafeDownCast(this->Reslice);
if (reslice)
{
// Set the default color the minimum scalar value
double range[2];
vtkImageData::SafeDownCast(reslice->GetInput())->GetScalarRange(range);
reslice->SetBackgroundLevel(range[0]);
auto flip = vtkSmartPointer< vtkImageFlip>::New();
flip->SetFilteredAxis(1);
flip->SetInputConnection(reslice->GetOutputPort());
this->ColorMap->SetInputConnection(flip->GetOutputPort());
reslice->TransformInputSamplingOff();
reslice->AutoCropOutputOn();
reslice->SetResliceAxes(this->ResliceAxes);
reslice->SetOutputSpacing(outputSpacingX, outputSpacingY, 1);
reslice->SetOutputOrigin(0.5 * outputSpacingX, 0.5 * outputSpacingY, 0);
reslice->SetOutputExtent(0, extentX - 1, 0, extentY - 1, 0, 0);
}
}
};
class vtkResliceCursorCallback : public vtkCommand
{
public:
static vtkResliceCursorCallback* New()
{
return new vtkResliceCursorCallback;
}
void Execute(vtkObject* caller, unsigned long ev,
void* callData) override
{
if (ev == vtkResliceCursorWidget::WindowLevelEvent ||
ev == vtkCommand::WindowLevelEvent ||
ev == vtkResliceCursorWidget::ResliceThicknessChangedEvent)
{
// Render everything
for (int i = 0; i < 3; i++)
{
this->RCW[i]->Render();
}
this->IPW[0]->GetInteractor()->GetRenderWindow()->Render();
//return;
}
vtkResliceCursorWidget* rcw = dynamic_cast<
vtkResliceCursorWidget*>(caller);
if (rcw)
{
vtkResliceCursorLineRepresentation* rep = dynamic_cast<
vtkResliceCursorLineRepresentation*>(rcw->GetRepresentation());
double window[2];
rep->GetWindowLevel(window);
//同步的前提下才能实现
for (size_t i = 0; i < 3; i++)
{
RCW[i]->GetResliceCursorRepresentation()->SetWindowLevel(window[0], window[1]);
}
rep->GetResliceCursorActor()->GetCursorAlgorithm()->GetResliceCursor();
for (int i = 0; i < 3; i++)
{
vtkPlaneSource* ps = static_cast<vtkPlaneSource*>(
this->IPW[i]->GetPolyDataAlgorithm());
ps->SetOrigin(this->RCW[i]->GetResliceCursorRepresentation()->
GetPlaneSource()->GetOrigin());
ps->SetPoint1(this->RCW[i]->GetResliceCursorRepresentation()->
GetPlaneSource()->GetPoint1());
ps->SetPoint2(this->RCW[i]->GetResliceCursorRepresentation()->
GetPlaneSource()->GetPoint2());
// If the reslice plane has modified, update it on the 3D widget
this->IPW[i]->UpdatePlacement();
}
}
// Render everything
for (int i = 0; i < 3; i++)
{
this->RCW[i]->Render();
}
this->IPW[0]->GetInteractor()->GetRenderWindow()->Render();
}
vtkResliceCursorCallback() {}
vtkImagePlaneWidget* IPW[3];
vtkResliceCursorWidget* RCW[3];
vtkResliceImageViewer* RIW[3];
};
int main()
{
vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();
std::string dict = "C:\\Users\\12820\\Desktop\\DICOM参考数据\\CT-head\\1.25-240";
std::string dict1 = "C:\\Users\\12820\\source\\repos\\vtkProject\\vtkProject\\imaghe\\rt_ct";
reader->SetDirectoryName(dict1.c_str());
reader->Update();
int imageDims[3];
reader->GetOutput()->GetDimensions(imageDims);
vtkSmartPointer< vtkResliceImageViewer >riw[3];
vtkSmartPointer< vtkRenderWindow >renderWindow[3];
vtkSmartPointer< vtkRenderWindowInteractor >renderWindowInteractor[3];
vtkSmartPointer< vtkResliceCursor > resliceCursor = vtkSmartPointer< vtkResliceCursor >::New();
vtkSmartPointer< myrep > rep[3];
resliceCursor->SetCenter(reader->GetOutput()->GetCenter());
resliceCursor->SetImage(reader->GetOutput());
for (int i = 0; i < 3; i++)
{
riw[i] = vtkSmartPointer< vtkResliceImageViewer >::New();
rep[i] = vtkSmartPointer< myrep >::New();
renderWindowInteractor[i] = vtkSmartPointer< vtkRenderWindowInteractor >::New();
riw[i]->SetupInteractor(renderWindowInteractor[i]);
}
for (int i = 0; i < 3; i++)
{
riw[i]->GetResliceCursorWidget()->SetRepresentation(rep[i]);
riw[i]->SetResliceCursor(resliceCursor);
rep[i]->GetResliceCursorActor()->GetCursorAlgorithm()->SetReslicePlaneNormal(i);
rep[i]->GetResliceCursorActor()->GetCenterlineProperty(0)->SetRepresentationToWireframe();//代表12窗口竖线
rep[i]->GetResliceCursorActor()->GetCenterlineProperty(1)->SetRepresentationToWireframe();//0竖线,2横线
rep[i]->GetResliceCursorActor()->GetCenterlineProperty(2)->SetRepresentationToWireframe();//01横线
riw[i]->SetInputData(reader->GetOutput());
riw[i]->GetRenderWindow()->SetSize(500, 500);
riw[i]->GetRenderWindow()->SetPosition(800 + i * 500, 500);
if (i == 2)
riw[i]->GetRenderWindow()->SetPosition(800, 0);
riw[i]->SetSliceOrientation(1);
riw[i]->SetSliceOrientation(i);
}
for (int i = 0; i < 3; i++)
{
riw[i]->SetResliceMode(1);
riw[i]->GetRenderer()->ResetCamera();
riw[i]->Render();
}
vtkSmartPointer<vtkCellPicker> picker = vtkSmartPointer<vtkCellPicker>::New();
vtkSmartPointer<vtkProperty> ipwProp = vtkSmartPointer<vtkProperty>::New();
vtkSmartPointer< vtkRenderer > ren = vtkSmartPointer< vtkRenderer >::New();
auto renderWindow4 = vtkSmartPointer<vtkRenderWindow>::New();;//第四个窗口
auto iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();//第四个窗口的vtkRenderWindowInteractor
renderWindow4->SetInteractor(iren);
renderWindow4->AddRenderer(ren);
vtkSmartPointer<vtkImagePlaneWidget>planeWidget[3];
for (int i = 0; i < 3; i++)
{
planeWidget[i] = vtkSmartPointer<vtkImagePlaneWidget>::New();
planeWidget[i]->SetInteractor(iren);
planeWidget[i]->SetPicker(picker);
planeWidget[i]->RestrictPlaneToVolumeOn();
double color[3] = { 0, 0, 0 };
color[i] = 1;
planeWidget[i]->GetPlaneProperty()->SetColor(color);
color[0] /= 4.0;
color[1] /= 4.0;
color[2] /= 4.0;
riw[i]->GetRenderer()->SetBackground(0, 0, 0);
planeWidget[i]->SetTexturePlaneProperty(ipwProp);
planeWidget[i]->TextureInterpolateOff();
planeWidget[i]->SetResliceInterpolateToLinear();
planeWidget[i]->SetInputConnection(reader->GetOutputPort());
planeWidget[i]->SetPlaneOrientation(i);
planeWidget[i]->SetSliceIndex(imageDims[i] / 2);
planeWidget[i]->DisplayTextOn();
planeWidget[i]->SetDefaultRenderer(ren);
planeWidget[i]->SetWindowLevel(1358, -27);
planeWidget[i]->On();
planeWidget[i]->InteractionOn();
}
auto cbk = vtkSmartPointer<vtkResliceCursorCallback>::New();
for (int i = 0; i < 3; i++)
{
cbk->RIW[i] = riw[i];
cbk->IPW[i] = planeWidget[i];
cbk->RCW[i] = riw[i]->GetResliceCursorWidget();
vtkWidgetEventTranslator* WidgetTrans = riw[i]->GetResliceCursorWidget()->GetEventTranslator();
riw[i]->GetResliceCursorWidget()->AddObserver(vtkResliceCursorWidget::ResliceAxesChangedEvent, cbk);
riw[i]->GetResliceCursorWidget()->AddObserver(vtkResliceCursorWidget::WindowLevelEvent, cbk);
riw[i]->GetResliceCursorWidget()->AddObserver(vtkResliceCursorWidget::ResliceThicknessChangedEvent, cbk);
riw[i]->GetResliceCursorWidget()->AddObserver(vtkResliceCursorWidget::ResetCursorEvent, cbk);
riw[i]->SetLookupTable(riw[0]->GetLookupTable());
planeWidget[i]->GetColorMap()->SetLookupTable(riw[0]->GetLookupTable());
// planeWidget[i]->GetColorMap()->(riw[i]->GetResliceCursorWidget()->GetResliceCursorRepresentation()->GetColorMap()->GetInput());
planeWidget[i]->SetColorMap(riw[i]->GetResliceCursorWidget()->GetResliceCursorRepresentation()->GetColorMap());
}
auto style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
iren->SetInteractorStyle(style);
renderWindow4->SetSize(500, 500);
renderWindow4->SetPosition(1300, 0);
renderWindow4->Render();
iren->Initialize();
iren->Start();
}
sorry i am new user ,don not allow me upload video, you can run my code and press “ctrl” rotate image,then you can found the question.