问题描述

在MRI扫描的时候,可能会由于病人体位的关系,出现扫描图像是倾斜的状况,如下图所示。

在特定的情况下,病人的倾斜状态会影响到后面我们数据的处理。比如在MRI头部自动定位通常是通过AC-PC连线来确定的,如果病人头部存在倾斜,则AC-PC点可能并不在同一个矢状位面上,给定位增加了难度。

如何进行倾斜校正

切斜角度计算的方法很多,常见的有基于主轴变换的方法[1]和基于傅里叶变换的方法[2]。我这里主要介绍使用主轴变换来计算偏转角度。

图像矩

图像矩主要表征了图像区域的几何特征,又称为几何矩。由于其具有不变特征,又称其为不变矩,它的主要思想是使用对变换不敏感的基于区域的几个矩作为形状特征。在医学图像处理经常被应用来作为预配准步骤。

在图像处理中, 我们把灰度图像看作为一块平板,每个像素点的值为该点处的密度。对某点求期望就是该图像在该点处的矩。我们一般讲的图像矩,就是原点矩。一阶矩和零阶矩就可以计算某个形状的中心,而二阶矩就可以计算形状的方向。

零阶矩:

  • M00=∑x∑yV(x,y)M_{00}=\sum_{x} \sum_{y} V(x,y)M00​=∑x​∑y​V(x,y)

一阶矩:

  • M10=∑x∑yx⋅V(x,y)M_{10}=\sum_{x} \sum_{y}x \cdot V(x,y)M10​=∑x​∑y​x⋅V(x,y)
  • M01=∑x∑yy⋅V(x,y)M_{01}=\sum_{x} \sum_{y}y \cdot V(x,y)M01​=∑x​∑y​y⋅V(x,y)

重心坐标:

  • xc=M10M00x_{c}=\frac{M_{10}}{M_{00}}xc​=M00​M10​​
  • yc=M01M00y_{c}=\frac{M_{01}}{M_{00}}yc​=M00​M01​​

二阶矩:

  • M20=∑x∑yx2⋅V(x,y)M_{20}=\sum_{x} \sum_{y} x^{2} \cdot V(x, y)M20​=∑x​∑y​x2⋅V(x,y)
  • M02=∑x∑yy2⋅V(x,y)M_{02}=\sum_{x} \sum_{y} y^{2} \cdot V(x, y)M02​=∑x​∑y​y2⋅V(x,y)
  • M11=∑x∑yxy⋅V(x,y)M_{11}=\sum_{x} \sum_{y} xy \cdot V(x, y)M11​=∑x​∑y​xy⋅V(x,y)

物体形状方向计算:

  • θ=12arctan⁡(2ba−c),θ∈[−90∘,90∘]\theta=\frac{1}{2} \arctan \left(\frac{2 b}{a-c}\right), \theta \in\left[-90^{\circ}, 90^{\circ}\right]θ=21​arctan(a−c2b​),θ∈[−90∘,90∘]

其中, a=M20M00−xc2,b=M11M00−xcyc,c=M02M00−yc2\mathrm{a}=\frac{M_{20}}{M_{00}}-x_{c}^{2}, b=\frac{M_{11}}{M_{00}}-x_{c} \mathrm{y}_{\mathrm{c}}, c=\frac{M_{02}}{M_{00}}-y_{c}^{2}a=M00​M20​​−xc2​,b=M00​M11​​−xc​yc​,c=M00​M02​​−yc2​

ITK代码实现

  1. 创建测试图像
LabelType::Pointer CreateSampleImage()
{LabelType::Pointer image = LabelType::New();LabelType::IndexType start;start[0] = 0;start[1] = 0;LabelType::SizeType size;size[0] = 200;size[1] = 200;LabelType::RegionType region;region.SetSize(size);region.SetIndex(start);image->SetRegions(region);image->Allocate();// 椭圆方程// (x-xc)^2/a^2 + (y-yc)^2/b^2 = 1itk::ImageRegionIterator< LabelType >  it(image, image->GetRequestedRegion());it.Begin();while (!it.IsAtEnd()){if (pow((int)it.GetIndex()[0] - 90, 2) / (57 * 57) + pow((int)it.GetIndex()[1] - 110, 2) / (78 * 78)  < 1)it.Set(1);elseit.Set(0);++it;}// 加一点旋转using MatrixType = itk::Matrix<double, 2, 2>;MatrixType matrix;matrix[0][0] = cos(3.14 / 20);matrix[0][1] = sin(3.14 / 20);matrix[1][0] = -sin(3.14 / 20);matrix[1][1] = cos(3.14 / 20);// 输出下这个旋转矩阵cout << "Init Transform Matrix : " << matrix <<endl;using PointType = itk::Point<double, 2>;PointType center;center[0] = 100;center[1] = 100;typedef itk::CenteredRigid2DTransform< double > TransformType;TransformType::Pointer transform = TransformType::New();transform->SetMatrix(matrix);transform->SetCenter(center);// 应用上面的变换重采样图像typedef itk::ResampleImageFilter<LabelType, LabelType > ResampleFilterType;ResampleFilterType::Pointer resample = ResampleFilterType::New();resample->SetTransform(transform);resample->SetInput(image);resample->SetSize(image->GetLargestPossibleRegion().GetSize());resample->SetOutputOrigin(image->GetOrigin());resample->SetOutputSpacing(image->GetSpacing());resample->SetOutputDirection(image->GetDirection());resample->SetDefaultPixelValue(0);resample->Update();// 写出我们生成的倾斜图像using WriterType = itk::ImageFileWriter<LabelType>;WriterType::Pointer writer = WriterType::New();writer->SetFileName("sample.mha");writer->SetInput(resample->GetOutput());writer->SetImageIO(itk::MetaImageIO::New());writer->Write();return image;
}

