Browse Source

Crop the edge of the result to hide warping

Martijn Braam 3 years ago
parent
commit
d2e2f2deb0
5 changed files with 64 additions and 0 deletions
  1. 2 0
      postprocess.c
  2. 16 0
      stacker.cpp
  3. 6 0
      stacker.h
  4. 29 0
      stackercpp.cpp
  5. 11 0
      stackercpp.h

+ 2 - 0
postprocess.c

@@ -406,6 +406,8 @@ postprocess_internal(char *burst_dir, char *target_dir)
     fprintf(stderr, "STACK   stacked.jpg\n");
     // Convert opencv result to a libraw struct and feed it in the jpeg encoder with the original exif data
     char *stacked = stacker_get_result(stacker);
+    decoded->width = stacker_get_width(stacker);
+    decoded->height = stacker_get_height(stacker);
     int result_size = decoded->width * decoded->height * 3;
     libraw_processed_image_t *stacked_data = (libraw_processed_image_t *) malloc(
         sizeof(libraw_processed_image_t) + result_size);

+ 16 - 0
stacker.cpp

@@ -46,4 +46,20 @@ stacker_postprocess(stacker_t *st, unsigned char *data, int width, int height)
     }
     obj = static_cast<Stacker * >(st->obj);
     return obj->postprocess(data, width, height);
+}
+
+int
+stacker_get_width(stacker_t *st)
+{
+    Stacker *obj;
+    obj = static_cast<Stacker * >(st->obj);
+    return obj->get_width();
+}
+
+int
+stacker_get_height(stacker_t *st)
+{
+    Stacker *obj;
+    obj = static_cast<Stacker * >(st->obj);
+    return obj->get_height();
 }

+ 6 - 0
stacker.h

@@ -22,6 +22,12 @@ stacker_get_result(stacker_t *st);
 char *
 stacker_postprocess(stacker_t *st, unsigned char *data, int width, int height);
 
+int
+stacker_get_width(stacker_t *st);
+
+int
+stacker_get_height(stacker_t *st);
+
 #ifdef __cplusplus
 }
 #endif

+ 29 - 0
stackercpp.cpp

@@ -3,6 +3,7 @@
 Stacker::Stacker()
 {
     Stacker::layers = 0;
+    Stacker::trimratio = 0;
     cv::setNumThreads(0);
     Stacker::stopwatch = clock();
 }
@@ -52,6 +53,10 @@ Stacker::add_frame(unsigned char *data, int width, int height)
         warpPerspective(mat, warped, warp_matrix, warped.size(), INTER_LINEAR);
         stopwatch_mark("warp image");
 
+        // Check how much the image should be cropped to hide the warped edges
+        float current_trimratio = cv::videostab::estimateOptimalTrimRatio(warp_matrix, mat.size());
+        Stacker::trimratio = std::max(Stacker::trimratio, current_trimratio);
+
         // Add the warped image to the stack
         Stacker::stacked += warped;
         Stacker::layers += 1;
@@ -61,6 +66,14 @@ Stacker::add_frame(unsigned char *data, int width, int height)
 Mat
 Stacker::postprocess_mat(Mat input)
 {
+    stopwatch_start();
+    int h_crop = (int) ((float) input.cols * Stacker::trimratio);
+    int v_crop = (int) ((float) input.rows * Stacker::trimratio);
+    printf("crop: %d %d\n", h_crop, v_crop);
+    Mat cropped;
+    input(Rect(h_crop, v_crop, input.cols - h_crop - h_crop, input.rows - v_crop - v_crop)).copyTo(input);
+    stopwatch_mark("trim");
+
     stopwatch_start();
     Mat blur;
     GaussianBlur(input, blur, Size(0, 0), 1.8);
@@ -131,6 +144,8 @@ Stacker::get_result()
 
     // Run the final-frame postprocessing
     Mat result = postprocess_mat(Stacker::stacked);
+    Stacker::export_width = result.cols;
+    Stacker::export_height = result.rows;
 
     // Convert mat to bytes
     size_t size = result.total() * result.elemSize();
@@ -147,6 +162,8 @@ Stacker::postprocess(unsigned char *data, int width, int height)
 
     // Run the final-frame postprocessing
     Mat result = postprocess_mat(mat);
+    Stacker::export_width = result.cols;
+    Stacker::export_height = result.rows;
 
     // Convert mat to bytes
     size_t size = result.total() * result.elemSize();
@@ -165,4 +182,16 @@ void
 Stacker::stopwatch_mark(const char *name)
 {
     printf("[%.1fms] %s\n", float(clock() - Stacker::stopwatch) / CLOCKS_PER_SEC * 1000, name);
+}
+
+int
+Stacker::get_width()
+{
+    return Stacker::export_width;
+}
+
+int
+Stacker::get_height()
+{
+    return Stacker::export_height;
 }

+ 11 - 0
stackercpp.h

@@ -2,6 +2,8 @@
 #include <opencv2/core.hpp>
 #include <opencv2/imgcodecs.hpp>
 #include <opencv2/video/tracking.hpp>
+#include <opencv2/videostab/motion_stabilizing.hpp>
+
 
 using namespace std;
 using namespace cv;
@@ -22,11 +24,20 @@ public:
         char *
         postprocess(unsigned char *data, int width, int height);
 
+        int
+        get_width();
+
+        int
+        get_height();
+
 private:
         int layers;
         cv::Mat reference;
         cv::Mat stacked;
         clock_t stopwatch;
+        int export_width;
+        int export_height;
+        float trimratio;
 
         Mat
         postprocess_mat(Mat input);