日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

区域提取

發布時間:2025/3/15 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 区域提取 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

5.7 區域提取

5.7.1 提取感興趣區域?

感興趣區域(Volum of Interest)是指圖像內部的一個子區域。在VTK中vtkExtractVOI類實現由用戶指定的區域范圍提取圖像的子圖像。該Filter的輸入和輸出都是一個vtkImageData,因此其結果可以直接作為圖像保存。

?

?? 1:????? vtkSmartPointer<vtkBMPReader> reader =

?? 2:????????? vtkSmartPointer<vtkBMPReader>::New();

?? 3:????? reader->SetFileName ( "lena.bmp" );

?? 4:????? reader->Update();

? ?5:??

?? 6:????? int dims[3];

?? 7:????? reader->GetOutput()->GetDimensions(dims);

?? 8:??

?? 9:????? vtkSmartPointer<vtkExtractVOI> extractVOI =

? 10:????????? vtkSmartPointer<vtkExtractVOI>::New();

? 11:????? extractVOI->SetInputConnection(reader->GetOutputPort());

? 12:????? extractVOI->SetVOI(dims[0]/4.,3.*dims[0]/4.,dims[1]/4.,3.*dims[1]/4., 0, 0);

? 13:????? extractVOI->Update();

?

上例代碼實現了提取一副圖像的子區域。首先讀取一個圖像,并獲取圖像的維數。然后定義vtkExtractVOI對象,該對象接收兩個輸入一個是圖像數據,第二個是區域大小。設置區域大小的函數原型:

void SetVOI(int _arg1, int _arg2, int _arg3, int _arg4, int _arg5, int _arg6)

void SetVOI(int _arg[])

其參數是提取的區域各個方向的大小,共6個參數,依次表示x方向最小值,x方向最大值,y方向最小值,y方向最大值,z方向最小值和z方向最大值。上例中由于讀取的是二維圖像,因此z方向的區域為[0,0],而在x方向范圍為[ dims[0]/4 , 3*dims[0]/4 ],y方向范圍為[ dims[1]/4 , 3*dims[1]/4 ],即提取圖像原圖中間1/4圖像。執行結果如下:

?

圖5.18 提取感興趣區域

5.7.2 三維圖像切片提取

切片是指三維圖像中的一個切面對應的圖像。切面可以是過圖像內部一點且平行于XY、YZ、XZ平面的平面,也可以是任意的過三維圖像內部一點任意方向的平面。通過提取切片可以方便的瀏覽和分析圖像內部組織結構,是醫學圖像瀏覽軟件中的一個重要的功能。在VTK中vtkImageReslice類實現圖像切片提取功能。下面首先看一段切片提取的代碼。

1:? vtkSmartPointer<vtkMetaImageReader> reader =

?? 2:???? vtkSmartPointer<vtkMetaImageReader>::New();

?? 3:? reader->SetFileName ( " brain.mhd" );

?? 4:? reader->Update();

?? 5:? ?

?? 6:? int extent[6];

?? 7:? double spacing[3];

?? 8:? double origin[3];

?? 9:? ?

? 10:? reader->GetOutput()->GetExtent(extent);

? 11:? reader->GetOutput()->GetSpacing(spacing);

? 12:? reader->GetOutput()->GetOrigin(origin);

? 13:? ?

? 14:? double center[3];

? 15:? center[0] = origin[0] + spacing[0] * 0.5 * (extent[0] + extent[1]);

? 16:? center[1] = origin[1] + spacing[1] * 0.5 * (extent[2] + extent[3]);

? 17:? center[2] = origin[2] + spacing[2] * 0.5 * (extent[4] + extent[5]);

? 18:? ?

? 19:? static double axialElements[16] = {

? 20:???? 1, 0, 0, 0,

? 21:???? 0, 1, 0, 0,

? 22:???? 0, 0, 1, 0,

? 23:???? 0, 0, 0, 1 };

? 24:? ?

? 25:? vtkSmartPointer<vtkMatrix4x4> resliceAxes =

? 26:???? vtkSmartPointer<vtkMatrix4x4>::New();

