Kaynağa Gözat

Add postprocess-single executable

Martijn Braam 3 yıl önce
ebeveyn
işleme
b92777c5e0
9 değiştirilmiş dosya ile 120 ekleme ve 10 silme
  1. 6 1
      CMakeLists.txt
  2. 4 0
      meson.build
  3. 49 1
      postprocess.c
  4. 3 0
      postprocess.h
  5. 45 0
      single.c
  6. 2 2
      stacker.cpp
  7. 1 1
      stacker.h
  8. 8 4
      stackercpp.cpp
  9. 2 1
      stackercpp.h

+ 6 - 1
CMakeLists.txt

@@ -17,4 +17,9 @@ add_compile_options(-Wall -Wextra -pedantic)
 add_executable(postprocessd main.c postprocess.c postprocess.h util.c util.h stacker.cpp stacker.h stackercpp.cpp stackercpp.h)
 target_link_libraries(postprocessd ${RAW_LIBRARIES} ${TIFF_LIBRARIES} ${JPEG_LIBRARIES} ${EXIF_LIBRARIES} ${CV_LIBRARIES})
 target_include_directories(postprocessd PUBLIC ${RAW_INCLUDE_DIRS} ${TIFF_INCLUDE_DIRS} ${JPEG_INCUDE_DIRS} ${EXIF_INCUDE_DIRS} ${CV_INCLUDE_DIRS})
-target_compile_options(postprocessd PUBLIC ${RAW_CFLAGS_OTHER} ${TIFF_CFLAGS_OTHER} ${JPEG_CFLAGS_OTHER} ${EXIF_CFLAGS_OTHER} ${CV_CFLAGS_OTHER})
+target_compile_options(postprocessd PUBLIC ${RAW_CFLAGS_OTHER} ${TIFF_CFLAGS_OTHER} ${JPEG_CFLAGS_OTHER} ${EXIF_CFLAGS_OTHER} ${CV_CFLAGS_OTHER})
+
+add_executable(postprocess-single single.c postprocess.c postprocess.h util.c util.h stacker.cpp stacker.h stackercpp.cpp stackercpp.h)
+target_link_libraries(postprocess-single ${RAW_LIBRARIES} ${TIFF_LIBRARIES} ${JPEG_LIBRARIES} ${EXIF_LIBRARIES} ${CV_LIBRARIES})
+target_include_directories(postprocess-single PUBLIC ${RAW_INCLUDE_DIRS} ${TIFF_INCLUDE_DIRS} ${JPEG_INCUDE_DIRS} ${EXIF_INCUDE_DIRS} ${CV_INCLUDE_DIRS})
+target_compile_options(postprocess-single PUBLIC ${RAW_CFLAGS_OTHER} ${TIFF_CFLAGS_OTHER} ${JPEG_CFLAGS_OTHER} ${EXIF_CFLAGS_OTHER} ${CV_CFLAGS_OTHER})

+ 4 - 0
meson.build

@@ -11,5 +11,9 @@ exif = dependency('libexif')
 cv = dependency('opencv4')
 
 executable('postprocessd', 'main.c','postprocess.c', 'stacker.cpp', 'stackercpp.cpp', 'util.c',
+    dependencies: [raw, tiff, jpeg, exif, cv],
+    install: true)
+
+executable('postprocess-single', 'single.c','postprocess.c', 'stacker.cpp', 'stackercpp.cpp', 'util.c',
     dependencies: [raw, tiff, jpeg, exif, cv],
     install: true)

+ 49 - 1
postprocess.c

@@ -5,6 +5,7 @@
 #include <tiffio.h>
 #include <jpeglib.h>
 #include <libexif/exif-data.h>
+#include <time.h>
 #include "postprocess.h"
 #include "stacker.h"
 
@@ -384,7 +385,7 @@ postprocess_internal(char *burst_dir, char *target_dir)
         printf("No DNG files found\n");
         exit(1);
     }
-    stacker_t *stacker = stacker_create();
+    stacker_t *stacker = stacker_create(1);
     while (burst_size--) {
         fprintf(stderr, "DEBAYER %s\n", namelist[burst_size]->d_name);
         snprintf(path, sizeof(path), "%s/%s", burst_dir, namelist[burst_size]->d_name);
@@ -422,3 +423,50 @@ postprocess_internal(char *burst_dir, char *target_dir)
     snprintf(stackpath, sizeof(stackpath), "%s.stacked.jpg", target_dir);
     save_jpeg(stackpath, stacked_data, 90, exif);
 }
