【VTK】读取一张dicom—计算窗宽窗位并动态交互显示像素位置和像素值

参考VTK官网:https://vtk.org/Wiki/VTK/Examples/Cxx/Images/PickPixel2

结果显示:【VTK】读取一张dicom—计算窗宽窗位并动态交互显示像素位置和像素值_第1张图片

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);


// Template for image value reading
template
void vtkValueMessageTemplate(vtkImageData* image, int* position,
	std::string& message)
{
	T* tuple = ((T*)image->GetScalarPointer(position));
	int components = image->GetNumberOfScalarComponents();
	for (int c = 0; c < components; ++c)
	{
		message += vtkVariant(tuple[c]).ToString();
		if (c != (components - 1))
		{
			message += ", ";
		}
	}
	message += " )";
}

// The mouse motion callback, to pick the image and recover pixel values
// 自定义交互方式
class vtkImageInteractionCallback : public vtkCommand
{
public:
	static vtkImageInteractionCallback *New()
	{
		return new vtkImageInteractionCallback;
	}

	vtkImageInteractionCallback()
	{
		this->Viewer = NULL;
		this->Picker = NULL;
		this->Annotation = NULL;
	}

	~vtkImageInteractionCallback()
	{
		this->Viewer = NULL;
		this->Picker = NULL;
		this->Annotation = NULL;
	}

	void SetPicker(vtkPropPicker *picker)
	{
		this->Picker = picker;
	}

	void SetAnnotation(vtkCornerAnnotation *annotation)
	{
		this->Annotation = annotation;
	}

	void SetViewer(vtkImageViewer2 *viewer)
	{
		this->Viewer = viewer;
	}

	virtual void Execute(vtkObject *, unsigned long vtkNotUsed(event), void *)
	{
		vtkRenderWindowInteractor *interactor =
			this->Viewer->GetRenderWindow()->GetInteractor();
		vtkRenderer* renderer = this->Viewer->GetRenderer();
		vtkImageActor* actor = this->Viewer->GetImageActor();
		vtkImageData* image = this->Viewer->GetInput();
		vtkInteractorStyle *style = vtkInteractorStyle::SafeDownCast(
			interactor->GetInteractorStyle());

#if VTK_MAJOR_VERSION <= 5
		image->Update();
#endif

		// Pick at the mouse location provided by the interactor
		this->Picker->Pick(interactor->GetEventPosition()[0],
			interactor->GetEventPosition()[1],
			0.0, renderer);

		// There could be other props assigned to this picker, so 
		// make sure we picked the image actor
		vtkAssemblyPath* path = this->Picker->GetPath();
		bool validPick = false;

		if (path)
		{
			vtkCollectionSimpleIterator sit;
			path->InitTraversal(sit);
			vtkAssemblyNode *node;
			for (int i = 0; i < path->GetNumberOfItems() && !validPick; ++i)
			{
				node = path->GetNextNode(sit);
				if (actor == vtkImageActor::SafeDownCast(node->GetViewProp()))
				{
					validPick = true;
				}
			}
		}

		if (!validPick)
		{
			this->Annotation->SetText(0, "Off Image");
			interactor->Render();
			// Pass the event further on
			style->OnMouseMove();
			return;
		}

		// Get the world coordinates of the pick
		double pos[3];
		this->Picker->GetPickPosition(pos);

		int image_coordinate[3];

		int axis = this->Viewer->GetSliceOrientation();
		switch (axis)
		{
		case vtkImageViewer2::SLICE_ORIENTATION_XZ:
			image_coordinate[0] = vtkMath::Round(pos[0]);
			image_coordinate[1] = this->Viewer->GetSlice();
			image_coordinate[2] = vtkMath::Round(pos[2]);
			break;
		case vtkImageViewer2::SLICE_ORIENTATION_YZ:
			image_coordinate[0] = this->Viewer->GetSlice();
			image_coordinate[1] = vtkMath::Round(pos[0]);
			image_coordinate[2] = vtkMath::Round(pos[1]);
			break;
		default:  // vtkImageViewer2::SLICE_ORIENTATION_XY
			image_coordinate[0] = vtkMath::Round(pos[0]);
			image_coordinate[1] = vtkMath::Round(pos[1]);
			image_coordinate[2] = this->Viewer->GetSlice();
			break;
		}

		std::string message = "Location: ( ";
		message += vtkVariant(image_coordinate[0]).ToString();
		message += ", ";
		message += vtkVariant(image_coordinate[1]).ToString();
		message += ", ";
		message += vtkVariant(image_coordinate[2]).ToString();
		message += " )\nValue: ( ";

		switch (image->GetScalarType())
		{
			vtkTemplateMacro((vtkValueMessageTemplate(image,
				image_coordinate,
				message)));

		default:
			return;
		}

		this->Annotation->SetText(0, message.c_str());
		interactor->Render();
		style->OnMouseMove();
	}

private:
	vtkImageViewer2*      Viewer;      // Pointer to the viewer
	vtkPropPicker*        Picker;      // Pointer to the picker
	vtkCornerAnnotation*  Annotation;  // Pointer to the annotation
};