? 27:? resliceAxes->DeepCopy(axialElements);

? 28:? ?

? 29:? resliceAxes->SetElement(0, 3, center[0]);

? 30:? resliceAxes->SetElement(1, 3, center[1]);

? 31:? resliceAxes->SetElement(2, 3, center[2]);

? 32:? ?

? 33:? ?

? 34:? vtkSmartPointer<vtkImageReslice> reslice =

? 35:???? vtkSmartPointer<vtkImageReslice>::New();

? 36:? reslice->SetInputConnection(reader->GetOutputPort());

? 37:? reslice->SetOutputDimensionality(2);

? 38:? reslice->SetResliceAxes(resliceAxes);

? 39:? reslice->SetInterpolationModeToLinear();

? 40:? ?

? 41:? vtkSmartPointer<vtkLookupTable> colorTable =

? 42:???? vtkSmartPointer<vtkLookupTable>::New();

? 43:? colorTable->SetRange(0, 1000);

? 44:? colorTable->SetValueRange(0.0, 1.0);

? 45:? colorTable->SetSaturationRange(0.0, 0.0);

? 46:? colorTable->SetRampToLinear();

? 47:? colorTable->Build();

? 48:? ?

? 49:? vtkSmartPointer<vtkImageMapToColors> colorMap =

? 50:???? vtkSmartPointer<vtkImageMapToColors>::New();

? 51:? colorMap->SetLookupTable(colorTable);

? 52:? colorMap->SetInputConnection(reslice->GetOutputPort());

? 53:? ?

? 54:? vtkSmartPointer<vtkImageActor> imgActor =

? 55:???? vtkSmartPointer<vtkImageActor>::New();

? 56:? imgActor->SetInput(colorMap->GetOutput());

? 57:? ?

? 58:? vtkSmartPointer<vtkRenderer> renderer =

? 59:???? vtkSmartPointer<vtkRenderer>::New();

? 60:? renderer->AddActor(imgActor);

? 61:? renderer->SetBackground(.4, .5, .6);

? 62:? ?

? 63:? vtkSmartPointer<vtkRenderWindow> renderWindow =

? 64:???? vtkSmartPointer<vtkRenderWindow>::New();

? 65:? renderWindow->SetSize(500, 500);

? 66:? renderWindow->AddRenderer(renderer);

? 67:? ?

? 68:? vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =

? 69:???? vtkSmartPointer<vtkRenderWindowInteractor>::New();

? 70:? vtkSmartPointer<vtkInteractorStyleImage> imagestyle =

? 71:???? vtkSmartPointer<vtkInteractorStyleImage>::New();

? 72:? ?

? 73:? renderWindowInteractor->SetInteractorStyle(imagestyle);

? 74:? renderWindowInteractor->SetRenderWindow(renderWindow);

? 75:? renderWindowInteractor->Initialize();

? 76:? ?

? 77:? renderWindowInteractor->Start();

?

首先通過vtkMetaImageReader讀取一副醫學三維圖像,并獲取得到圖像范圍(extent),原點和像素間隔;由這三個參數可以計算圖像的中心位置center;接下來定義了切面的變換矩陣axialElements,該矩陣的前三列分別表示x、y和z方向向量,第四列為中心點坐標;代碼中的axialElements表示切面變換矩陣與當前坐標系一致,且切面為過中心點center,并平行于XY平面的平面。當前,定義該切面時,也可以是其他平面,甚至是任意平面,但是必須要過圖像內部點。下面給出了一個常用的變換矩陣:

?

static double coronalElements[16] = {

?1, 0, 0, 0,

?0, 0, 1, 0,

0,-1, 0, 0,

?0, 0, 0, 1 }; 提取平行于XZ平面的切片

?

static double sagittalElements[16] = {

?0, 0,-1, 0,

?1, 0, 0, 0,

?0,-1, 0, 0,

?0, 0, 0, 1 }; 提取平行于YZ平面的切片

?

static double obliqueElements[16] = {

?1, 0, 0, 0,

?0, 0.866025, -0.5, 0,

?0, 0.5, 0.866025, 0,

?0, 0, 0, 1 }; 提取斜切切片