+
+void
+postprocess_single(char *in_path, char *out_path, int quality, int verbose)
+{
+    libraw_processed_image_t *decoded;
+    libraw_processed_image_t *processed_data;
+    struct Imagedata imagedata;
+    ExifData *exif;
+    int width, height, result_size;
+    char *result;
+    clock_t timer;
+    stacker_t *stacker = stacker_create(verbose);
+
+    // Parse exif data from original file
+    timer = clock();
+    imagedata = read_exif(in_path);
+    exif = create_exif(imagedata);
+    if (verbose) {
+        printf("[%.1fms] %s\n", (float) (clock() - timer) / CLOCKS_PER_SEC * 1000, "exif read");
+    }
+
+    // Convert the sensor data to rgb
+    timer = clock();
+    decoded = debayer_file(in_path);
+    if (verbose) {
+        printf("[%.1fms] %s\n", (float) (clock() - timer) / CLOCKS_PER_SEC * 1000, "debayer");
+    }
+
+    // Run the opencv postprocessing on the single frame
+    result = stacker_postprocess(stacker, decoded->data, decoded->width, decoded->height);
+    width = stacker_get_width(stacker);
+    height = stacker_get_height(stacker);
+
+    // Export the final jpeg with the original exif data
+    timer = clock();
+    result_size = width * height * 3;
+    processed_data = (libraw_processed_image_t *) malloc(sizeof(libraw_processed_image_t) + result_size);
+    memset(processed_data, 0, sizeof(libraw_processed_image_t));
+    processed_data->colors = 3;
+    processed_data->width = decoded->width;
+    processed_data->height = decoded->height;
+    memmove(processed_data->data, result, result_size);
+    save_jpeg(out_path, processed_data, quality, exif);
+    if (verbose) {
+        printf("[%.1fms] %s\n", (float) (clock() - timer) / CLOCKS_PER_SEC * 1000, "export");
+    }
+}

+ 3 - 0
postprocess.h

@@ -30,6 +30,9 @@ struct Imagedata {
 void
 postprocess_internal(char *burst_dir, char *target_dir);
 
+void
+postprocess_single(char *in_path, char *out_path, int quality, int verbose);
+
 void
 postprocess_setup();
 

+ 45 - 0
single.c

@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <libnet.h>
+
+#include "util.h"
+#include "postprocess.h"
+
+int
+main(int argc, char *argv[])
+{
+    int opt;
+    int verbose = 0;
+    int quality = 90;
+    char *input_path;
+    char *output_path;
+
+    while ((opt = getopt(argc, argv, "vq:")) != -1) {
+        switch (opt) {
+            case 'v':
+                verbose = 1;
+                break;
+            case 'q':
+                quality = atoi(optarg);
+                break;
+            case 'i':
+                printf("input: %s\n", argv[optind]);
+                input_path = argv[optind];
+                break;
+            case 'o':
+                printf("output: %s\n", argv[optind]);
+                output_path = argv[optind];
+                break;
+            case '?':
+                printf("WTF\n");
+                break;
+        }
+    }
+
+    input_path = argv[optind];
+    output_path = argv[optind + 1];
+
+    postprocess_setup();
+    postprocess_single(input_path, output_path, quality, verbose);
+    return 0;
+}

+ 2 - 2
stacker.cpp

@@ -3,13 +3,13 @@
 #include "stackercpp.h"
 
 stacker_t *
-stacker_create()
+stacker_create(int verbose)
 {
     stacker_t *st;
     Stacker *obj;
 
     st = (__typeof__(st)) malloc(sizeof(*st));
-    obj = new Stacker();
+    obj = new Stacker(verbose != 0);
     st->obj = obj;
     return st;
 }

+ 1 - 1
stacker.h

@@ -11,7 +11,7 @@ struct stacker {
 typedef struct stacker stacker_t;
 
 stacker_t *
-stacker_create();
+stacker_create(int verbose);
 
 void
 stacker_add_image(stacker_t *st, unsigned char *data, int width, int height);

+ 8 - 4
stackercpp.cpp

@@ -1,7 +1,10 @@
 #include "stackercpp.h"
 
-Stacker::Stacker()
+Stacker::Stacker(bool verbose)
 {
+    Stacker::verbose = verbose;
+    Stacker::export_width = 0;
+    Stacker::export_height = 0;
     Stacker::layers = 0;
     Stacker::trimratio = 0;
     cv::setNumThreads(0);
@@ -22,7 +25,7 @@ Stacker::add_frame(unsigned char *data, int width, int height)
     Scalar mean, stddev;
     meanStdDev(grayscale, mean, stddev);
     printf("mean: %f, dev: %f\n", mean[0], stddev[0]);
-    if (mean[0] < 20) {
+    if (mean[0] < 10) {
         return;
     }
     stopwatch_mark("filter");
@@ -69,7 +72,6 @@ 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");
@@ -183,7 +185,9 @@ Stacker::stopwatch_start()
 void
 Stacker::stopwatch_mark(const char *name)
 {
-    printf("[%.1fms] %s\n", float(clock() - Stacker::stopwatch) / CLOCKS_PER_SEC * 1000, name);
+    if (Stacker::verbose) {
+        printf("[%.1fms] %s\n", float(clock() - Stacker::stopwatch) / CLOCKS_PER_SEC * 1000, name);
+    }
 }
 
 int

+ 2 - 1
stackercpp.h

@@ -13,7 +13,7 @@ using namespace cv;
 
 class Stacker {
 public:
-        Stacker();
+        Stacker(bool verbose);
 
         void
         add_frame(unsigned char *data, int width, int height);
@@ -31,6 +31,7 @@ public:
         get_height();
 
 private:
+        bool verbose;
         int layers;
         cv::Mat reference;
         cv::Mat stacked;