vtk实现一个简易的RubberBand 并求矩形内部hu平均值和最值

想实现一个两点的矩形框,并求内部hu平均值。之前是用vtk自带的RubberBand来实现,交互关闭,清空显示等跟其他交互不太好集成统一管理。
趁着周末直接尝试下自定义一个Widget。效果:

反正就两个点,干脆直接用vtkDistanceWidget来实现吧。自己实现一个交互,需要写三个相关类

  • RubberBandWidget:直接用的DistanceWidget,主要是初始化、清空复位用。
  • RubberBandWidgetCallback:只绑定了个EndInteractionEvent,交互结束后求平均值和极值
  • RubberBandRepresentation2D:用四个vtkAxisActor2D实现矩形
class CBTagging2DWidget {public:virtual bool OffTagging() = 0;virtual bool ClearTagging() = 0;
};
class CBvtkRubberBandWidget : public vtkDistanceWidget, public CBTagging2DWidget {public:static CBvtkRubberBandWidget *New();vtkTypeMacro(CBvtkRubberBandWidget, vtkDistanceWidget);CBvtkRubberBandWidget();~CBvtkRubberBandWidget();vtkSmartPointer<vtkImageResliceToColors> m_reslicer {};vtkSmartPointer<vtkImageData> m_vtiData {};QPointer<CBvtkMPRWidget> m_parentWid {};virtual bool OffTagging() override;virtual bool ClearTagging() override;
};vtkStandardNewMacro(CBvtkRubberBandWidget);
CBvtkRubberBandWidget::CBvtkRubberBandWidget() {auto rep = CBvtkRubberBandRepresentation2D::New();SetRepresentation(rep);
}
CBvtkRubberBandWidget::~CBvtkRubberBandWidget() {}
bool CBvtkRubberBandWidget::OffTagging() {if(vtkDistanceWidget::Manipulate != GetWidgetState()) {this->ClearTagging();return true;}return false;
}bool CBvtkRubberBandWidget::ClearTagging() {SetInteractor(0);EnabledOff();Delete();return true;
}
class CBvtkRubberBandWidgetCallback : public vtkCommand {public:static CBvtkRubberBandWidgetCallback *New();vtkTypeMacro(CBvtkRubberBandWidgetCallback, vtkCommand);CBvtkRubberBandWidgetCallback() = default;~CBvtkRubberBandWidgetCallback() = default;void Execute(vtkObject *caller, unsigned long, void *) override;vtkRenderer *m_renderer;
};vtkStandardNewMacro(CBvtkRubberBandWidgetCallback);
void CBvtkRubberBandWidgetCallback::Execute(vtkObject *t_obj, unsigned long eid, void *) {if (eid != vtkCommand::EndInteractionEvent) {return;}auto *const widget = dynamic_cast<CBvtkRubberBandWidget *>(t_obj);widget->GetInteractor()->GetPicker()->Pick(widget->GetInteractor()->GetEventPosition()[0],widget->GetInteractor()->GetEventPosition()[1], 0,  m_renderer);double picked[3];widget->GetInteractor()->GetPicker()->GetPickPosition(picked);auto rep = static_cast<CBvtkRubberBandRepresentation2D *>(widget->GetRepresentation());double pos1[3], pos2[3];rep->GetPoint1WorldPosition(pos1);rep->GetPoint2WorldPosition(pos2);double min_value = 9999;double max_value = -9999;double average_value = 0;int num_x = abs(pos2[0] - pos1[0]);int num_y = abs(pos2[1] - pos1[1]);double division_x = (pos2[0] - pos1[0]) / num_x;double division_y = (pos2[1] - pos1[1]) / num_y;double pos[3];pos[2] = pos1[2];vtkMatrix4x4 *sourceMatrix =widget->m_reslicer->GetResliceAxes();double origin[3];double spaceing[3];double bounds[6];widget->m_vtiData->GetOrigin(origin);widget->m_vtiData->GetSpacing(spaceing);widget->m_vtiData->GetBounds(bounds);for (int i = 0; i < num_x; i++) {pos[0] = pos1[0] + i * division_x;for (int j = 0; j < num_y; j++) {pos[1] = pos1[1] + j * division_y;vtkNew<vtkTransform> transform;transform->SetMatrix(sourceMatrix);transform->Translate(pos[0], pos[1], 0);double pos_3d[3] = {transform->GetMatrix()->GetElement(0, 3),transform->GetMatrix()->GetElement(1, 3),transform->GetMatrix()->GetElement(2, 3)};double point[3] {0, 0, 0};for(int k = 0; k < 3; k++) {point[k] = pos_3d[k] - origin[k];point[k] /= spaceing[k];if(point[k] < bounds[k * 2 + 0] / spaceing[k] ||point[k] > bounds[k * 2 + 1] / spaceing[k]) {return;}}int pixel = *(int *) (widget->m_vtiData->GetScalarPointer(point[0], point[1], point[2]));average_value += pixel;if(min_value >= pixel) {min_value = pixel;}if(max_value <= pixel) {max_value = pixel;}}}average_value /= num_x * num_y;rep->SetRubberBandTitle(average_value, max_value, min_value);
}
class CBvtkRubberBandRepresentation2D : public vtkDistanceRepresentation {public:static CBvtkRubberBandRepresentation2D *New();vtkTypeMacro(CBvtkRubberBandRepresentation2D, vtkDistanceRepresentation);void PrintSelf(ostream &os, vtkIndent indent) override;double GetDistance() override {return this->Distance;}double *GetPoint1WorldPosition() override;double *GetPoint2WorldPosition() override;void GetPoint1WorldPosition(double pos[3]) override;void GetPoint2WorldPosition(double pos[3]) override;void SetPoint1WorldPosition(double pos[3]) override;void SetPoint2WorldPosition(double pos[3]) override;void SetPoint1DisplayPosition(double pos[3]) override;void SetPoint2DisplayPosition(double pos[3]) override;void GetPoint1DisplayPosition(double pos[3]) override;void GetPoint2DisplayPosition(double pos[3]) override;void BuildRepresentation() override;void ReleaseGraphicsResources(vtkWindow *w) override;int RenderOverlay(vtkViewport *viewport) override;int RenderOpaqueGeometry(vtkViewport *viewport) override;vtkSmartPointer<vtkImageResliceToColors> m_reslicer {};vtkSmartPointer<vtkImageData> m_vtiData {};void SetRubberBandTitle(const double &, const double &, const double &);protected:CBvtkRubberBandRepresentation2D();~CBvtkRubberBandRepresentation2D() override;vtkAxisActor2D *AxisActors[4];vtkProperty2D *AxisProperty;double Distance;private:CBvtkRubberBandRepresentation2D(const CBvtkRubberBandRepresentation2D &) = delete;void operator=(const CBvtkRubberBandRepresentation2D &) = delete;
};vtkStandardNewMacro(CBvtkRubberBandRepresentation2D);
CBvtkRubberBandRepresentation2D::CBvtkRubberBandRepresentation2D() {this->HandleRepresentation = vtkPointHandleRepresentation2D::New();this->AxisProperty = vtkProperty2D::New();this->AxisProperty->SetColor(0, 1, 0);//for (int i = 0; i < 4; i++) {AxisActors[i] = vtkAxisActor2D::New();AxisActors[i]->GetPoint1Coordinate()->SetCoordinateSystemToWorld();AxisActors[i]->GetPoint2Coordinate()->SetCoordinateSystemToWorld();AxisActors[i]->SetNumberOfLabels(5);AxisActors[i]->LabelVisibilityOff();AxisActors[i]->AdjustLabelsOff();AxisActors[i]->SetProperty(this->AxisProperty);AxisActors[i]->SetTitle(" ");AxisActors[i]->GetTitleTextProperty()->SetBold(1);AxisActors[i]->GetTitleTextProperty()->SetItalic(1);AxisActors[i]->GetTitleTextProperty()->SetShadow(1);AxisActors[i]->GetTitleTextProperty()->SetFontFamilyToArial();}this->Distance = 0.0;
}CBvtkRubberBandRepresentation2D::~CBvtkRubberBandRepresentation2D() {this->AxisProperty->Delete();this->AxisActors[0]->Delete();this->AxisActors[1]->Delete();this->AxisActors[2]->Delete();this->AxisActors[3]->Delete();
}void CBvtkRubberBandRepresentation2D::GetPoint1WorldPosition(double pos[3]) {this->Point1Representation->GetWorldPosition(pos);
}void CBvtkRubberBandRepresentation2D::GetPoint2WorldPosition(double pos[3]) {this->Point2Representation->GetWorldPosition(pos);
}double *CBvtkRubberBandRepresentation2D::GetPoint1WorldPosition() {if (!this->Point1Representation) {static double temp[3] = { 0, 0, 0 };return temp;}return this->Point1Representation->GetWorldPosition();
}double *CBvtkRubberBandRepresentation2D::GetPoint2WorldPosition() {if (!this->Point2Representation) {static double temp[3] = { 0, 0, 0 };return temp;}return this->Point2Representation->GetWorldPosition();
}void CBvtkRubberBandRepresentation2D::SetPoint1DisplayPosition(double x[3]) {this->Point1Representation->SetDisplayPosition(x);double p[3];this->Point1Representation->GetWorldPosition(p);this->Point1Representation->SetWorldPosition(p);this->BuildRepresentation();
}void CBvtkRubberBandRepresentation2D::SetPoint2DisplayPosition(double x[3]) {this->Point2Representation->SetDisplayPosition(x);double p[3];this->Point2Representation->GetWorldPosition(p);this->Point2Representation->SetWorldPosition(p);this->BuildRepresentation();
}void CBvtkRubberBandRepresentation2D::SetPoint1WorldPosition(double x[3]) {if (this->Point1Representation) {this->Point1Representation->SetWorldPosition(x);this->BuildRepresentation();}
}void CBvtkRubberBandRepresentation2D::SetPoint2WorldPosition(double x[3]) {if (this->Point2Representation) {this->Point2Representation->SetWorldPosition(x);this->BuildRepresentation();}
}void CBvtkRubberBandRepresentation2D::GetPoint1DisplayPosition(double pos[3]) {this->Point1Representation->GetDisplayPosition(pos);pos[2] = 0.0;
}void CBvtkRubberBandRepresentation2D::GetPoint2DisplayPosition(double pos[3]) {this->Point2Representation->GetDisplayPosition(pos);pos[2] = 0.0;
}void CBvtkRubberBandRepresentation2D::BuildRepresentation() {if (this->GetMTime() > this->BuildTime ||this->AxisActors[0]->GetMTime() > this->BuildTime ||this->AxisActors[1]->GetMTime() > this->BuildTime ||this->AxisActors[2]->GetMTime() > this->BuildTime ||this->AxisActors[3]->GetMTime() > this->BuildTime ||this->AxisActors[0]->GetTitleTextProperty()->GetMTime() > this->BuildTime ||this->AxisActors[1]->GetTitleTextProperty()->GetMTime() > this->BuildTime ||this->AxisActors[2]->GetTitleTextProperty()->GetMTime() > this->BuildTime ||this->AxisActors[3]->GetTitleTextProperty()->GetMTime() > this->BuildTime ||this->Point1Representation->GetMTime() > this->BuildTime ||this->Point2Representation->GetMTime() > this->BuildTime ||(this->Renderer && this->Renderer->GetVTKWindow() &&this->Renderer->GetVTKWindow()->GetMTime() > this->BuildTime)) {this->Superclass::BuildRepresentation();double p1[3], p2[3];this->Point1Representation->GetWorldPosition(p1);this->Point2Representation->GetWorldPosition(p2);this->Distance = sqrt(vtkMath::Distance2BetweenPoints(p1, p2));//this->AxisActors[0]->GetPoint1Coordinate()->SetValue(p1[0], p1[1], p1[2]);this->AxisActors[0]->GetPoint2Coordinate()->SetValue(p2[0], p1[1], p2[2]);this->AxisActors[1]->GetPoint1Coordinate()->SetValue(p2[0], p1[1], p2[2]);this->AxisActors[1]->GetPoint2Coordinate()->SetValue(p2[0], p2[1], p2[2]);this->AxisActors[2]->GetPoint1Coordinate()->SetValue(p1[0], p1[1], p2[2]);this->AxisActors[2]->GetPoint2Coordinate()->SetValue(p1[0], p2[1], p2[2]);this->AxisActors[3]->GetPoint1Coordinate()->SetValue(p1[0], p2[1], p2[2]);this->AxisActors[3]->GetPoint2Coordinate()->SetValue(p2[0], p2[1], p2[2]);//for (int i = 0; i < 4; i++) {AxisActors[i]->SetRulerMode(this->RulerMode);if (this->Scale != 0.0) {AxisActors[i]->SetRulerDistance(this->RulerDistance / this->Scale);}AxisActors[i]->SetNumberOfLabels(this->NumberOfRulerTicks);}this->BuildTime.Modified();}
}void CBvtkRubberBandRepresentation2D::ReleaseGraphicsResources(vtkWindow *w) {this->AxisActors[0]->ReleaseGraphicsResources(w);this->AxisActors[1]->ReleaseGraphicsResources(w);this->AxisActors[2]->ReleaseGraphicsResources(w);this->AxisActors[3]->ReleaseGraphicsResources(w);
}int CBvtkRubberBandRepresentation2D::RenderOverlay(vtkViewport *v) {this->BuildRepresentation();if (this->AxisActors[0]->GetVisibility()) {this->AxisActors[1]->RenderOverlay(v);this->AxisActors[2]->RenderOverlay(v);this->AxisActors[3]->RenderOverlay(v);return this->AxisActors[0]->RenderOverlay(v);} else {return 0;}
}int CBvtkRubberBandRepresentation2D::RenderOpaqueGeometry(vtkViewport *v) {this->BuildRepresentation();if (this->AxisActors[0]->GetVisibility()) {this->AxisActors[1]->RenderOpaqueGeometry(v);this->AxisActors[2]->RenderOpaqueGeometry(v);this->AxisActors[3]->RenderOpaqueGeometry(v);return this->AxisActors[0]->RenderOpaqueGeometry(v);} else {return 0;}
}void CBvtkRubberBandRepresentation2D::SetRubberBandTitle(const double &average, const double &max, const double &min) {QString str;str += QString::number(average, 'f', 0);str += "( ";str += QString::number(min);str += "~";str += QString::number(max);str += " )";this->AxisActors[3]->GetTitleTextProperty()->SetFontSize(1);this->AxisActors[3]->SetTitle(str.toLocal8Bit().data());
}void CBvtkRubberBandRepresentation2D::PrintSelf(ostream &os, vtkIndent indent) {this->Superclass::PrintSelf(os, indent);
}

vtk实现一个简易的RubberBand 并求矩形内部hu平均值和最值相关推荐

  1. python9行代码_如何用9行Python代码编写一个简易神经网络

    原标题:如何用9行Python代码编写一个简易神经网络 Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发. 学习人工智能时,我给自己定了一个目标--用Pyth ...

  2. 利用java swing编写一个简易的计算器,实现了括号,优先级,三角函数,阶乘等功能

    利用java swing编写一个简易的计算器 背景 效果图 一.默认图 二.计算三角函数 三.阶乘运算 四.常见的四则运算(实现了优先级) 代码 本文借鉴了"初识Java,实现简易计算器(带 ...

  3. 手把手带你利用栈来实现一个简易版本的计算器

    手把手带你利用栈来实现一个简易版本的计算器 什么是栈 栈的实现 通过数组实现 通过队列实现 实现思路 栈的经典应用场景 浏览器前进后退 括号配对 leetcode 20 题 表达式求值 leetcod ...

  4. Python:写了一个简易的同/环比分析器

    前言:数据分析中,传统描述性统计(即没有用到machine learning)还是在日常工作中占了很大一部分比重(或者说99%...),而同/环比分析更是占了绝大多数. 而传统处理中,一般都是用exc ...

  5. (简易)一元三次方程拆分/求根方法

    (简易)一元三次方程拆分/求根方法 例:x3+7x2+14x+8=0x^3+7x^2+14x+8=0x3+7x2+14x+8=0 式中常数8的因子有[1,2,4,8] 为了让因子之和或差等于二次项的系 ...

  6. python中用于释放类占用的资源的方法是()_编写一个简易计算器,要求根据输入的数字和四则运算符号,计算运算结果并输出。_学小易找答案...

    [简答题]20191220 课前作业 新工作页4.1的3-5-3页的填空题,参考教材P135-P144 [简答题]AutoCAD改编视图,尽量不用虚线 1. 主视图采用局部剖,表达右上角小圆筒(及孔) ...

  7. 使用java语言编写一个简易的计算器(完整代码与详细步骤都有哦!)

    [案例介绍] 1.案例描述 本案例要求利用Java Swing 图形组件开发一个可以进行简单的算术运算的图形化计算器. 2.运行结果 运行结果 [案例目标] 学会分析"简易计算器" ...

  8. Python课程设计,设计一个简易计算器

    在Python课程设计中,设计一个简易计算器,根据课本内容所写 import tkinter import tkinter.messagebox import reroot = tkinter.Tk( ...

  9. 在windows程序中嵌入Lua脚本引擎--建立一个简易的“云命令”执行的系统

    在<在windows程序中嵌入Lua脚本引擎--使用VS IDE编译Luajit脚本引擎>开始处,我提到某公司被指责使用"云命令"暗杀一些软件.本文将讲述如何去模拟一个 ...

  10. 用java实现一个简易自动提款机

    用java实现一个简易自动提款机,且有以下要求 如何实现呢?首先,我们定义一个用户类User,同时根据要求设计好属性(本人部分命名没有使用驼峰命名法,不够规范).因为一个人可能有多个卡,卡号又不能重复 ...

最新文章

  1. 1.3-date命令
  2. Selenium 爬虫时遇到的问题 Selenium message:session not created
  3. SaltStack(五) SaltStack与ZeroMQ
  4. Database之SQLSever:SQL命令实现查询之多表查询、嵌套查询、分页复杂查询,删除表内重复记录数据、连接(join、left join和right join简介及其区别)等案例之详细攻略
  5. NYOJ 642 牛奶
  6. sql是否包含多个字符串_工作中遇到的99%SQL优化,这里都能给你解决方案
  7. Tips_一级菜单栏实现
  8. DML数据操作语言练习
  9. 网页页面禁止用户复制
  10. react 组件怎么公用_在React中的组件之间共享数据
  11. 利用DroidCamX将手机摄像头打造成电脑高清摄像头
  12. Maven 安装教程
  13. 【大二下复习】新视野大学英语(第三版)第四册读写教程答案 + 期末复习翻译的部分题目
  14. JAVA:实现求StandardDeviation标准差算法(附完整源码)
  15. CF小组训练赛 Holiday 19
  16. uniapp 小程序 ios 音频播放 没有声音的问题
  17. 发明了万维网的他,如今却想亲手推翻它
  18. 【牛客网】 G-大水题
  19. 很好看的爱心表白代码(动态)
  20. 爬虫实战(1):直播吧网站的赛程表

热门文章

  1. win10提高开机速度只需要5步
  2. Greenplum数据库巡检报告
  3. 记录oracle表-字段小写转大写-自用
  4. 7年阿里Java人教你:秒杀活动就应该这样玩?
  5. 基于 SpringBoot + MyBatis-Plus 的公众号管理系统
  6. python计算消费额_11、Python 数据分析-用户消费行为分析
  7. winxp笔记本和有线路由器通过网线连接情况下的设置方法
  8. 小马激活工具激活系统后,电脑不能启动,出现错误 a disk read error occurred
  9. 他是“自由软件”之父,天才程序员,史上最伟大的黑客!最后却黯然离场
  10. U盘安装win7 启动一键u盘安装Ghost Win7系统教程