# Qt显示 vtk cpr 序列

2023-11-03 13:40
文章标签 显示 qt 序列 vtk cpr

本文主要是介绍# Qt显示 vtk cpr 序列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Qt显示 vtk cpr 序列

周末终于不忙了,正好实现一个cpr的常用功能,截面图序列浏览。

下边六个截面只是单纯的显示图片,想了想直接用qlabel吧,正好之前没做过可以学习下。记录下用到的东西

vtkImage 转 QImage

图片类型转换

vtkNew<vtkImageCast>cast;
cast->SetInputConnection(mpr_maker_->GetImageReslice(3)->GetOutputPort());
cast->SetOutputScalarTypeToUnsignedChar();
cast->Update();
QImage vtkImageDataToQImage(vtkSmartPointer<vtkImageData> imageData) {if (!imageData) {return QImage();}int width = imageData->GetDimensions()[0];int height = imageData->GetDimensions()[1];QImage image(width, height, QImage::Format_RGB32);QRgb *rgbPtr = reinterpret_cast<QRgb *>(image.bits()) + width * (height - 1);unsigned char *colorsPtr =reinterpret_cast<unsigned char *>(imageData->GetScalarPointer());for (int row = 0; row < height; row++) {for (int col = 0; col < width; col++) {*(rgbPtr++) = QColor(colorsPtr[0], colorsPtr[1], colorsPtr[2]).rgb();colorsPtr += imageData->GetNumberOfScalarComponents();}rgbPtr -= width * 2;}return image;
}

多条可拖动直线

需要自己实现一个Actor,
m_windowSize:窗口大小
m_windowOrigin:窗口原点
m_centerPointDisplayPosition:窗口中心点
m_cameraDistance:缩放倍率

