APP下载

从CT图片到3D互动解剖教学模型的制作—以颅骨解剖结构教学模型制作为例

2017-11-29

中国医学教育技术 2017年5期
关键词:脚本医学教育按钮

周 瑶

黄冈职业技术学院附属医院, 湖北 黄冈 438000

从CT图片到3D互动解剖教学模型的制作—以颅骨解剖结构教学模型制作为例

周 瑶

黄冈职业技术学院附属医院, 湖北 黄冈 438000

文章探讨了从CT图片到3D互动解剖教学模型的制作过程:通过一个真实人体的CT图片,进行3D解剖数字模型制作,并利用Unity3D制作成可在多个平台运行并互动的软件,以利于医学解剖教学。

CT图片;3D;Mimics;Unity 3D;C#;解剖;教学

医学教学信息化因行业间的差别通常难以互通,而一些现代信息手段也难以应用在医学教学上。医学教学课堂以演示文稿为主,网站互动成为主要互动方法,不能提高学生互动兴趣[1]。文章试图结合医学解剖教学,借助一些软件,制作成可互动的3D解剖模型,为教师教学和学生学习提供信息化教学的思路。

1 设计思路

将人体结构转换成3D数字模型,再将数字模型导入Unity成为场景或游戏对象,用脚本控制互动操作,最后根据需要面向电脑、Web或手机发布应用。互动操作包含自由旋转3D解剖模型、放大缩小模型[2]、在模型上标记并能去掉标记、“内窥镜”查看内部结构等功能[3]。

2 通过Mimics软件制备3D建模

人体结构的来源依靠CT或MRI数字图片。该次示例采用CT(GE Optima CT660)导出头部DICOM格式图片305张(层距0.625 mm),导入Mimics 17.0软件,进行阈值分割(thresholding),并生成蒙板(Mask),通过计算(Calculate 3D),得到STL文件。阈值分割是否满意,以及是否需要进一步进行使用区域增长(region growing)或者手工处理(Edit mask 工具),完全依赖于操作者对人体解剖的熟悉程度。获取到我们需要的结构(如骨、肌肉、脏器、皮肤等),以及符合教学的精准程度,需要具备一定的实践经验。生成的STL文件可用于3D打印[4]。

打开3Ds Max软件,导入STL文件,形成组后,导出为fbx格式模型。在3Ds Max中要注意设置导出单位为Micrometer。这样,用CT图片处理成3D模型已经完成。

3 通过Unity软件制备互动解剖模型并发布

打开Unity软件,创建一个新的项目。导入准备好的fbx解剖模型,以及场景中需要的各种资源,如欢迎界面图片、按钮图片等。

3.1场景设计

场景设计以及互相切换如下图。欢迎界面可用专业特色图片做背景,并设计按钮分别跳转需要的场景(如图1所示)。

图1 各场景切换及相互关系

3.2主要场景搭建和主要脚本文件

欢迎场景主要功能是一些可跳转的按钮和帮助文件。设计3个按钮,分别为:跳转帮助界面,说明操作方法;跳转加载场景,并通过异步加载进入互动场景;链接到教师个人主页或网页。3个按钮均挂载同一脚本WelcomeAndGo.cs:

using UnityEngine;

using System.Collections;

