image_alignment.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /**
  2. * OpenCV Image Alignment Example
  3. *
  4. * Copyright 2015 by Satya Mallick <spmallick@learnopencv.com>
  5. *
  6. */
  7. #include "opencv2/opencv.hpp"
  8. using namespace cv;
  9. using namespace std;
  10. Mat GetGradient(Mat src_gray)
  11. {
  12. Mat grad_x, grad_y;
  13. Mat abs_grad_x, abs_grad_y;
  14. int scale = 1;
  15. int delta = 0;
  16. int ddepth = CV_32FC1; ;
  17. // Calculate the x and y gradients using Sobel operator
  18. Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );
  19. convertScaleAbs( grad_x, abs_grad_x );
  20. Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );
  21. convertScaleAbs( grad_y, abs_grad_y );
  22. // Combine the two gradients
  23. Mat grad;
  24. addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );
  25. return grad;
  26. }
  27. int main( int argc, char** argv )
  28. {
  29. // Read 8-bit color image.
  30. // This is an image in which the three channels are
  31. // concatenated vertically.
  32. Mat im = imread("images/cathedral.jpg", IMREAD_GRAYSCALE);
  33. // Find the width and height of the color image
  34. Size sz = im.size();
  35. int height = sz.height / 3;
  36. int width = sz.width;
  37. // Extract the three channels from the gray scale image
  38. vector<Mat>channels;
  39. channels.push_back(im( Rect(0, 0, width, height)));
  40. channels.push_back(im( Rect(0, height, width, height)));
  41. channels.push_back(im( Rect(0, 2*height, width, height)));
  42. // Merge the three channels into one color image
  43. Mat im_color;
  44. merge(channels,im_color);
  45. // Set space for aligned image.
  46. vector<Mat> aligned_channels;
  47. aligned_channels.push_back(Mat(height, width, CV_8UC1));
  48. aligned_channels.push_back(Mat(height, width, CV_8UC1));
  49. // The blue and green channels will be aligned to the red channel.
  50. // So copy the red channel
  51. aligned_channels.push_back(channels[2].clone());
  52. // Define motion model
  53. const int warp_mode = MOTION_AFFINE;
  54. // Set space for warp matrix.
  55. Mat warp_matrix;
  56. // Set the warp matrix to identity.
  57. if ( warp_mode == MOTION_HOMOGRAPHY )
  58. warp_matrix = Mat::eye(3, 3, CV_32F);
  59. else
  60. warp_matrix = Mat::eye(2, 3, CV_32F);
  61. // Set the stopping criteria for the algorithm.
  62. int number_of_iterations = 5000;
  63. double termination_eps = 1e-10;
  64. TermCriteria criteria(TermCriteria::COUNT+TermCriteria::EPS,
  65. number_of_iterations, termination_eps);
  66. // Warp the blue and green channels to the red channel
  67. for ( int i = 0; i < 2; i++)
  68. {
  69. double cc = findTransformECC (
  70. GetGradient(channels[2]),
  71. GetGradient(channels[i]),
  72. warp_matrix,
  73. warp_mode,
  74. criteria
  75. );
  76. cout << "warp_matrix : " << warp_matrix << endl;
  77. cout << "CC " << cc << endl;
  78. if (cc == -1)
  79. {
  80. cerr << "The execution was interrupted. The correlation value is going to be minimized." << endl;
  81. cerr << "Check the warp initialization and/or the size of images." << endl << flush;
  82. }
  83. if (warp_mode == MOTION_HOMOGRAPHY)
  84. // Use Perspective warp when the transformation is a Homography
  85. warpPerspective (channels[i], aligned_channels[i], warp_matrix, aligned_channels[0].size(), INTER_LINEAR + WARP_INVERSE_MAP);
  86. else
  87. // Use Affine warp when the transformation is not a Homography
  88. warpAffine(channels[i], aligned_channels[i], warp_matrix, aligned_channels[0].size(), INTER_LINEAR + WARP_INVERSE_MAP);
  89. }
  90. // Merge the three channels
  91. Mat im_aligned;
  92. merge(aligned_channels, im_aligned);
  93. // Show final output
  94. imshow("Color Image", im_color);
  95. imshow("Aligned Image", im_aligned);
  96. waitKey(0);
  97. }