5.3.7 影象重取樣
影象重取樣後圖像的維數會發生改變。當重取樣影象小於原影象維數時,稱為降取樣;當重取樣影象維數大於原影象時,稱為升取樣。VTK中可以方便的對影象進行重取樣。vtkImageShrink3D類實現影象降取樣。降取樣需要設定每個方向的取樣率,降取樣率越大,影象越模糊。升取樣的原理與降取樣原理一致,只是增加取樣點數來增加影象的維數。
#include <vtkSmartPointer.h> #include <vtkBMPReader.h> #include <vtkImageData.h> #include <vtkImageShrink3D.h> //降取樣標頭檔案 #include <vtkImageMagnify.h> //升取樣標頭檔案 #include <vtkImageActor.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkInteractorStyleImage.h> //互動樣式 int main() { vtkSmartPointer<vtkBMPReader> reader = vtkSmartPointer<vtkBMPReader>::New(); reader->SetFileName("data\\lena.bmp"); reader->Update(); vtkSmartPointer<vtkImageShrink3D> shrinkFilter = vtkSmartPointer<vtkImageShrink3D>::New(); shrinkFilter->SetInputConnection(reader->GetOutputPort());//建立管道 shrinkFilter->SetShrinkFactors(16, 16, 1);//設定降取樣率 shrinkFilter->Update(); vtkSmartPointer<vtkImageMagnify> magnifyFilter = vtkSmartPointer<vtkImageMagnify>::New(); magnifyFilter->SetInputConnection(reader->GetOutputPort()); magnifyFilter->SetMagnificationFactors(10, 10, 1); magnifyFilter->Update(); int originalDims[3]; reader->GetOutput()->GetDimensions(originalDims); double originalSpacing[3]; reader->GetOutput()->GetSpacing(originalSpacing); int shrinkDims[3]; shrinkFilter->GetOutput()->GetDimensions(shrinkDims); double shrinkSpacing[3]; shrinkFilter->GetOutput()->GetSpacing(shrinkSpacing); int magnifyDims[3]; magnifyFilter->GetOutput()->GetDimensions(magnifyDims); double magnifuSpacing[3]; magnifyFilter->GetOutput()->GetSpacing(magnifuSpacing); std::cout << "原始維度: " << originalDims[0] << "*" << originalDims[1] << "*" << originalDims[2] << std::endl; std::cout << "原始畫素間距: " << originalSpacing[0] << " " << originalSpacing[1] << " " << originalSpacing[2] << std::endl; std::cout << "降取樣維度: " << shrinkDims[0] << "*" << shrinkDims[1] << "*" << shrinkDims[2] << std::endl; std::cout << "降取樣畫素間距:" << shrinkSpacing[0] << " " << shrinkSpacing[1] << " " << shrinkSpacing[2] << std::endl; std::cout << "升取樣維度: " << magnifyDims[0] << "*" << magnifyDims[1] << "*" << magnifyDims[2] << std::endl; std::cout << "升取樣畫素間距:" << magnifuSpacing[0] << " " << magnifuSpacing[1] << " " << magnifuSpacing[2] << std::endl; vtkSmartPointer<vtkImageActor> origActor = vtkSmartPointer<vtkImageActor>::New(); origActor->SetInputData(reader->GetOutput()); vtkSmartPointer<vtkImageActor> shrinkActor = vtkSmartPointer<vtkImageActor>::New(); shrinkActor->SetInputData(shrinkFilter->GetOutput()); vtkSmartPointer<vtkImageActor> magnifyActor = vtkSmartPointer<vtkImageActor>::New(); magnifyActor->SetInputData(magnifyFilter->GetOutput()); /////////////////////////////////////////////////////// double origView[4] = { 0, 0, 0.3, 1.0 }; double shrinkView[4] = { 0.3, 0, 0.6, 1.0 }; double magnifyView[4] = { 0.6, 0, 1, 1 }; vtkSmartPointer<vtkRenderer> origRender = vtkSmartPointer<vtkRenderer>::New(); origRender->SetViewport(origView);//檢視 origRender->AddActor(origActor);//物件 origRender->ResetCamera();//相機 origRender->SetBackground(0, 0, 0);//背景 vtkSmartPointer<vtkRenderer> shrinkRender = vtkSmartPointer<vtkRenderer>::New(); shrinkRender->SetViewport(shrinkView); shrinkRender->AddActor(shrinkActor); shrinkRender->ResetCamera(); shrinkRender->SetBackground(0, 0, 0); vtkSmartPointer<vtkRenderer> magnifyRender = vtkSmartPointer<vtkRenderer>::New(); magnifyRender->SetViewport(magnifyView); magnifyRender->AddActor(magnifyActor); magnifyRender->ResetCamera(); magnifyRender->SetBackground(0, 0, 0); ///////////////////////////////////////////////// vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New(); rw->AddRenderer(origRender); rw->AddRenderer(shrinkRender); rw->AddRenderer(magnifyRender); rw->SetSize(720, 240); rw->SetWindowName("Image-Shrink-Magnify"); rw->Render(); //////////////////////////////////////////////// vtkSmartPointer<vtkRenderWindowInteractor> rwi = vtkSmartPointer<vtkRenderWindowInteractor>::New(); vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New(); rwi->SetInteractorStyle(style); rwi->SetRenderWindow(rw); rwi->Initialize(); rwi->Start(); return 0; }
執行結果:
vtkImageShrink3D通過SetShrinkFactors()設定X、Y和Z方向的取樣率,引數為三個int型別資料。vtkImageMagnify通過SetMagnificationFactors設定相應的放大采樣率。從圖中可以看成,重取樣影象已經變得十分模糊了。而升取樣影象則變化不大。程式中輸出了原圖和重取樣影象的維數和畫素間隔,從輸出來看,原影象的維數為512x512,縮小16倍後,影象維數變為32x32。需要注意的是,原圖的畫素間隔為(1,1,1),而重取樣後像素間隔變為(16, 16, 1),這是因為取樣是在世界座標系下進行的,當取樣影象的維數減小時,取樣的畫素間隔也相應的變大,這樣保持影象的區域不會發生改變。同樣的道理,當升取樣後圖像的維數變為原來的10倍,而畫素間隔變為原來的十分之一。
注:此文知識學習筆記,僅記錄完整程式和實現結果,具體原理參見:
https://blog.csdn.net/www_doling_net/article/details/8541534
https://blog.csdn.net/shenziheng1/article/category/6114053/4
參考資料:
1.《The Visualization Toolkit – AnObject-Oriented Approach To 3D Graphics (4th Edition)》
2. 張曉東, 羅火靈. VTK圖形影象開發進階[M]. 機械工業出版社, 2015.