MPRReslice UI and windowlevel fix.

This commit is contained in:
Krad
2023-01-06 16:55:12 +08:00
parent f67cdd3a5c
commit 679170af7c
9 changed files with 204 additions and 7 deletions

View File

@@ -12,6 +12,7 @@
#include <vtkCamera.h>
#include <vtkPropCollection.h>
#include <vtkPropPicker.h>
#include <vtkImageProperty.h>
#include "Rendering/Core/RenderingDefines.h"
#include "Rendering/Legend/ResliceCursorLegendActor.h"
@@ -88,27 +89,29 @@ void ResliceImageInteractorStyle::OnLeftButtonDown() {
cursor->SetDragStartPosition(pos);
cursor->StartDrag();
}
else if (this->InteractionMode == VTKIS_WINDOW_LEVEL)
else if (this->InteractionMode == VTKIS_IMAGE_WINDOWLEVEL)
{
this->WindowLevelStartPosition[0] = pos[0];
this->WindowLevelStartPosition[1] = pos[1];
this->StartWindowLevel();
}
else if (this->InteractionMode == VTKIS_IMAGE3D)
else if (this->InteractionMode == VTKIS_IMAGE_ROTATE3D)
{
this->StartRotate();
}
else if (this->InteractionMode == VTKIS_IMAGE2D)
else if (this->InteractionMode == VTKIS_IMAGE_ROTATE2D)
{
this->StartSpin();
}
else if (this->InteractionMode == VTKIS_IMAGE_SLICING)
else if (this->InteractionMode == VTKIS_IMAGE_SLICE)
{
this->StartSlice();
}
else
{
this->Superclass::OnLeftButtonDown();
else if (this->InteractionMode == VTKIS_IMAGE_ZOOM){
this->StartDolly();
}
else if (this->InteractionMode == VTKIS_IMAGE_PAN){
this->StartPan();
}
}
@@ -142,3 +145,90 @@ void ResliceImageInteractorStyle::NoneStatePick() {
}
return;
}
void ResliceImageInteractorStyle::StartWindowLevel()
{
if (this->State != VTKIS_NONE)
{
return;
}
this->StartState(VTKIS_WINDOW_LEVEL);
if (this->HandleObservers && this->HasObserver(vtkCommand::StartWindowLevelEvent))
{
this->InvokeEvent(vtkCommand::StartWindowLevelEvent, this);
}
else
{
if (this->CurrentImageProperty)
{
vtkImageProperty* property = this->CurrentImageProperty;
this->WindowLevelInitial[0] = property->GetColorWindow();
this->WindowLevelInitial[1] = property->GetColorLevel();
}
}
}
void ResliceImageInteractorStyle::WindowLevel() {
vtkRenderWindowInteractor *rwi = this->Interactor;
this->WindowLevelCurrentPosition[0] = rwi->GetEventPosition()[0];
this->WindowLevelCurrentPosition[1] = rwi->GetEventPosition()[1];
if (this->CurrentImageProperty) {
int *size = this->CurrentRenderer->GetSize();
double window = this->WindowLevelInitial[0];
double level = this->WindowLevelInitial[1];
// Compute normalized delta
double dx = (this->WindowLevelCurrentPosition[0] -
this->WindowLevelStartPosition[0]) * 4.0 / size[0];
double dy = (this->WindowLevelStartPosition[1] -
this->WindowLevelCurrentPosition[1]) * 4.0 / size[1];
// Scale by current values
if (fabs(window) > 0.01) {
dx = dx * window;
} else {
dx = dx * (window < 0 ? -0.01 : 0.01);
}
if (fabs(level) > 0.01) {
dy = dy * level;
} else {
dy = dy * (level < 0 ? -0.01 : 0.01);
}
// Abs so that direction does not flip
if (window < 0.0) {
dx = -1 * dx;
}
if (level < 0.0) {
dy = -1 * dy;
}
// Compute new window level
double newWindow = dx + window;
double newLevel = level - dy;
if (newWindow < 0.01) {
newWindow = 0.01;
}
this->CurrentImageProperty->SetColorWindow(newWindow);
this->CurrentImageProperty->SetColorLevel(newLevel);
if (this->HandleObservers &&
this->HasObserver(vtkCommand::WindowLevelEvent)) {
this->InvokeEvent(vtkCommand::WindowLevelEvent, this);
}
this->Interactor->Render();
}
}
void ResliceImageInteractorStyle::SetMode(int mode) {
this->InteractionMode = mode;
}

View File

@@ -24,12 +24,19 @@ public:
void OnMouseMove() override;
void StartWindowLevel() override;
void WindowLevel() override;
void SetMode(int mode);
virtual void StartCursorInteractive(){
this->State = VTKIS_POSITION_PROP;
}
virtual void StopCursorInteractive(){
this->State = VTKIS_NONE;
}
vtkSetMacro(CurrentImageProperty, vtkImageProperty*);
protected:
ResliceImageInteractorStyle();

View File