?

注意使用這些變換矩陣的時候,需要將第四列替換為切片經過圖像的一個點坐標,上例中將圖像的中心添加到axialElements矩陣,并通過函數SetResliceAxes設置變換矩陣,SetOutputDimensionality(2)指定輸出的圖像為一個二維圖像;而函數SetInterpolationModeToLinear()則指定了切面提取中的差值方式為線性差值,另外該類中還提供了其他的差值方式:

SetInterpolationModeToNearestNeighbor():最近鄰方式

SetInterpolationModeToCubic():三次線性差值

設置完畢后,執行Update()即可完成切面計算。運行結果如下圖:

?

圖5.19 切片提取

5.7.3 擴展

學習三維圖像切面的提取后,我們在上節的程序上做一個擴展,實現一個稍微復雜的程序——通過滑動鼠標來切換三維圖像切片,這也是醫學圖像處理軟件中一個很基本的功能。實現該功能難點是怎樣在VTK中控制鼠標來實時提取圖像切片。在前面的章節中已經介紹觀察者/命令(Observer/Command)模式,我們也采用這種機制來實現。VTK中鼠標消息是在交互類型對象(interactorstyle)中響應,因此通過為交互類型對象(interactorstyle)添加觀察者(observer)來監聽相應的消息,當消息觸發時,由命令模式執行相應的回調函數。閑話少說,放代碼。

? 1:? class vtkImageInteractionCallback : public vtkCommand

?? 2:? {

?? 3:? public:

?? 4:? ?

?? 5:????? static vtkImageInteractionCallback *New()

?? 6:????? {

?? 7:????????? return new vtkImageInteractionCallback;

?? 8:????? }

?? 9:? ?

? 10:????? vtkImageInteractionCallback()

? 11:????? {

? 12:????????? this->Slicing = 0;

? 13:????????? this->ImageReslice = 0;

? 14:????????? this->Interactor = 0;

? 15:????? }

? 16:? ?

? 17:????? void SetImageReslice(vtkImageReslice *reslice)

? 18:????? {

? 19:????????? this->ImageReslice = reslice;

? 20:????? }

? 21:? ?

? 22:????? vtkImageReslice *GetImageReslice()

? 23:????? {

? 24:????????? return this->ImageReslice;

? 25:????? }

? 26:? ?

? 27:????? void SetInteractor(vtkRenderWindowInteractor *interactor)

? 28:????? {

? 29:????????? this->Interactor = interactor;

? 30:????? }

? 31:? ?

? 32:????? vtkRenderWindowInteractor *GetInteractor()

? 33:????? {

? 34:????????? return this->Interactor;

? 35:????? }

? 36:? ?

? 37:????? virtual void Execute(vtkObject *, unsigned long event, void *)

? 38:????? {

? 39:????????? vtkRenderWindowInteractor *interactor = this->GetInteractor();

? 40:? ?

? 41:????????? int lastPos[2];

? 42:????????? interactor->GetLastEventPosition(lastPos);

? 43:????????? int currPos[2];

? 44:????????? interactor->GetEventPosition(currPos);

? 45:? ?

? 46:????????? if (event == vtkCommand::LeftButtonPressEvent)

? 47:????????? {

? 48:????????????? this->Slicing = 1;

? 49:????????? }

? 50:????????? else if (event == vtkCommand::LeftButtonReleaseEvent)

? 51:????????? {

? 52:????????????? this->Slicing = 0;

? 53:????????? }

? 54:????????? else if (event == vtkCommand::MouseMoveEvent)

? 55:????????? {

? 56:????????????? if (this->Slicing)

? 57:????????????? {

? 58:????????????????? vtkImageReslice *reslice = this->ImageReslice;

? 59:? ?

? 60:? ????????????????// Increment slice position by deltaY of mouse

? 61:????????????????? int deltaY = lastPos[1] - currPos[1];

? 62:? ?

? 63:????????????????? reslice->Update();

? 64:????????????????? double sliceSpacing = reslice->GetOutput()->GetSpacing()[2];

? 65:????????????????? vtkMatrix4x4 *matrix = reslice->GetResliceAxes();

? 66:????????????????? // move the center point that we are slicing through

? 67:????????????????? double point[4];

? 68:????????????????? double center[4];

? 69:????????????????? point[0] = 0.0;

? 70:????????????????? point[1] = 0.0;

? 71:????????????????? point[2] = sliceSpacing * deltaY;

? 72:????????????????? point[3] = 1.0;

? 73:????????????????? matrix->MultiplyPoint(point, center);

? 74:????????????????? matrix->SetElement(0, 3, center[0]);

? 75:????????????????? matrix->SetElement(1, 3, center[1]);

? 76:????????????????? matrix->SetElement(2, 3, center[2]);

? 77:????????????????? interactor->Render();

? 78:????????????? }

? 79:????????????? else

? 80:????????????? {

? 81:??? ??????????????vtkInteractorStyle *style = vtkInteractorStyle::SafeDownCast(

? 82:????????????????????? interactor->GetInteractorStyle());

? 83:????????????????? if (style)

? 84:????????????????? {

? 85:????????????????????? style->OnMouseMove();

? 86:???? ?????????????}

? 87:????????????? }

? 88:????????? }

? 89:????? }

? 90:? ?

? 91:? private:

? 92:????? int Slicing;

? 93:????? vtkImageReslice *ImageReslice;

? 94:????? vtkRenderWindowInteractor *Interactor;

? 95:? };