public class WelcomeAndGo:MonoBehaviour{

void OnClick()

{

switch(this.gameObject.name){

case"play":

Application.LoadLevel("loadload");

break;

case"help":

Application.LoadLevel("Dohelp");

break;

case"about":

Application.OpenURL("http://www.hbhgzy.com.

cn/Index.html");

break;

}

}

}

加载等待场景是因为导入的3D解剖模型可多达近106个面,加载资源需要一段时间,故直接在Main Camera上加载script组件Loaderr.cs:

using UnityEngine;

using System.Collections;

public class Loaderr:MonoBehaviour

{

AsyncOperation async;

private float progress;

void Start()

{

StartCoroutine(loadScene());

}

IEnumerator loadScene()

{

yield return new WaitForEndOfFrame();

async=Application.LoadLevelAsync("playtext");

yield return async;

}

void Update()

{

progress=async.progress*100f;

}

void OnGUI()

{

GUI.Label(new Rect(Screen.width*0.48f,Screen.height*0.7f,Screen.width*0.3f,Screen.height*0.05f),progress+"%");

GUI.HorizontalSlider(new Rect(Screen.width*0.25f,Screen.height*0.75f,Screen.width*0.5f,Screen.height*0.1f),progress,1,100);

GUI.Label(new Rect(Screen.width*0.4f,Screen.height*0.8f,Screen.width*0.3f,Screen.height*0.05f),"场景加载中,请稍等......");

}

}

互动场景是主要场景,先导入先前制作的fbx解剖模型,并在模型上加载C#脚本NewMove.cs,可以使用键盘(WSAD以及→←↑↓)控制模型的旋转和缩放(Z、X):

using UnityEngine;

using System.Collections;

public class NewMove:MonoBehaviour{

private float angle;

void Start(){

angle=5f;

}

void Update()

{

if(Input.GetKey(KeyCode.W)||Input.GetKey(KeyCode.DownArrow))

{

transform.Rotate(Vector3.right,angle);

}else if(Input.GetKey(KeyCode.S)||Input.GetKey(KeyCode.UpArrow))

{

transform.Rotate(Vector3.right,angle*-1);

}

if(Input.GetKey(KeyCode.A)||Input.GetKey(KeyCode.LeftArrow))

{

transform.Rotate(Vector3.forward,angle);

}else if(Input.GetKey(KeyCode.D)||Input.GetKey(KeyCode.RightArrow))

{

transform.Rotate(Vector3.forward,angle*-1);

}

if(Input.GetKey(KeyCode.X))

{

transform.localScale+=new Vector3(0.1f,0.1f,0.1f);

}else if(Input.GetKey(KeyCode.Z))

{

transform.localScale-=new Vector3(0.1f,0.1f,0.1f);

}

}

}

为了使操作更加直观,需要在场景中加载一些操作按钮脚本ButtonAndQuit.cs:

using UnityEngine;

using System.Collections;

public class ButtonAndQuit:MonoBehaviour

{

private float angle;

void Start()

{

angle=5f;

}

void OnGUI()

{

if(GUI.Button(new Rect(Screen.width-150,100,

100,50),"上翻")){transform.Rotate(Vector3.right,

angle);

}

if(GUI.Button(new Rect(Screen.width-150,200,

100,50),"下翻")){transform.Rotate(Vector3.right,

angle*-1);

}

if(GUI.Button(new Rect(Screen.width-200,150,

50,50),"左转")){transform.Rotate(Vector3.forward,

angle);

}

if(GUI.Button(new Rect(Screen.width-50,150,50,50),"右转")){transform.Rotate(Vector3.forward,

angle*-1);

}

if(GUI.Button(new Rect(Screen.width-150,Screen.height-50,100,50),"退出")){

Application.Quit();

}

if(GUI.Button(new Rect(Screen.width-150,Screen.height-150,100,50),"复位")){

Application.LoadLevel("playtext");

}

if(GUI.Button(new Rect(Screen.width-150,Screen.height-200,100,50),"内窥镜")){

Application.LoadLevel("EndMove");

}

if(GUI.Button(new Rect(Screen.width-150,Screen.height-100,100,50),"返回")){

Application.LoadLevel("wolcome");

}

}

}

另外,场景中加入一空游戏对象,加载以下脚本Signn.cs,以能够在互动时标记,方便教师讲解或学生作业(如图2所示)。

图2 头颅3D模型导入后制作的互动操作(缩放、旋转、标记)

using UnityEngine;

using System.Collections;

public class Signn:MonoBehaviour

{

void Update()

{

if(Input.GetMouseButtonDown(0)){

Ray rayy=Camera.main.ScreenPointToRay(Input.

mousePosition);

RaycastHit hit;

if(Physics.Raycast(rayy,out hit)){

if(hit.collider.gameObject.name=="head2017

0216"){

Vector3 pos=hit.point;

GameObject redboll=GameObject.CreatePrimi-

tive(PrimitiveType.Sphere);

redboll.transform.position=pos;

redboll.transform.localScale=hit.transform.localScale*0.05f;

redboll.renderer.material.color=Color.red;

if(Input.GetKey(KeyCode.Alpha1)){

redboll.renderer.material.color=Color.red;

}else if(Input.GetKey(KeyCode.Alpha2)){

redboll.renderer.material.color=Color.green;

}else if(Input.GetKey(KeyCode.Alpha3)){

redboll.renderer.material.color=Color.yellow;

}else if(Input.GetKey(KeyCode.Alpha4)){

redboll.renderer.material.color=Color.blue;

}

redboll.transform.parent=hit.transform;

redboll.AddComponent();

}

}

}

}

}

该例左键点击标记一个小球,按1、2、3、4等数字键可改变不同颜色。右键点击时标记的小球消失,在生成的小球上需要另加一个组件,脚本DesoryBoll.cs另为:

using UnityEngine;

using System.Collections;

public class DesoryBoll:MonoBehaviour{

void Update()

{

if(Input.GetMouseButtonDown(1))

{

Ray rayyy=Camera.main.ScreenPointToRay(Input.

mousePosition);

RaycastHit hitt;

if(Physics.Raycast(rayyy,out hitt))

{

Destroy(hitt.collider.gameObject);

}

}

}

}

内窥镜场景是为了更好地观察一些腔隙内部的结构(如图3所示),在“内窥镜”(摄像机)按钮,导入一个新场景。场景的摄像机上加载一个自由视角脚本EndMouselook.cs。

图3 模拟“内窥镜”看到的颅后窝及枕骨大孔

using UnityEngine;

using System.Collections;

public class EndMouselook:MonoBehaviour

{

public enum RotationAxess

{

MouseXAndY=0,

Mouse X=1,

Mouse Y=2

}

public RotationAxess axes=RotationAxess.MouseXAndY;

public float sensitivity_X=20F;public float sensitivity_Y=20F;

public float minimum_Y=-360F;

public float maximum_Y=360F;

public Texture2D picture1;

public GameObject target;

float rotation_Y=0F;

void Update()

{

target=GameObject.Find("Player");

transform.position=target.transform.position;

if(axes==RotationAxess.MouseXAndY){

float rotation_X=transform.localEulerAngles.y+Input.GetAxis("Mouse X")*sensitivity_X;

rotation_Y+=Input.GetAxis("Mouse Y")*sen-

sitivity_Y;

rotation_Y=Mathf.Clamp(rotation_Y,minimum_Y,maximum_Y);

transform.localEulerAngles=new Vector3(-rotation_Y,rotation_X,0);

}else if(axes==RotationAxess.MouseX){

transform.Rotate(0,Input.GetAxis("Mouse X")*sensitivity_X,0);

} else {

rotation_Y+=Input.GetAxis("Mouse Y")*sen-

sitivity_Y;

rotation_Y=Mathf.Clamp(rotation_Y,minimum_Y,maximum_Y);

transform.localEulerAngles=new Vector3(-rotation_Y,transform.localEulerAngles.y,0);

}

}

void OnGUI()

{

GUI.DrawTexture(new Rect(0,0,Screen.width,Sc-

reen.height),picture1);

if(GUI.Button(new Rect(Screen.width-150,Screen.height-100,100,50),"返回")){

Application.LoadLevel("playtext");

}

}

}

另增加一个空游戏对象,除加载上一个脚本外,须加载一个移动操作脚本EndMove01.cs,并与摄像机绑定在一起:

using UnityEngine;

using System.Collections;

public class EndMove01:MonoBehaviour

{

public float speed;

void Start()

{

speed=0.005f;

}

void Update()

{

if(Input.GetKey(KeyCode.W)){

transform.Translate(Vector3.forward*speed);

}else if(Input.GetKey(KeyCode.S)){

transform.Translate(Vector3.back*speed);

}

if(Input.GetKey(KeyCode.A)){

transform.Translate(Vector3.right*speed);

}else if(Input.GetKey(KeyCode.D)){

transform.Translate(Vector3.left*speed);

}

}

}

至此,整个互动制作基本完成,测试各场景跳转及操作无误后即可进行发布。根据不同需要,可以向不同平台发布,如PC,Mac & Linux Standalone、Web Player[5]、Android、iOS等平台,以方便各种应用的需要。向PC平台发布时,生成的软件无须安装,双击exe文件即可在自建的窗口中运行。

目前,软件的Web发布是流行趋势,将项目向网页(Web)平台发布,各种浏览器均能在线或单机运行此项目,这样3D解剖互动即能实现远程互动。在发布之前,要求Unity软件安装Unity Web Player Full插件,否则离线将无法运行。发布生成的文件html即可用常规浏览器打开,这在网页建设中是十分有利的。而对html进行参数设置(MonoDevelop脚本编辑器),可以修改logo、进度条、背景色等,以改善软件的运行状态。

4 讨论

此次教学模型的制作,用到3个软件和一个编程语言(C#),最后制作出能在多种平台上应用和操作的软件,达到用于教学的目的。

其中,Mimics软件的应用需要专业解剖学知识,能准确取到符合要求的3D模型。不同解剖部位的分割需要对解剖结构相当熟悉,还需要有时间上的耐心和分割技巧。简易直观的培训材料能帮助教师完成这个项目。

3Ds Max软件的作用仅将STL文件转换成Fbx文件,但它根据要求录制3D视频文件,这也可以作为教学之需。

Unity软件在近几年的3D游戏制作中极为火热,对制作教学软件也十分有利:①互动操作的实现方便、直观。不仅在解剖结构上的旋转、缩放、场景转换时方便,还可开发出一些数字交互,如用“药”后的“人体”改变、医疗处置操作等。②角色控制和自动导航等实现人体自身生理变化。如“食物”的吸收与转化[6]、血流动力学、神经传导、分子构象、细胞生理等的变化,都可用软件表现出来。③Unity的离子系统可以用于模拟人体的呼吸气流、循环血流、呕吐、咳嗽、大小便等生理状态。④Unity的动画系统和关节(Joint),可以用于人体运动的各种状态或康复运动状态,通过脚本表达关节的转动(角度)或肌肉的收缩,角度和强度将受程序控制,还可用于产科产程过程教学[7]。⑤渲染和布料有利用于控制人体皮肤属性、病理切片或针灸学的腧穴[8]。如皮肤的黄染、苍白、青紫等病理变化,以及各种传染病的皮疹、皮肤病病变。

因此,该类教学软件的制作,需要熟悉Mimics等制模软件,精通医学各专业知识,同时,应熟悉Unity3D软件的应用,掌握一门编程语言,如C#或者JaveScr-ipt,用于表现各种生理、病理过程。

医学教学信息化的实现,是一个跨学科的项目,旨在把医学解剖和生理、病理使用计算机技术表达出来,以供学生学习或健康教育的开展和传播[9]。

[1]朱振东,张林,任铭新.3D动画技术在人体解剖学实验教学中的应用探索[J].中国高等医学教育,2016(9):120-121

[2]王刚,郭育卓,欧阳钧.3D多媒体软件系统在人体解剖学教学中的应用探索[J].解剖学研究,2015,37(1):69-71

[3]温小鹏,张广健,付军科,等.3D腔镜视频资料在腔镜手术教学中的应用[J].西北医学教育,2016,24(3):489-491

[4]李忠海,唐家广,王华东,等.3D打印技术在骨科临床教学中的应用初探[J].中国医学教育技术,2016,30(2):198-200

[5]杨天化,辛均益,安国防,等.Web 3D技术及其在解剖学教学中的应用研究[J].中国现代医生,2016,54(9):120-127

[6]闻永,汤华军,李俊,等.3D解剖模拟技术结合PBL教学模式在肛肠解剖教学中的应用探析[J].解剖学研究,2016,38(5):414-416

[7]李圣洁,熊振芳,李琳,等.3D虚拟展示技术在妇产科护理学教学中的应用的质性研究[J].护理研究,2016,30(9):3412-3413

[8]张季,张宏如,董海艳,等.基于Unity 3D技术的数字人体腧穴教学信息系统的设计与实现[J].中国医学教育技术,2014,28(2):139-142

[9]夏爽,李松峰,黄娜.3D解剖结构教学模型在人体解剖实验教学中的研究[J].中国继续医学教育,2016,8(31):16-17

ProductionofCTimages-to-3Dinteractiveanatomyteachingmodel:Takingtheskullasanexample

ZhouYao

AffiliatedHospitalofHuanggangVocationalandTechnicalCollege,Huanggang438000,China

This article discusses the process of making CT images-to-3D interactive anatomy teaching model. By using CT images of a real human body, we make a 3D anatomy digital model. We also make interactive software with Unity3D that can be run on multiple platforms so as to facilitate medical anatomy teaching.

computed tomography (CT) image; 3D; Mimics; Unity 3D; C#; anatomy; teaching

2017-03-31

周瑶(1973-),男,内蒙古托县人,副主任医师,本科,主要研究方向:医学教育、儿科医学。

G434

:A

:1004-5287(2017)05-0541-06

:10.13566/j.cnki.cmet.cn61-1317/g4.201705014

猜你喜欢

脚本医学教育按钮
酒驾
当你面前有个按钮
安奇奇与小cool 龙(第二回)
提升医学教育能级 培养拔尖创新人才
2019年第一批口腔医学国家级继续医学教育项目
快乐假期
死循环
小编的新年愿望
医学生怎么看待现在的医学教育
内心不能碰的按钮