class CBvtkResliceActor final : public vtkObject {public:static CBvtkResliceActor *New();vtkTypeMacro(CBvtkResliceActor, vtkObject);CBvtkResliceActor() {createActor();}~CBvtkResliceActor() = default;vtkActor *getActor() const {return m_actor;}vtkMTimeType getLineTime() const {return m_cursorLines[0]->GetMTime();}void setCameraDistance(const double t_distance) {m_cameraDistance = t_distance;}void setDisplaySize(const double *t_size);void setDisplayOriginPoint(const double *t_point);void setCenterPosition(const double *t_center);void createActor();void update();void reset() const;void createColors(double *t_color1, double *t_color2);void setCPRLines();bool cpr_lines_ = false;private:vtkSmartPointer<vtkAppendPolyData> m_appender = {};vtkSmartPointer<vtkActor> m_actor = {};vtkSmartPointer<vtkTransformFilter> m_filter = {};vtkSmartPointer<vtkLineSource> m_cursorLines[11] = {};vtkSmartPointer<vtkUnsignedCharArray> m_colors[3] = {};vtkSmartPointer<vtkPolyDataMapper> m_mapper = {};double m_windowSize[3] = {};double m_windowOrigin[3] = {};double m_centerPointDisplayPosition[3] = {};double m_cameraDistance = 0;int m_start = 0;
};
void CBvtkResliceActor::update() {if (m_start == 0) {if(cpr_lines_) {for (auto i = -3; i < 4; ++i) {if(0 == i) {continue;}m_cursorLines[7 + i]->SetPoint1(m_centerPointDisplayPosition[0] + i * 1.6,m_centerPointDisplayPosition[1] - 5, 0.01);m_cursorLines[7 + i]->SetPoint2(m_centerPointDisplayPosition[0] + i * 1.6,m_centerPointDisplayPosition[1] + 5, 0.01);m_cursorLines[7 + i]->Update();m_cursorLines[7 + i]->GetOutput()->GetPointData()->AddArray(m_colors[0]);}} else {// 中间连起来m_cursorLines[0]->SetPoint1(m_windowOrigin[0], m_centerPointDisplayPosition[1], 0.01);m_cursorLines[0]->SetPoint2(m_windowSize[0], m_centerPointDisplayPosition[1], 0.01);m_cursorLines[0]->Update();m_cursorLines[0]->GetOutput()->GetPointData()->AddArray(m_colors[1]);m_cursorLines[2]->SetPoint1(m_centerPointDisplayPosition[0], m_windowOrigin[1], 0.01);m_cursorLines[2]->SetPoint2(m_centerPointDisplayPosition[0], m_windowSize[1], 0.01);m_cursorLines[2]->Update();m_cursorLines[2]->GetOutput()->GetPointData()->AddArray(m_colors[0]);// 中间空一个centerHide距离if(false) {m_cursorLines[0]->SetPoint1(m_windowOrigin[0], m_centerPointDisplayPosition[1], 0.01);m_cursorLines[0]->SetPoint2(m_centerPointDisplayPosition[0] - centerHide, m_centerPointDisplayPosition[1], 0.01);m_cursorLines[0]->Update();m_cursorLines[0]->GetOutput()->GetPointData()->AddArray(m_colors[1]);m_cursorLines[1]->SetPoint1(m_centerPointDisplayPosition[0] + centerHide, m_centerPointDisplayPosition[1], 0.01);m_cursorLines[1]->SetPoint2(m_windowSize[0], m_centerPointDisplayPosition[1], 0.01);m_cursorLines[1]->Update();m_cursorLines[1]->GetOutput()->GetPointData()->AddArray(m_colors[1]);m_cursorLines[2]->SetPoint1(m_centerPointDisplayPosition[0], m_windowOrigin[1], 0.01);m_cursorLines[2]->SetPoint2(m_centerPointDisplayPosition[0], m_centerPointDisplayPosition[1] - centerHide, 0.01);m_cursorLines[2]->Update();m_cursorLines[2]->GetOutput()->GetPointData()->AddArray(m_colors[0]);m_cursorLines[3]->SetPoint1(m_centerPointDisplayPosition[0], m_centerPointDisplayPosition[1] + centerHide, 0.01);m_cursorLines[3]->SetPoint2(m_centerPointDisplayPosition[0], m_windowSize[1], 0.01);m_cursorLines[3]->Update();m_cursorLines[3]->GetOutput()->GetPointData()->AddArray(m_colors[0]);}}m_actor->SetScale(5);m_start = 1;} else {m_actor->SetPosition(m_centerPointDisplayPosition[0],m_centerPointDisplayPosition[1],0.01);}
}

绑定鼠标滚轮和拖动事件的槽函数


enum vtkCustomEvents : unsigned long {changeScrollValue = vtkCommand::UserEvent + 1,defaultCursor = changeScrollValue + 1,cursorMove = defaultCursor + 1,cursorFinishMovement = cursorMove + 1,cursorRotate = cursorFinishMovement + 1,imageChanged = cursorRotate + 1,qualityLow = imageChanged + 1,qualityHigh = qualityLow + 1,
};for (auto i = 0; i < 3; ++i) {if (!m_cursor[i]) {m_cursor[i] = vtkSmartPointer<CBvtkReslicePlaneCursorWidget>::New();m_cursor[i]->cpr_type_ = cpr_type_;m_cbk[i] = vtkSmartPointer<CBvtkResliceCallback>::New();m_cbk[i]->setHandleNumber(i);m_cbk[i]->setWidget(this);m_cbk[i]->planeWidget_[0] = this->m_planeWidget[0];m_cbk[i]->planeWidget_[1] = this->m_planeWidget[1];m_cbk[i]->planeWidget_[2] = this->m_planeWidget[2];m_cursor[i]->setWidget(this);m_cursor[i]->AddObserver(cursorRotate, m_cbk[i]);m_cursor[i]->AddObserver(cursorMove, m_cbk[i]);m_cursor[i]->AddObserver(qualityLow, m_cbk[i]);m_cursor[i]->AddObserver(qualityHigh, m_cbk[i]);m_cursor[i]->AddObserver(vtkCommand::LeftButtonReleaseEvent, m_cbk[i]);m_cursor[i]->AddObserver(cursorFinishMovement, m_cbk[i]);m_cursor[i]->AddObserver(imageChanged, m_cbk[i]);m_windows[i]->GetInteractor()->GetInteractorStyle()->AddObserver(imageChanged, m_cbk[i]);}
}if(reslice_widget_->cpr_type_) {for(int i = 0; i < 3; i++) {connection_->Connect(reslice_widget_->GetReslicePlaneCursorWidget()[i],cursorMove, this,SLOT(SlotUpdataCPR(vtkObject *, unsigned long, void *, void *)));connection_->Connect(reslice_widget_->GetReslicePlaneCursorWidget()[i],imageChanged, this,SLOT(SlotUpdataCPR(vtkObject *, unsigned long, void *, void *)));}
}

生成多张切片

要保证几个窗口的床位窗宽一致,我是选择四组vtkImageResliceToColors + vtkImageReslice,几个窗口公用一个vtkScalarsToColors来实现。
三组用来切割实现cpr切割,另外一组用来切割下面几张用QLabel显示的图片。每次切割平移8个毫米。
QList<QImage>把几张需要显示的图片传出去。

QList<QImage> list;
vtkNew<vtkMatrix4x4>reslice_axes;
for(int i = -24; i < 25; i = i + 8) {if(0 == i) {continue;}reslice_axes->DeepCopy(reslice_widget_->GetImageReslicers()[0]->GetResliceAxes());reslice_axes->SetElement(0, 3, reslice_axes->GetElement(0, 3) + i);reslice_axes->SetElement(1, 3, cpr_center_[1]);reslice_axes->SetElement(2, 3, cpr_center_[2]);mpr_maker_->GetImageReslice(3)->SetResliceAxes(reslice_axes);vtkNew<vtkImageCast>cast;cast->SetInputConnection(mpr_maker_->GetImageReslice(3)->GetOutputPort());cast->SetOutputScalarTypeToUnsignedChar();cast->Update();list <<  vtkImageDataToQImage(cast->GetOutput()).mirrored(false, true);
}
emit SgnUpdataCPR(list);

这篇关于# Qt显示 vtk cpr 序列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/338554

相关文章

Qt 中集成mqtt协议的使用方法

《Qt中集成mqtt协议的使用方法》文章介绍了如何在工程中引入qmqtt库,并通过声明一个单例类来暴露订阅到的主题数据,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一,引入qmqtt 库二,使用一,引入qmqtt 库我是将整个头文件/源文件都添加到了工程中进行编译,这样 跨平台

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

关于最长递增子序列问题概述

《关于最长递增子序列问题概述》本文详细介绍了最长递增子序列问题的定义及两种优化解法:贪心+二分查找和动态规划+状态压缩,贪心+二分查找时间复杂度为O(nlogn),通过维护一个有序的“尾巴”数组来高效... 一、最长递增子序列问题概述1. 问题定义给定一个整数序列,例如 nums = [10, 9, 2

如何设置vim永久显示行号

《如何设置vim永久显示行号》在Linux环境下,vim默认不显示行号,这在程序编译出错时定位错误语句非常不便,通过修改vim配置文件vimrc,可以在每次打开vim时永久显示行号... 目录设置vim永久显示行号1.临时显示行号2.永www.chinasem.cn久显示行号总结设置vim永久显示行号在li

基于Qt Qml实现时间轴组件

《基于QtQml实现时间轴组件》时间轴组件是现代用户界面中常见的元素,用于按时间顺序展示事件,本文主要为大家详细介绍了如何使用Qml实现一个简单的时间轴组件,需要的可以参考下... 目录写在前面效果图组件概述实现细节1. 组件结构2. 属性定义3. 数据模型4. 事件项的添加和排序5. 事件项的渲染如何使用

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

电脑显示hdmi无信号怎么办? 电脑显示器无信号的终极解决指南

《电脑显示hdmi无信号怎么办?电脑显示器无信号的终极解决指南》HDMI无信号的问题却让人头疼不已,遇到这种情况该怎么办?针对这种情况,我们可以采取一系列步骤来逐一排查并解决问题,以下是详细的方法... 无论你是试图为笔记本电脑设置多个显示器还是使用外部显示器,都可能会弹出“无HDMI信号”错误。此消息可能

python与QT联合的详细步骤记录

《python与QT联合的详细步骤记录》:本文主要介绍python与QT联合的详细步骤,文章还展示了如何在Python中调用QT的.ui文件来实现GUI界面,并介绍了多窗口的应用,文中通过代码介绍... 目录一、文章简介二、安装pyqt5三、GUI页面设计四、python的使用python文件创建pytho

QT实现TCP客户端自动连接

《QT实现TCP客户端自动连接》这篇文章主要为大家详细介绍了QT中一个TCP客户端自动连接的测试模型,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录版本 1:没有取消按钮 测试效果测试代码版本 2:有取消按钮测试效果测试代码版本 1:没有取消按钮 测试效果缺陷:无法手动停

基于Qt实现系统主题感知功能

《基于Qt实现系统主题感知功能》在现代桌面应用程序开发中,系统主题感知是一项重要的功能,它使得应用程序能够根据用户的系统主题设置(如深色模式或浅色模式)自动调整其外观,Qt作为一个跨平台的C++图形用... 目录【正文开始】一、使用效果二、系统主题感知助手类(SystemThemeHelper)三、实现细节