ITK 實現 RBG 圖片讀取、平移旋轉等操作
阿新 • • 發佈:2020-08-11
灰度圖讀取介紹
itk 預設讀取圖片的格式為灰度圖,讀取過程分為下面三個部分:
- 定義 PixelType,一般 為 float 或 unsigned char;
- 通過 itk::Image<Pixeltype,Dimension> 完成影象型別的定義;
- 利用 itk::FileImageName 建立 reader 例項,並通過檔案路徑對單通道圖片、或 Mha 三維影象讀取,
下方為其中的核心程式碼:
using PixlType = unsigned char; using ImageType = itk::Image<PixlType,3>; using ReaderType = itk::ImageFileReader<ImageType>; ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName(OpenPath);
RGB 讀取流程
與灰度圖不同的是,針對 RGB 影象,ITK 提供了一個專有的類 itk::RGBPixel() ,用於畫素型別定義,而後面影象型別定義、影象讀取與 Gray 圖沒有太大的區別
為了加深理解應用,這裡寫了一個例子;程式碼功能流程如下:
- 讀取 RGB 影象
- 影象讀取之後沿著X 、Y軸分別平移,以影象中心作為中心進行旋轉某一角度;
- 變換後的影象再以 RGB 影象格式進行儲存;
#include<itkRGBPixel.h> #include<itkImage.h> #include<itkImageFileReader.h> #include<itkImageFileWriter.h> #include<itkPNGImageIOFactory.h> #include<itkResampleImageFilter.h> #include<itkCenteredRigid2DTransform.h> #include<iostream> #include<cmath> # define PI acos(-1) using namespace std; int RGB_Read_main() { itk::PNGImageIOFactory::RegisterOneFactory(); string Open_Path = "D:/ceshi1/1/203.png"; string Save_Path = "D:/ceshi1/1/203_1.png"; using PixelType = itk::RGBPixel<unsigned char>; constexpr unsigned int Dimension = 2; using ImageType = itk::Image<PixelType, Dimension>; using ReadType = itk::ImageFileReader<ImageType>; using WriteType = itk::ImageFileWriter<ImageType>; ReadType::Pointer reader = ReadType::New(); WriteType::Pointer writer = WriteType::New(); reader->SetFileName(Open_Path); writer->SetFileName(Save_Path); reader->Update(); const ImageType::SpacingType& spacing = reader->GetOutput()->GetSpacing(); const ImageType::PointType& origin = reader->GetOutput()->GetOrigin(); const ImageType::SizeType size = reader->GetOutput()->GetLargestPossibleRegion().GetSize(); using TransformType = itk::CenteredRigid2DTransform<double>; using RescaleImageType = itk::ResampleImageFilter<ImageType, ImageType>; TransformType::Pointer transform = TransformType::New(); RescaleImageType::Pointer rescale = RescaleImageType::New(); TransformType::OutputVectorType translation1; translation1[0] = 12.0; translation1[1] = 13.1; const double imageCenterx = origin[0] + spacing[0] * size[0] / 2.0; const double imageCenterY = origin[1] + spacing[1] * size[1] / 2.0; transform->SetTranslation(translation1); transform->SetAngle(2 * PI / 180.0); TransformType::OutputPointType Center; Center[0] = imageCenterx; Center[1] = imageCenterY; transform->SetCenter(Center); cout << "Center1 ::" << imageCenterx << endl; cout << "Center2::" << imageCenterY << endl; rescale->SetDefaultPixelValue(100); rescale->SetTransform(transform); rescale->SetSize(reader->GetOutput()->GetLargestPossibleRegion().GetSize()); rescale->SetOutputOrigin(reader->GetOutput()->GetOrigin()); rescale->SetOutputSpacing(reader->GetOutput()->GetSpacing()); rescale->SetOutputDirection(reader->GetOutput()->GetDirection()); rescale->SetInput(reader->GetOutput()); writer->SetInput(rescale->GetOutput()); try { writer->Update(); cout << "Sucessfully Converted !" << endl; return EXIT_SUCCESS; } catch (itk::ExceptionObject & e) { cout << e.what() << endl; cout << "Expectation Caught!!!" << endl; return EXIT_FAILURE; } }
程式碼中實現影象變換,用到的是 itkCenteredRigid2DTransform.h 類,該類的基本功能就是面向 2D 影象進行中心剛性變換;用 CenteredRigid2DTransform 做變換時,需要提供三個引數:1,x、y 軸平移量;2,旋轉中心座標;3,旋轉弧度(弧度 = 角度*Π/180,這裡設定的是雙精度 );
最後把 transform 矩陣應用到源影象時,需要藉助 ResampleImageFilter 對源影象做重取樣操作,最後結果如下:
這裡設定的引數分別為:
- X、Y 軸平移量12.0,13.1;
- 旋轉中心:源影象中心點;
- 旋轉角度:20°*Π/180;