int main(int argc, char* argv[])
{
	vtkSmartPointer imageViewer =
		vtkSmartPointer::New();

	// Verify input arguments
	vtkSmartPointer reader = vtkSmartPointer::New();
	reader->SetFileName("D:\\NeuboronFile\\dcm\\dcm\\CHC\\CTsim image\\CT.4278314-2.20.dcm");
	reader->Update();

	// create a noise image
	vtkSmartPointer noiseSource =
		vtkSmartPointer::New();
	noiseSource->SetWholeExtent(0, 512, 0, 512, 0, 0);
	noiseSource->SetMinimum(0.0);
	noiseSource->SetMaximum(65535.0);

	// cast noise image to unsigned short
	vtkSmartPointer imageCast =
		vtkSmartPointer::New();
	imageCast->SetInputConnection(noiseSource->GetOutputPort());
	imageCast->SetOutputScalarTypeToUnsignedShort();
	imageCast->Update();

	// connect to image viewer pipeline
	imageViewer->SetInputConnection(imageCast->GetOutputPort());

	// Picker to pick pixels
	vtkSmartPointer propPicker =
		vtkSmartPointer::New();
	propPicker->PickFromListOn();

	// Give the picker a prop to pick
	vtkImageActor* imageActor = imageViewer->GetImageActor();
	propPicker->AddPickList(imageActor);

	// disable interpolation, so we can see each pixel
	imageActor->InterpolateOff();

	// Visualize
	vtkSmartPointer renderWindowInteractor =
		vtkSmartPointer::New();
	imageViewer->SetInputConnection(reader->GetOutputPort());
	imageViewer->SetupInteractor(renderWindowInteractor);
	imageViewer->SetSize(600, 600);

	vtkRenderer* renderer = imageViewer->GetRenderer();
	renderer->ResetCamera();
	renderer->GradientBackgroundOn();
	renderer->SetBackground(0.6, 0.6, 0.5);
	renderer->SetBackground2(0.3, 0.3, 0.2);

	// Annotate the image with window/level and mouse over pixel
	// information
	vtkSmartPointer cornerAnnotation =
		vtkSmartPointer::New();
	cornerAnnotation->SetLinearFontScaleFactor(2);
	cornerAnnotation->SetNonlinearFontScaleFactor(1);
	cornerAnnotation->SetMaximumFontSize(20);
	cornerAnnotation->SetText(0, "Off Image");
	cornerAnnotation->SetText(3, "\n");
	cornerAnnotation->GetTextProperty()->SetColor(1, 0, 0);

	imageViewer->GetRenderer()->AddViewProp(cornerAnnotation);

	// Callback listens to MouseMoveEvents invoked by the interactor's style
	vtkSmartPointer callback =
		vtkSmartPointer::New();
	callback->SetViewer(imageViewer);
	callback->SetAnnotation(cornerAnnotation);
	callback->SetPicker(propPicker);

	// InteractorStyleImage allows for the following controls:
	// 1) middle mouse + move = camera pan
	// 2) left mouse + move = window/level
	// 3) right mouse + move = camera zoom
	// 4) middle mouse wheel scroll = zoom
	// 5) 'r' = reset window/level
	// 6) shift + 'r' = reset camera
	vtkInteractorStyleImage* imageStyle =
		imageViewer->GetInteractorStyle();
	imageStyle->AddObserver(vtkCommand::MouseMoveEvent, callback);

	renderWindowInteractor->Initialize();
	renderWindowInteractor->Start();

	return EXIT_SUCCESS;
}

 

 

 

你可能感兴趣的:(VTK学习)