然后我们就得到这样一个二值图像

这个变换的旋转矩阵为:

Init Transform Matrix : 0.987701 0.156356 -0.156356 0.987701
  1. 计算主轴变换矩阵并重采样
#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>
#include <itkGDCMImageIO.h>
#include <itkMetaImageIO.h>
#include <itkImageMomentsCalculator.h>
#include <itkOtsuThresholdImageFilter.h>
#include <itkBinaryFillholeImageFilter.h>
#include <itkCenteredRigid2DTransform.h>
#include <itkResampleImageFilter.h>int main(int argc, char * argv[])
{using LabelType = itk::Image<unsigned char, 2>;// 读取图像using ReaderType = itk::ImageFileReader<LabelType>;ReaderType::Pointer reader = ReaderType::New();reader->SetFileName("sample.mha");reader->SetImageIO(itk::MetaImageIO::New());reader->Update();// 计算图像矩using ImageMomentsFilter = itk::ImageMomentsCalculator<LabelType>;ImageMomentsFilter::Pointer moments = ImageMomentsFilter::New();moments->SetImage(reader->GetOutput());moments->Compute();moments->Print(cout);// 这里我们要将偏转的图像重新摆正,// 所以旋转矩阵使用主轴变换的逆矩阵using MatrixType = itk::Matrix<double, 2, 2>;MatrixType trans(moments->GetPrincipalAxes().GetInverse());typedef itk::CenteredRigid2DTransform< double > TransformType;TransformType::Pointer transform = TransformType::New();transform->SetMatrix(trans);typedef itk::ResampleImageFilter<LabelType,LabelType > ResampleFilterType;ResampleFilterType::Pointer resample = ResampleFilterType::New();resample->SetTransform(transform);resample->SetInput(reader->GetOutput());resample->SetSize(reader->GetOutput()->GetLargestPossibleRegion().GetSize());resample->SetOutputOrigin(reader->GetOutput()->GetOrigin());resample->SetOutputSpacing(reader->GetOutput()->GetSpacing());resample->SetOutputDirection(reader->GetOutput()->GetDirection());resample->SetDefaultPixelValue(0);try{resample->Update();}catch (itk::ExceptionObject & excp){std::cerr << excp << std::endl;}using WriterType = itk::ImageFileWriter<LabelType>;WriterType::Pointer writer = WriterType::New();writer->SetFileName("resample.mha");writer->SetInput(resample->GetOutput());writer->SetImageIO(itk::MetaImageIO::New());try{writer->Write();}catch (itk::ExceptionObject & excp){std::cerr << excp << std::endl;}//moments->Print(std::cout, 0);return EXIT_SUCCESS;
}

我们的校正的倾斜图像

主轴变换的相关计算结果如下:

ImageMomentsCalculator (000001C489893E70)RTTI typeinfo:   class itk::ImageMomentsCalculator<class itk::Image<unsigned char,2> >Reference Count: 1Modified Time: 47Debug: OffObject Name:Observers:noneImage: 000001C4898B1EB0Valid: 1Zeroth Moment about origin: 13680First Moment about origin: [88.5567, 108.308]Second Moment about origin: 809.857 -108.129
-108.129 1477.97Center of Gravity: [88.5567, 108.308]Second central moments: 809.857 -108.129
-108.129 1477.97Principal Moments: [1.08454e+07, 2.0452e+07]Principal axes: 0.987776 0.155883
-0.155883 0.987776

参考文献

[1]. 潘梅森. 医学图像倾斜校正方法与应用研究[D].中南大学,2011.
[2]. https://blog.csdn.net/linqianbi/article/details/78863839

