stackercpp.cpp 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. #include "stackercpp.h"
  2. Stacker::Stacker()
  3. {
  4. Stacker::layers = 0;
  5. }
  6. void
  7. Stacker::add_frame(unsigned char *data, int width, int height)
  8. {
  9. Mat warp_matrix = Mat::eye(3, 3, CV_32F);
  10. Mat mat = Mat(height, width, CV_8UC3, data);
  11. Mat grayscale = Mat(height, width, CV_8UC1);
  12. cv::cvtColor(mat, grayscale, cv::COLOR_BGR2GRAY);
  13. int number_of_iterations = 5000;
  14. double termination_eps = 1e-10;
  15. TermCriteria criteria(TermCriteria::COUNT + TermCriteria::EPS, number_of_iterations, termination_eps);
  16. if (layers == 0) {
  17. // First image in the stack is used as the reference to align the next frames to
  18. Stacker::reference = grayscale;
  19. // Create black image to accumulate the average
  20. Stacker::stacked = Mat(height, width, CV_64FC3);
  21. Stacker::stacked.setTo(Scalar(0, 0, 0, 0));
  22. // Add first frame to the stack
  23. Stacker::stacked += mat;
  24. Stacker::layers += 1;
  25. } else {
  26. // All frames after the initial one are stacked
  27. Mat warped = Mat(Stacker::stacked.rows, Stacker::stacked.cols, CV_32FC1);
  28. cv::findTransformECC(grayscale, Stacker::reference, warp_matrix, MOTION_HOMOGRAPHY, criteria);
  29. warpPerspective(mat, warped, warp_matrix, warped.size(), INTER_LINEAR);
  30. // Add the warped image to the stack
  31. Stacker::stacked += warped;
  32. Stacker::layers += 1;
  33. }
  34. }
  35. char *
  36. Stacker::get_result()
  37. {
  38. Stacker::stacked.convertTo(Stacker::stacked, CV_8U, 1. / Stacker::layers);
  39. size_t size = Stacker::stacked.total() * Stacker::stacked.elemSize();
  40. char *data = (char *) malloc(size);
  41. std::memcpy(data, Stacker::stacked.data, size * sizeof(char));
  42. return data;
  43. }