?

vtkImageInteractionCallback繼承自vtkCommand類,并覆蓋父類函數Execute()。該類提供了兩個接口:SetImageReslice和SetInteractor。SetImageReslice用以設置vtkImageSlice對象,vtkImageSlice根據設置的變換矩陣提取三維圖像切片。SetInteractor用以設置vtkRenderWindowInteractor,vtkRenderWindowInteractor類對象負責每次提取切片后刷新視圖。

下面我們重點來看一下Execute函數,該函數提供了具體的切片提取功能。在該函數里面,主要監聽了三個消息:

vtkCommand::LeftButtonPressEvent,

vtkCommand::LeftButtonReleaseEvent,

vtkCommand::MouseMoveEvent,

前兩個消息分別是鼠標左鍵的按下和彈起消息。當鼠標左鍵按下時,就設置切片提取標志為1,而當彈起時,將標志置為0。這樣在鼠標移動時,只有在確定切片提取標志為1時,執行切片提取功能。

vtkCommand::MouseMoveEvent即為鼠標移動消息。當檢測到該消息時,首先檢查切片提取標志,當為1時提取切片。提取切片時,需要為vtkImageSlice對象設置變換矩陣。這里在函數開始時,首先獲取了鼠標滑動的前后兩次點的位置lastPos和currPos。然后根據兩點的Y坐標差deltaY,計算新的中心點center并變換至vtkImageSlice當前變換矩陣中,得到變換中心點,將其設置到原來的變換矩陣matrix中,并設置到vtkImageSlice中,最后執行interactor->Render()即可不斷的根據鼠標移動刷新圖像。

Command對象定義完畢后,即可為交互對象InteractorStyle添加觀察者,響應鼠標消息。這里可以在上節的程序上進行修改,前面代碼一致,只需要在最后添加如下代碼:

1:????? vtkSmartPointer<vtkImageInteractionCallback> callback =

?? 2:????????? vtkSmartPointer<vtkImageInteractionCallback>::New();

?? 3:????? callback->SetImageReslice(reslice);

?? 4:????? callback->SetInteractor(renderWindowInteractor);

?? 5:??

?? 6:????? imagestyle->AddObserver(vtkCommand::MouseMoveEvent, callback);

?? 7:????? imagestyle->AddObserver(vtkCommand::LeftButtonPressEvent, callback);

?? 8:????? imagestyle->AddObserver(vtkCommand::LeftButtonReleaseEvent, callback);

?? 9:??

? 10:????? renderWindowInteractor->Start();