@@ -15,6 +15,7 @@
#include <vtkImageSlice.h>
#include <vtkMatrix4x4.h>
#include <vtkProperty2D.h>
#include <vtkImageProperty.h>
#include <vtkTextProperty.h>
@@ -130,6 +131,7 @@ void ResliceImageViewer::InstallPipeline() {
if (this->Renderer && this->Actor) {
this->Renderer->AddViewProp(Actor);
this->InteractorStyle->SetCurrentImageProperty(Actor->GetProperty());
this->Renderer->SetBackground(0., 0., 0.);
}
}
@@ -150,6 +152,7 @@ void ResliceImageViewer::UnInstallPipeline() {
Renderer->RemoveAllObservers();
}
if (this->Interactor) {
this->InteractorStyle->SetCurrentImageProperty(nullptr);
this->Interactor->SetInteractorStyle(nullptr);
this->Interactor->SetRenderWindow(nullptr);
}
@@ -229,6 +232,8 @@ void ResliceImageViewer::Render() {
this->InteractorStyle->AddObserver(ResliceCursorLegendActor::IMAGE_INTERACT_OFF,this,&ResliceImageViewer::ResetHandle);
this->InteractorStyle->AddObserver(ResliceCursorLegendActor::END_DRAG,this,&ResliceImageViewer::EndDrag);
this->InteractorStyle->AddObserver(SliceEvent,this, &ResliceImageViewer::SliceCallback);
this->InteractorStyle->AddObserver(vtkCommand::WindowLevelEvent,this, &ResliceImageViewer::WindowLevelCallback);
this->InteractorStyle->AddObserver(vtkCommand::EndWindowLevelEvent,this, &ResliceImageViewer::EndWindowLevelCallback);
this->RenderWindow->AddObserver(vtkCommand::WindowResizeEvent,this,&ResliceImageViewer::handleResize);
cursor1->AddObserver(ResliceCursorLegendActor::ROLL,this, &ResliceImageViewer::handleRoll);
@@ -439,3 +444,34 @@ void ResliceImageViewer::SliceCallback() {
this->InvokeEvent(SliceEvent);
}
}
void ResliceImageViewer::EndWindowLevelCallback() {
this->InvokeEvent(vtkCommand::EndWindowLevelEvent);
}
void ResliceImageViewer::SetStyleMode(int mode) {
this->InteractorStyle->SetMode(mode);
}
void ResliceImageViewer::GetWindowLevel(double* windowLevel) {
if (windowLevel){
windowLevel[0] = Actor->GetProperty()->GetColorWindow();
windowLevel[1] = Actor->GetProperty()->GetColorLevel();
}
}
void ResliceImageViewer::SetWindowLevel(double* windowLevel) {
if (windowLevel){
Actor->GetProperty()->SetColorWindow(windowLevel[0]);
Actor->GetProperty()->SetColorLevel(windowLevel[1]);
WindowLevelCallback();
Render();
}
}
void ResliceImageViewer::WindowLevelCallback() {
char buff[1024] = {0};
sprintf(buff,"WL:%d WW: %d",(int)Actor->GetProperty()->GetColorLevel(),
(int)Actor->GetProperty()->GetColorWindow());
annotation->SetText(5, buff);
}

View File

@@ -43,23 +43,43 @@ public:
void SetInputData(vtkImageData *in);
void SetStyleMode(int mode);
void SetDefaultSliceOrientation(int orientation);
void SetCoordsTransformMatrix(vtkMatrix4x4* matrix4X4);
double* GetCursorSlicePoint();
double* GetCursorSliceDirection1();
double* GetCursorSliceDirection2();
void AdjustOrthogonalScale();
void ChangeSlicePoint(double * point);
void ChangeSliceNormal(double * normal);
void EndDrag();
void UpdateSliceCursor();
void AdjustCameraFollowCursor();
void SetChecked(bool checked);
void InvokeClick();
void SliceCallback();
void WindowLevelCallback();
void EndWindowLevelCallback();
void GetWindowLevel(double* windowLeveL);
void SetWindowLevel(double* windowLeveL);
protected:
ResliceImageViewer();

View File

