1. 程式人生 > 實用技巧 >ITK 實現 RBG 圖片讀取、平移旋轉等操作

ITK 實現 RBG 圖片讀取、平移旋轉等操作

灰度圖讀取介紹

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;