小言_互联网的博客

图像配准系列之基于FFD形变与LM算法的图像配准

434人阅读  评论(0)

在前面的文章中,我们讲到使用FFD形变作为坐标变换模型,使用梯度下降法作为优化算法来寻求FFD的最优控制参数:

图像配准系列之基于FFD形变与梯度下降法的图像配准

LM算法可以看作是梯度下降法与高斯-牛顿法的结合算法,它既具有梯度下降法的稳健性,又具有高斯-牛顿法的快速收敛性,而且相比来说更不容易陷入局部极值。有关LM算法的数学公式推导,我们也在前文中有详细说明:

最优化算法之牛顿法、高斯-牛顿法、LM算法

本文我们将使用LM算法作为优化算法来寻求FFD变换的最优控制参数。并与梯度下降法比较配准结果。

1. LM算法的计算过程

(1) 差分法求控制参数的梯度。

假设FFD变换模型有r+3行c+3列的控制点,每个控制点有x方向、y方向的两个控制参数,因此总共有N=2*(r+3)*(c+3)个控制参数需要优化,所有控制参数组成一个1行N列的向量X:

对于每个控制参数,其梯度的计算如下式,其中F为目标函数,EPS为一个较小的数,一般取1或者0.5即可。

所有控制点的梯度组成一个1行N列的梯度向量:

(2) 计算当前控制参数的目标函数值f0、矩阵gk、海塞矩阵H。

(3) 使用海塞矩阵计算矩阵G、矩阵h。

上式中,u为LM算法的控制步长,通常u取一个较小的初始值(比如0.001),在迭代优化过程中u的值根据情况而改变,详细如何改变在后续步骤说明。矩阵I为N*N的单位矩阵:

(4) 判断是否满足以下条件,如果满足则认为找到最优控制参数,因此停止循环迭代:

上式中,norm函数为L2范数,e通常取一个很小的值,比如10-12。比如X的L2范数可按下式计算:

(5) 更新X得到X',然后计算X'的目标函数值f1,并计算步长因子ρ。

(6) 判断ρ是否大于0。

I. 如果ρ大于0则减小u的值:

则把X'赋值给X,并改变u的值。接着判断迭代次数是否达到设定的最大次数,如果达到则停止迭代,否则跳转到第(1)步执行。

II. 如果ρ小于等于0则增大u和v:

接着判断迭代次数是否达到设定的最大次数,如果达到则停止迭代,否则跳转到第(3)步执行。

上式中,在迭代开始之前通常把v初始化值为2。

2. C++实现代码

cal_gradient、F_fun_bpline、Bspline_Ffd_cuda、init_bpline_para在上篇文章中已经讲过,此处不再重复贴出来:

图像配准系列之基于FFD形变与梯度下降法的图像配准

求海塞矩阵代码:


   
  1. Mat cal_hessian_matrix(Mat gradient)
  2. {
  3. Mat gradient_trans;
  4.   Mat hessian;
  5.   transpose(gradient, gradient_trans);   //转置
  6.   hessian =  gradient_trans*gradient;
  7. return hessian;
  8. }

LM算法代码:


   
  1. void bpline_match_LM(Mat S1, Mat Si, Mat &M, int row_block_num, int col_block_num, Mat &grid_points)
  2. {
  3. int iter = 150; //迭代次数
  4.    double e =  1e-12;   // 误差限
  5. double u = 1e-3;
  6. double v = 2.0;
  7. Mat H;
  8. Mat G;
  9. Mat new_grid_points;
  10. Mat I = cv::Mat::eye(grid_points.cols, grid_points.cols, CV_32FC1); //单位矩阵
  11. Mat h, h_T;
  12. Mat gradient, gradient_T;
  13. float f0, f1;
  14. Mat gk;
  15. double low = 1.0;
  16.   
  17. cal_gradient(S1, Si, row_block_num, col_block_num, grid_points, gradient); //求梯度
  18. f0 = F_fun_bpline(S1, Si, row_block_num, col_block_num, grid_points);
  19. transpose(gradient, gradient_T);
  20. gk = gradient_T*f0;
  21. H = cal_hessian_matrix(gradient); //由雅克比矩阵计算海塞矩阵
  22. for( int i = 0; i < iter; i++)
  23. {
  24. G = H + u*I;
  25. Mat G_T;
  26. invert(G, G_T, DECOMP_SVD);
  27. h = -G_T*gk;
  28.      if(norm(h, NORM_L2) < e*(norm(grid_points, NORM_L2)+e))
  29. break;
  30. transpose(h, h_T);
  31. new_grid_points = grid_points + h_T;
  32. f1 = F_fun_bpline(S1, Si, row_block_num, col_block_num, new_grid_points);
  33. Mat L_0_h = 0.5*h_T*(u*h-gk); //1_N*N_1 = 1*1
  34. low = (f0 - f1)/L_0_h.at< float>( 0, 0);
  35. if(low > 0)
  36. {
  37. grid_points = new_grid_points.clone();
  38. double tmp = 2*low -1; //5*low-1;
  39. tmp = 1 - tmp*tmp*tmp;
  40. double t = 0.333333;
  41. u = u*(t > tmp ? t : tmp);
  42. v = 2;
  43. cal_gradient(S1, Si, row_block_num, col_block_num, grid_points, gradient); //求梯度
  44. f0 = F_fun_bpline(S1, Si, row_block_num, col_block_num, grid_points);
  45. transpose(gradient, gradient_T);
  46. gk = gradient_T*f0;
  47.       H = cal_hessian_matrix(gradient);     //由雅克比矩阵计算海塞矩阵
  48. }
  49. else
  50. {
  51. u *= v;
  52. v *= 2;
  53. }
  54. cout<< "f1="<<f1<< ", low="<<low<< ", u="<<u<< endl;
  55. }
  56.   Bspline_Ffd_cuda(Si, M, row_block_num, col_block_num, grid_points);
  57. }

测试代码:


   
  1. void ffd_match_LM_test(void)
  2. {
  3. Mat img1 = imread( "lena.jpg", CV_LOAD_IMAGE_GRAYSCALE);
  4.   Mat img2 = imread( "lena_out.jpg", CV_LOAD_IMAGE_GRAYSCALE);
  5. int row_block_num = 30;
  6. int col_block_num = 30;
  7. Mat grid_points;
  8. init_bpline_para(img1, row_block_num, col_block_num, grid_points, -0.001, 0.001);
  9. Mat out;
  10. bpline_match_LM(img1, img2, out, row_block_num, col_block_num, grid_points);
  11. imshow( "img1", img1);
  12. imshow( "img2", img2);
  13. imshow( "out", out);
  14. imshow( "img1-img2", abs(img1-img2));
  15. imshow( "img1-out", abs(img1- out));
  16. waitKey();
  17. }

运行上述代码,对扭曲的Lena图像进行配准,结果如下图所示。

基准图像

浮动图像

配准图像

基准图像与浮动图像的差值图

基准图像与配准图像的差值图

目标函数值的下降过程

由上图可知,LM算法的优化结果比梯度下降法更理想,其收敛速度更快,且优化结果更接近最优解。

本人微信公众号如下,会不定时更新更精彩的内容,欢迎扫码关注:


转载:https://blog.csdn.net/shandianfengfan/article/details/113778069
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场