@@ -44,6 +44,9 @@ void ResliceImageManager::InitEvents() {
viewerA->AddObserver(vtkCommand::LeftButtonPressEvent,this,&ResliceImageManager::ClickCallback);
viewerS->AddObserver(vtkCommand::LeftButtonPressEvent,this,&ResliceImageManager::ClickCallback);
viewerC->AddObserver(vtkCommand::LeftButtonPressEvent,this,&ResliceImageManager::ClickCallback);
viewerA->AddObserver(vtkCommand::EndWindowLevelEvent,this,&ResliceImageManager::WindowLevelCallback);
viewerS->AddObserver(vtkCommand::EndWindowLevelEvent,this,&ResliceImageManager::WindowLevelCallback);
viewerC->AddObserver(vtkCommand::EndWindowLevelEvent,this,&ResliceImageManager::WindowLevelCallback);
viewerA->AddObserver(SliceEvent,this,&ResliceImageManager::MoveCallback);
viewerS->AddObserver(SliceEvent,this,&ResliceImageManager::MoveCallback);
viewerC->AddObserver(SliceEvent,this,&ResliceImageManager::MoveCallback);
@@ -117,3 +120,26 @@ void ResliceImageManager::ClickCallback(vtkObject *sender, unsigned long eventID
}
}
void ResliceImageManager::SetMode(int mode) {
viewerA->SetStyleMode(mode);
viewerS->SetStyleMode(mode);
viewerC->SetStyleMode(mode);
}
void ResliceImageManager::WindowLevelCallback(vtkObject *sender, unsigned long eventID, void *data) {
auto viewer = ResliceImageViewer::SafeDownCast(sender);
double windowLevel[2]={.0,.0};
viewer->GetWindowLevel(windowLevel);
if (viewer) {
if (viewer!=viewerA){
viewerA->SetWindowLevel(windowLevel);
}
if (viewer!=viewerC){
viewerC->SetWindowLevel(windowLevel);
}
if (viewer!=viewerS){
viewerS->SetWindowLevel(windowLevel);
}
}
}

View File

@@ -21,6 +21,7 @@ public :
void SetViewer(int index, ResliceImageViewer* viewer);
void InitEvents();
void SetMode(int mode);
private:
std::vector<ResliceImageViewer*> mViewers;
ResliceImageViewer * viewerA;
@@ -30,6 +31,7 @@ private:
void RollCallback(vtkObject* sender, unsigned long eventID, void* data);
void MoveCallback(vtkObject* sender, unsigned long eventID, void* data);
void ClickCallback(vtkObject* sender, unsigned long eventID, void* data);
void WindowLevelCallback(vtkObject* sender, unsigned long eventID, void* data);
// void SliceCallback(vtkObject* sender, unsigned long eventID, void* data);
void EndDrag(vtkObject* sender, unsigned long eventID, void* data);
};

View File

@@ -69,6 +69,7 @@ MPRResliceWindow::MPRResliceWindow(QWidget *parent, Qt::WindowFlags f) : QDialog
manager->SetViewer(2,mViewerS);
manager->InitEvents();
connect(toolBar, &ResliceMPRToolBar::modeButtonClicked,manager,&ResliceImageManager::SetMode);
}
MPRResliceWindow::~MPRResliceWindow() {
@@ -212,15 +213,25 @@ void MPRResliceWindow::loadData(SeriesImageSet *series) {
mViewerC->SetCoordsTransformMatrix(series->GetProperty()->GetOrientationMatrix());
mViewerC->SetInputData(series->GetData());
mViewerC->SetDefaultSliceOrientation(2);
mViewerC->SetWindowLevel(mWindowLevel);
mViewerC->Render();
mViewerS->SetRenderWindow(mWidgetSagittal->renderWindow());
mViewerS->SetCoordsTransformMatrix(series->GetProperty()->GetOrientationMatrix());
mViewerS->SetInputData(series->GetData());
mViewerS->SetDefaultSliceOrientation(1);
mViewerS->SetWindowLevel(mWindowLevel);
mViewerS->Render();
mViewerA->SetRenderWindow(mWidgetAxial->renderWindow());
mViewerA->SetCoordsTransformMatrix(series->GetProperty()->GetOrientationMatrix());
mViewerA->SetInputData(series->GetData());
mViewerA->SetDefaultSliceOrientation(0);
mViewerA->SetWindowLevel(mWindowLevel);
mViewerA->Render();
}
void MPRResliceWindow::SetDefaultWindowLevel(double* windowLevel) {
if (windowLevel){
mWindowLevel[0] = windowLevel[0];
mWindowLevel[1] = windowLevel[1];
}
}

View File

@@ -32,6 +32,7 @@ public:
Rows_1_1_1,
};
void loadData(SeriesImageSet* series);
void SetDefaultWindowLevel(double * windowLevel);
void setRenderWindowLayout(LayoutType type);
private:
QVTKOpenGLNativeWidget *mWidgetAxial;
@@ -44,6 +45,7 @@ private:
ResliceImageManager* manager = nullptr;
QSplitter* mMainSplitter= nullptr;
QSplitter* mAppendSplitter= nullptr;
double mWindowLevel[2]={.0, .0};
int layoutType = 0;
};

View File

@@ -178,10 +178,13 @@ void QDicomViewer::initViewOperation() {
});
// MPR
connect(ui->toolBar, &DefaultToolBar::requestMPR,[=](){
DicomImageView *curV = ui->viewContainer->getCurrentView();
auto mprWin = new MPRResliceWindow(this);
connect(mprWin,&QDialog::finished,[=](){
mprWin->deleteLater();
});
double windowLevel[2] = {curV->getImageViewer()->GetColorWindow(),curV->getImageViewer()->GetColorLevel()};
mprWin->SetDefaultWindowLevel(windowLevel);
mprWin->show();
mprWin->loadData(ui->viewContainer->getViewManager()->getCurrentView()->getSeriesInstance());
});