這里主要是定義了vtkImageInteractionCallback對象,并設置vtkImageSlice對象和vtkRenderWindowInteractor對象。然后為交互對象vtkInteractorStyle添加觀察者來監控相應的消息,這里主要是三個消息:

vtkCommand::LeftButtonPressEvent,

vtkCommand::LeftButtonReleaseEvent,

vtkCommand::MouseMoveEvent,

當響應到這三個消息時,立即執行vtkImageInteractionCallback的Execute函數,以便實現切片的實時提取和更新。完成以后,運行程序,當鼠標在圖像上移動時,會發現圖像會跟著鼠標的移動而變化,神奇吧?有興趣的話,還可以實現YZ平面、XZ平面切片提取,甚至是任意方向的切面提取。

?

==========歡迎轉載,轉載時請保留該聲明信息==========

版權歸@東靈工作室所有,更多信息請訪問東靈工作室


教程系列導航:http://blog.csdn.net/www_doling_net/article/details/8763686

================================================


總結

以上是生活随笔為你收集整理的区域提取的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 91人妻一区二区三区蜜臀 | 嫩草研究院在线 | 日韩av一区在线 | 日日噜噜噜噜久久久精品毛片 | 亚洲综合视频在线观看 | 日本做爰三级床戏 | 天天撸在线视频 | 国产私人影院 | 一区视频在线 | 丝袜五月天 | 在线看三级 | 国产精品制服丝袜 | 欧美综合亚洲图片综合区 | 麻豆日韩| 国产成人91精品 | 亚洲精品乱码久久久久久麻豆不卡 | 公车激情云雨小说 | 亚洲av永久纯肉无码精品动漫 | 97超碰伊人 | 乱淫的女高中暑假调教h | 色悠久久综合 | 耳光调教vk | 日本少妇在线观看 | 在线观看久草 | 97久久久久久久久久 | 丰满少妇一区二区三区 | 日韩成人综合 | 亚洲一区二区精品在线 | 人妻少妇精品无码专区 | 日韩一区二区三区三四区视频在线观看 | 黄色网在线免费观看 | 精品久久毛片 | 美国一级黄色大片 | 国产私人影院 | 干干日日 | 亚洲jlzzjizz少妇 | 青娱乐97 | 九九爱国产 | 视频在线一区二区三区 | 性插视频在线观看 | 自拍 亚洲 欧美 | 国产免费一区二区三区 | av观看在线免费 | av在线电影观看 | 成人免费在线播放视频 | 黑人操bb| 爱爱视频网站 | 欧美在线亚洲 | 国产一区二区三区四区在线观看 | 深夜国产视频 | 色欲亚洲Av无码精品天堂 | 夜色综合网 | 精品国产人妻一区二区三区 | 亚洲欧美日韩另类在线 | 中文字幕不卡视频 | 国产免费福利视频 | 免费拍拍拍网站 | 一个人在线观看免费视频www | 免费观看毛片 | 樱花视频在线观看 | 亚洲激情在线 | 亚洲综合色吧 | 可以直接看的毛片 | av国语| 国产成人一区二区三区影院在线 | 久久亚洲一区二区三区四区五区 | 欧美日韩亚洲另类 | 日韩精彩视频 | 最新黄色av网站 | 黄色网页在线看 | 色呦呦入口 | 欧美日本成人 | 亚洲精品久久久久久久蜜桃臀 | 自拍视频网址 | 视频这里只有精品 | 日本三级大全 | 亚洲综合五月 | 色偷偷免费费视频在线 | 亚洲福利网站 | 美女88av| 中文字幕av第一页 | wwwxxxx国产 | 少妇被爽到高潮动态图 | 精品熟女一区 | 人成在线| 国产在线观看无码免费视频 | 美女的奶胸大爽爽大片 | av生活片 | 91亚洲专区 | 国产精品九九九九九 | 日韩欧美视频网站 | 香蕉视频在线免费 | 国模在线| 波多野结衣视频在线看 | 丰满少妇一级片 | 免费观看久久久 | 婷婷色中文网 | 欧美a一级 | 欧美一级免费黄色片 |