基于主轴变换的医学图像倾斜校正相关推荐

  1. MATLAB基于Randon变换的图像倾斜校正算法及实现

    Radon变换的基本原理: 一个平面内沿不同的直线(直线与原点的距离为d,方向角为alfa)对f(x,y)做线积分,得到的像F(d,alfa)就是函数f的Radon变换.也就是说,平面(d,alfa) ...

  2. 毕业设计-基于机器学习的图片处理图片倾斜校正

    前言

  3. 图像倾斜校正 Radon 变换原理及函数

    radon校正 Radon(拉东)算法是一种通过定方向投影叠加,找到最大投影值时角度,从而确定图像倾斜角度的算法.具体过程如图所示 拉东变换 若函数F表示一个未知的密度,对F做radon变换,相当于得 ...

  4. 基于AlexNet卷积神经网络的手写体数字倾斜校正系统研究-附Matlab代码

    ⭕⭕ 目 录 ⭕⭕ ✳️ 一.引言 ✳️ 二.AlexNet 网络 ✳️ 三.实验验证 ✳️ 3.1 实验数据集 ✳️ 3.2 数据训练 ✳️ 3.3 手写体倾斜数字校正结果 ✳️ 四.参考文献 ✳️ ...

  5. 【表盘识别】基于Hough变换实现指针式仪表识别(倾斜矫正)

    一.简介 模型参考这里. 二.源代码 clear all; close all; clc; ​ img= imread('3.jpg'); img= rgb2gray(img); %% 归一化处理 f ...

  6. python.freelycode.com-通过OpenCV和Python进行文本倾斜校正

    Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发. 本文所展示的是一个由Pyhton实现的文本倾斜校正的脚本,在实现中使用到了OpenCV和Python的图像 ...

  7. 实战:基于OpenCV实现偏斜文档校正

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达本文转自|OpenCV学堂 纸质文档扫描中经常会发生扫描出来的图像有 ...

  8. matlab 倾斜矫正,matlab图像倾斜校正

    4 图像颜色畸变校正介绍图像颜色畸变现象可以是由摄像器材导致,也可以是由于真实环境本身就偏 色导致,还有的是由于图像放置过久氧化.老化导致.无论其产生的原因如何, 其校正方法都是类似的.如果用 Mat ...

  9. 【OpenCV 例程 300篇】237. 基于主成分提取的方向校正(OpenCV)

    『youcans 的 OpenCV 例程200篇 - 总目录』 [youcans 的 OpenCV 例程 300篇]237. 基于主成分提取的方向校正(OpenCV) 主成分分析(Principal ...

最新文章

  1. 数据库 分组,distinct
  2. Redis scan命令原理
  3. 未付服务网关限流作用
  4. iOS探索:Block解析浅谈
  5. 550什么意思_研报翻译官第二期:带你了解什么是CPI
  6. Gradle 2.3 发布
  7. (转)Spring Boot 2 (二):Spring Boot 2 尝鲜-动态 Banner
  8. linux之我常用的20条命令( 之三)
  9. python解析mht文件_将不同内容类型的MHT文件提取到多个MHT-fi中
  10. Android 如何通过拨号盘暗码启动你的应用
  11. 51单片机内部外设:定时器和计数器
  12. RNA-seq全流程分析
  13. python基于SVM的疫情评论情感数据分析
  14. 浙江理工大学英语平台Unipus自动答题
  15. Vant在微信小程序中的使用
  16. 昨夜无人喝彩,苹果的创新力真的到顶了吗?
  17. 通过用户id 查询权限
  18. 扶我起来我还能打:NBA新赛季开打,历史数据看勇士是否无敌?
  19. 洛谷P1209 [USACO1.3]修理牛棚 Barn Repair----解题报告
  20. 小黄鸡 php,php版小黄鸡simsimi聊天机器人接口分享

热门文章

  1. Illegal character in authority at index 18:
  2. 和讯金融界证券之星 财经网站竞争格局突变
  3. 360 os3.0 android7.1,【360 N6】360OS安卓7.1系统V3.0.070付费纯净版ROOT刷机包
  4. 经纬度坐标系转东北天_经纬度坐标系转换
  5. emby,jellyfin,kodi系列
  6. 【论文阅读】Finetuned Language Models Are Zero-Shot Learners
  7. mysql表中字段数据类型_mysql数据表中字段的数据类型有哪些?
  8. 将数据库转换为word文档
  9. JAVA程序设计题解与上机指导 第四版 第8章 Java的图形用户界面设计 8.2 创建“My JFrame”
  10. 华为g9一直显示服务器错误,华为G9青春版失败变砖开不了机了怎么办_G9青春版救砖方法...