Browse Source

Merge branch 'release/v0.0.8'

Jérôme BUISINE 4 months ago
parent
commit
460d7574c8

+ 7 - 1
main/CMakeLists.txt

@@ -3,15 +3,21 @@ add_executable(rawls_merge_mean rawls_merge_mean.cpp)
 add_executable(rawls_h_flip rawls_h_flip.cpp)
 add_executable(rawls_merge_mean_incr rawls_merge_mean_incr.cpp)
 add_executable(rawls_merge_median_incr rawls_merge_median_incr.cpp)
+add_executable(rawls_merge_MON_incr rawls_merge_MON_incr.cpp)
+add_executable(rawls_merge_MON_pct_incr rawls_merge_MON_pct_incr.cpp)
 
 target_link_libraries(rawls_convert LINK_PUBLIC rawls)
 target_link_libraries(rawls_merge_mean LINK_PUBLIC rawls)
 target_link_libraries(rawls_h_flip LINK_PUBLIC rawls)
 target_link_libraries(rawls_merge_mean_incr LINK_PUBLIC rawls)
 target_link_libraries(rawls_merge_median_incr LINK_PUBLIC rawls)
+target_link_libraries(rawls_merge_MON_incr LINK_PUBLIC rawls)
+target_link_libraries(rawls_merge_MON_pct_incr LINK_PUBLIC rawls)
 
 set_property(TARGET rawls_merge_mean PROPERTY CXX_STANDARD 17)
 set_property(TARGET rawls_convert PROPERTY CXX_STANDARD 17)
 set_property(TARGET rawls_h_flip PROPERTY CXX_STANDARD 17)
 set_property(TARGET rawls_merge_mean_incr PROPERTY CXX_STANDARD 17)
-set_property(TARGET rawls_merge_median_incr PROPERTY CXX_STANDARD 17)
+set_property(TARGET rawls_merge_median_incr PROPERTY CXX_STANDARD 17)
+set_property(TARGET rawls_merge_MON_incr PROPERTY CXX_STANDARD 17)
+set_property(TARGET rawls_merge_MON_pct_incr PROPERTY CXX_STANDARD 17)

+ 277 - 0
main/rawls_merge_MON_incr.cpp

@@ -0,0 +1,277 @@
+#include <iostream>
+#include <string.h>
+#include <memory>
+
+#include "lodepng.h"
+#include "rawls.h"
+
+#include <algorithm>
+#include <filesystem>
+#include <regex>
+
+// number of means expected
+const unsigned numberOfMeans = 20;
+
+void writeProgress(float progress, bool moveUp = false){
+    int barWidth = 200;
+
+    if (moveUp){
+        // move up line
+        std::cout << "\e[A";
+        std::cout.flush();
+    }
+
+    std::cout << "[";
+    int pos = barWidth * progress;
+    for (int i = 0; i < barWidth; ++i) {
+        if (i < pos) std::cout << "=";
+        else if (i == pos) std::cout << ">";
+        else std::cout << " ";
+    }
+    std::cout << "] " << int(progress * 100.0) << " %\r";
+    std::cout.flush();
+}
+
+void insertSample(unsigned* occurences, float* values, float value){
+
+    /* generate secret number: */
+    unsigned foundIndex = rand() % numberOfMeans;
+
+    values[foundIndex] += value;
+    occurences[foundIndex] += 1;
+}
+
+/*
+ * Compute array of means and sort values
+ */
+float* prepareMeans(unsigned* occurences, float* values){
+
+    float* means = new float[numberOfMeans];
+
+    for (int i = 0; i < numberOfMeans; i++){
+        means[i] = values[i] / occurences[i];
+    }
+
+    std::sort(means, means + numberOfMeans, std::less<float>());
+
+    return means;
+}
+
+/*
+ * Returns median value from array of values
+ */
+float getMedianValue(float values[]){
+
+    if (numberOfMeans % 2 == 0)
+    {
+      return (values[numberOfMeans / 2 - 1] + values[numberOfMeans / 2]) / 2;
+    }
+    else 
+    {
+      return values[numberOfMeans / 2];
+    }
+}
+
+/*
+ * Save current step images from current buffer
+ */
+bool saveCurrentImage(int width, int height, int nbChanels, float* buffer, std::string outfileName, std::string comments){
+    
+    // create outfile 
+    if (rawls::HasExtension(outfileName, ".ppm")){
+        rawls::saveAsPPM(width, height, nbChanels, buffer, outfileName);
+    } 
+    else if (rawls::HasExtension(outfileName, ".png")){
+        rawls::saveAsPNG(width, height, nbChanels, buffer, outfileName);
+    } 
+    else if (rawls::HasExtension(outfileName, ".rawls") || rawls::HasExtension(outfileName, ".rawls_20")){
+    
+        // Here no gamma conversion is done, only mean of samples
+        rawls::saveAsRAWLS(width, height, nbChanels, comments, buffer, outfileName);
+    }
+    else{
+        std::cout << "Unexpected output extension image" << std::endl;
+        return false;
+    }
+
+    return true;
+}
+
+/*
+ * Incremental merge of `rawls` images using `median-of-means`
+ */
+int main(int argc, char *argv[]){
+
+    /* initialize random seed: */
+    srand ( time(NULL) );
+
+    std::string folderName; 
+    std::string outputFolder;
+    std::string prefixImageName;
+    std::string imageExtension;
+
+    unsigned step = 10;
+    unsigned maxSamples = 0;
+    bool random;
+
+    for (int i = 1; i < argc; ++i) {
+        if (!strcmp(argv[i], "--folder") || !strcmp(argv[i], "-folder")) {
+            folderName = argv[++i];
+        } else if (!strcmp(argv[i], "--step") || !strcmp(argv[i], "-step")) {
+            step = atoi(argv[++i]);
+        }else if (!strcmp(argv[i], "--random") || !strcmp(argv[i], "-random")) {
+            random = bool(atoi(argv[++i]));
+        }else if (!strcmp(argv[i], "--output") || !strcmp(argv[i], "-output")) {
+            outputFolder = argv[++i];
+        }else if (!strcmp(argv[i], "--prefix") || !strcmp(argv[i], "-prefix")) {
+            prefixImageName = argv[++i];
+        }else if (!strcmp(argv[i], "--max") || !strcmp(argv[i], "-max")) {
+            maxSamples = atoi(argv[++i]);
+        }else if (!strcmp(argv[i], "--extension") || !strcmp(argv[i], "-extension")) {
+            imageExtension = argv[++i];
+        }
+    }
+
+    std::vector<std::string> imagesPath;
+
+    for (const auto & entry : std::filesystem::directory_iterator(folderName)){
+        std::string imageName = entry.path().string();
+        if (rawls::HasExtension(imageName, ".rawls") || rawls::HasExtension(imageName, ".rawls_20")){
+            imagesPath.push_back(imageName);
+        }
+    }
+
+    // sort or shuffle the images path
+    if (!random){
+        std::sort(imagesPath.begin(), imagesPath.end(), std::less<std::string>());
+    }else{
+        std::random_shuffle(imagesPath.begin(), imagesPath.end());
+    }
+
+    unsigned width, height, nbChanels;
+
+    float** sumBuffer; // stores sum array for each sample
+    unsigned** occurencesMeanBuffer; 
+    float* outputStepBuffer; // buffer which stores kept median for each generated image (median is found using `outputMeanBuffer`)
+
+    if (imagesPath.size() > 0){
+
+        std::tuple<unsigned, unsigned, unsigned> dimensions = rawls::getDimensionsRAWLS(imagesPath.at(0));
+
+        width = std::get<0>(dimensions);
+        height = std::get<1>(dimensions);
+        nbChanels = std::get<2>(dimensions);
+
+        // init all pointers size
+        sumBuffer = new float*[width * height * nbChanels];
+        occurencesMeanBuffer = new unsigned*[width * height * nbChanels];
+        outputStepBuffer = new float[width * height * nbChanels];
+
+        // init values of buffer
+        for (int i = 0; i < height * width * nbChanels; i++){
+            // define array size and initialization
+            sumBuffer[i] = new float[numberOfMeans];
+            occurencesMeanBuffer[i] = new unsigned[numberOfMeans];
+
+            for (int j = 0; j < numberOfMeans; j++){
+                sumBuffer[i][j] = 0;
+                occurencesMeanBuffer[i][j] = 0;
+            }
+
+            outputStepBuffer[i] = 0;
+        }
+    }
+    else
+    {
+        std::cout << "Folder is empty..." << std::endl;
+        return 1;
+    }
+
+    // just for indication
+    float progress = 0.0;
+    unsigned bufferSize = width * height * nbChanels;
+    std::string comments;
+
+    // get comments if output is also `rawls` file
+    if (rawls::HasExtension(imageExtension, "rawls")){
+        comments = rawls::getCommentsRAWLS(imagesPath.at(0));
+    }
+
+    for (unsigned i = 0; i < maxSamples; i++){
+
+        unsigned currentSample = i + 1;
+
+        // read into folder all `.rawls` file and merge pixels values
+        float* buffer = rawls::getPixelsRAWLS(imagesPath.at(i));
+
+        for(unsigned y = 0; y < height; y++){
+
+            for(unsigned x = 0; x < width; x++) {
+
+                for(unsigned j = 0; j < nbChanels; j++){
+                    
+                    unsigned currentIndex = nbChanels * width * y + nbChanels * x + j;
+                    
+                    float value = buffer[currentIndex];
+
+                    // add new `luminance` of chanel[j] found randomly (uniformly) into means array
+                    insertSample(occurencesMeanBuffer[currentIndex], sumBuffer[currentIndex], value);
+                }
+            }
+        }
+
+        // save a new 
+        if (currentSample % step == 0){
+
+            float currentMean;
+
+            // get median all samples values by number of samples used (using MON method)
+            for (int j = 0; j < height * width * nbChanels; j++){
+
+                float* means = prepareMeans(occurencesMeanBuffer[j], sumBuffer[j]);
+
+                // get meadian of these means as expected output luminance
+                outputStepBuffer[j] = getMedianValue(means);
+
+                // remove pointer values
+                delete means;
+            }
+
+            // add suffix with `5` digits
+            std::string suffix = std::to_string(currentSample);
+            
+            while(suffix.length() < 5){
+                suffix = "0" + suffix;
+            }
+
+            // build output path of image
+            std::string outfileName = outputFolder + "/" + prefixImageName + "_" + suffix + "." + imageExtension;
+            outfileName = std::regex_replace(outfileName, std::regex("\\//"), "/"); // fix path 
+
+            // save the expected `step` image using built outpath
+            saveCurrentImage(width, height, nbChanels, outputStepBuffer, outfileName, comments);
+
+            // just for progress information with erasing previous info
+            writeProgress(progress, true);
+        }
+
+        // update and write progress information
+        progress += (1 / (float)maxSamples);
+        writeProgress(progress);
+
+        delete buffer;
+    }
+    
+    writeProgress(1.);
+    std::cout << std::endl;
+
+    // clear all pointers memory
+    for (int j = 0; j < height * width * nbChanels; j++){
+        delete[] sumBuffer[j];
+        delete[] occurencesMeanBuffer[j];
+    }
+
+    delete sumBuffer;
+    delete occurencesMeanBuffer;
+    delete outputStepBuffer;
+}

+ 267 - 0
main/rawls_merge_MON_pct_incr.cpp

@@ -0,0 +1,267 @@
+#include <iostream>
+#include <string.h>
+#include <memory>
+
+#include "lodepng.h"
+#include "rawls.h"
+
+#include <algorithm>
+#include <filesystem>
+#include <regex>
+
+void writeProgress(float progress, bool moveUp = false){
+    int barWidth = 200;
+
+    if (moveUp){
+        // move up line
+        std::cout << "\e[A";
+        std::cout.flush();
+    }
+
+    std::cout << "[";
+    int pos = barWidth * progress;
+    for (int i = 0; i < barWidth; ++i) {
+        if (i < pos) std::cout << "=";
+        else if (i == pos) std::cout << ">";
+        else std::cout << " ";
+    }
+    std::cout << "] " << int(progress * 100.0) << " %\r";
+    std::cout.flush();
+}
+
+void insertSorted(unsigned size, float* values, float value){
+
+    // avoid use of:
+    //std::sort(values, values + size, std::greater<float>());
+    unsigned position = 0;
+
+    // find expected position value
+    for (int i = 0; i < size; i++){
+
+        if(value <= values[i]){
+            break; // position found go out of the loop
+        }
+        position = i + 1;
+    }
+
+    // shift all values to right by one
+    for (int i = size ; i > position; i--){        
+        values[i] = values[i - 1];
+    }
+
+    // insert new value into found position (now free)
+    values[position] = value;
+
+}
+
+float getMedianValue(unsigned size, float* values){
+
+    if (size % 2 == 0)
+    {
+      return (values[size / 2 - 1] + values[size / 2]) / 2;
+    }
+    else 
+    {
+      return values[size / 2];
+    }
+}
+
+/*
+ * Save current step images from current buffer
+ */
+bool saveCurrentImage(int width, int height, int nbChanels, float* buffer, std::string outfileName, std::string comments){
+    
+    // create outfile 
+    if (rawls::HasExtension(outfileName, ".ppm")){
+        rawls::saveAsPPM(width, height, nbChanels, buffer, outfileName);
+    } 
+    else if (rawls::HasExtension(outfileName, ".png")){
+        rawls::saveAsPNG(width, height, nbChanels, buffer, outfileName);
+    } 
+    else if (rawls::HasExtension(outfileName, ".rawls") || rawls::HasExtension(outfileName, ".rawls_20")){
+    
+        // Here no gamma conversion is done, only mean of samples
+        rawls::saveAsRAWLS(width, height, nbChanels, comments, buffer, outfileName);
+    }
+    else{
+        std::cout << "Unexpected output extension image" << std::endl;
+        return false;
+    }
+
+    return true;
+}
+
+/*
+ * Incremental merge of `rawls` images using `median-of-means`
+ */
+int main(int argc, char *argv[]){
+
+    std::string folderName;
+    std::string outputFolder;
+    std::string prefixImageName;
+    std::string imageExtension;
+
+    unsigned step = 10;
+    unsigned maxSamples = 0;
+    bool random;
+
+    for (int i = 1; i < argc; ++i) {
+        if (!strcmp(argv[i], "--folder") || !strcmp(argv[i], "-folder")) {
+            folderName = argv[++i];
+        } else if (!strcmp(argv[i], "--step") || !strcmp(argv[i], "-step")) {
+            step = atoi(argv[++i]);
+        }else if (!strcmp(argv[i], "--random") || !strcmp(argv[i], "-random")) {
+            random = bool(atoi(argv[++i]));
+        }else if (!strcmp(argv[i], "--output") || !strcmp(argv[i], "-output")) {
+            outputFolder = argv[++i];
+        }else if (!strcmp(argv[i], "--prefix") || !strcmp(argv[i], "-prefix")) {
+            prefixImageName = argv[++i];
+        }else if (!strcmp(argv[i], "--max") || !strcmp(argv[i], "-max")) {
+            maxSamples = atoi(argv[++i]);
+        }else if (!strcmp(argv[i], "--extension") || !strcmp(argv[i], "-extension")) {
+            imageExtension = argv[++i];
+        }
+    }
+
+    std::vector<std::string> imagesPath;
+
+    for (const auto & entry : std::filesystem::directory_iterator(folderName)){
+        std::string imageName = entry.path().string();
+        if (rawls::HasExtension(imageName, ".rawls") || rawls::HasExtension(imageName, ".rawls_20")){
+            imagesPath.push_back(imageName);
+        }
+    }
+
+    // sort or shuffle the images path
+    if (!random){
+        std::sort(imagesPath.begin(), imagesPath.end(), std::less<std::string>());
+    }else{
+        std::random_shuffle(imagesPath.begin(), imagesPath.end());
+    }
+
+    unsigned width, height, nbChanels;
+
+    float** outputMeanBuffer; // stores means array for each sample
+    float* outputStepBuffer; // buffer which stores kept median for each generated image (median is found using `outputMeanBuffer`)
+    float* outputSumBuffer; // buffer which stores sum of new computed mean for each sample (then new mean is added to `outputMeanBuffer`)
+
+    if (imagesPath.size() > 0){
+
+        std::tuple<unsigned, unsigned, unsigned> dimensions = rawls::getDimensionsRAWLS(imagesPath.at(0));
+
+        width = std::get<0>(dimensions);
+        height = std::get<1>(dimensions);
+        nbChanels = std::get<2>(dimensions);
+
+        // init all pointers size
+        outputMeanBuffer = new float*[width * height * nbChanels];
+        outputSumBuffer = new float[width * height * nbChanels];
+        outputStepBuffer = new float[width * height * nbChanels];
+
+        // init values of buffer
+        for (int i = 0; i < height * width * nbChanels; i++){
+            // set as default size `maxSamples` by `step`
+            outputMeanBuffer[i] = new float[maxSamples / step];
+            outputSumBuffer[i] = 0;
+            outputStepBuffer[i] = 0;
+        }
+    }
+    else
+    {
+        std::cout << "Folder is empty..." << std::endl;
+        return 1;
+    }
+
+    // just for indication
+    float progress = 0.0;
+    unsigned bufferSize = width * height * nbChanels;
+    std::string comments;
+
+    // get comments if output is also `rawls` file
+    if (rawls::HasExtension(imageExtension, "rawls")){
+        comments = rawls::getCommentsRAWLS(imagesPath.at(0));
+    }
+
+    for (unsigned i = 0; i < maxSamples; i++){
+
+        unsigned currentSample = i + 1;
+
+        // read into folder all `.rawls` file and merge pixels values
+        float* buffer = rawls::getPixelsRAWLS(imagesPath.at(i));
+
+        for(unsigned y = 0; y < height; y++){
+
+            for(unsigned x = 0; x < width; x++) {
+
+                for(unsigned j = 0; j < nbChanels; j++){
+                    
+                    float value = buffer[nbChanels * width * y + nbChanels * x + j];
+
+                    // add new `luminance` of chanel[j] found
+                    outputSumBuffer[nbChanels * width * y + nbChanels * x + j] += value;
+                }
+            }
+        }
+
+        // save a new 
+        if (currentSample % step == 0){
+
+            unsigned nbElementsMean = currentSample / step;
+            float currentMean;
+
+            // get median all samples values by number of samples used (using MON method)
+            for (int j = 0; j < height * width * nbChanels; j++){
+
+                // get current mean for new samples luminances found
+                currentMean = outputSumBuffer[j] / step;
+
+                // insert this new mean into buffer (using `nbElementsMean - 1` because the new mean element is now inserted)
+                insertSorted(nbElementsMean - 1, outputMeanBuffer[j], currentMean);
+
+                // get meadian of these means as expected output luminance
+                outputStepBuffer[j] = getMedianValue(nbElementsMean, outputMeanBuffer[j]);
+            }
+
+
+            // add suffix with `5` digits
+            std::string suffix = std::to_string(currentSample);
+            
+            while(suffix.length() < 5){
+                suffix = "0" + suffix;
+            }
+
+            // build output path of image
+            std::string outfileName = outputFolder + "/" + prefixImageName + "_" + suffix + "." + imageExtension;
+            outfileName = std::regex_replace(outfileName, std::regex("\\//"), "/"); // fix path 
+
+            // save the expected `step` image using built outpath
+            saveCurrentImage(width, height, nbChanels, outputStepBuffer, outfileName, comments);
+            
+            // reinit `sum` buffer in order to get next mean
+            for (int j = 0; j < height * width * nbChanels; j++){
+                outputSumBuffer[j] = 0;
+            }
+
+            // just for progress information with erasing previous info
+            writeProgress(progress, true);
+        }
+
+        // update and write progress information
+        progress += (1 / (float)maxSamples);
+        writeProgress(progress);
+
+        delete buffer;
+    }
+    
+    writeProgress(1.);
+    std::cout << std::endl;
+
+    // clear all pointers memory
+    for (int j = 0; j < height * width * nbChanels; j++){
+        delete[] outputMeanBuffer[j];
+    }
+
+    delete outputMeanBuffer;
+    delete outputSumBuffer;
+    delete outputStepBuffer;
+}

+ 12 - 8
main/rawls_merge_mean_incr.cpp

@@ -137,7 +137,9 @@ int main(int argc, char *argv[]){
         comments = rawls::getCommentsRAWLS(imagesPath.at(0));
     }
 
-    for (unsigned i = 1; i < maxSamples; i++){
+    for (unsigned i = 0; i < maxSamples; i++){
+
+        unsigned currentSample = i + 1;
 
         // read into folder all `.rawls` file and merge pixels values
         float* buffer = rawls::getPixelsRAWLS(imagesPath.at(i));
@@ -149,29 +151,31 @@ int main(int argc, char *argv[]){
                 for(unsigned j = 0; j < nbChanels; j++){
                     
                     float value = buffer[nbChanels * width * y + nbChanels * x + j];
-                    outputBuffer[nbChanels * width * y + nbChanels * x + j] = outputBuffer[nbChanels * width * y + nbChanels * x + j] + value;
+                    outputBuffer[nbChanels * width * y + nbChanels * x + j] +=  value;
                 }
             }
         }
 
         // save a new 
-        if (i % step == 0){
+        if (currentSample % step == 0){
 
              // mean all samples values by number of samples used
             for (int j = 0; j < height * width * nbChanels; j++){
-                outputStepBuffer[j] = outputBuffer[j] / i;
+                outputStepBuffer[j] = outputBuffer[j] / currentSample;
             }
 
-            std::string suffix = std::to_string(i);
-
+            // add suffix with `5` digits
+            std::string suffix = std::to_string(currentSample);
+            
             while(suffix.length() < 5){
                 suffix = "0" + suffix;
             }
 
+            // build output path of image
             std::string outfileName = outputFolder + "/" + prefixImageName + "_" + suffix + "." + imageExtension;
-            // fix path
-            outfileName = std::regex_replace(outfileName, std::regex("\\//"), "/");
+            outfileName = std::regex_replace(outfileName, std::regex("\\//"), "/"); // fix path 
 
+            // save the expected `step` image using built outpath
             saveCurrentImage(width, height, nbChanels, outputStepBuffer, outfileName, comments);
             writeProgress(progress, true);
         }

+ 13 - 11
main/rawls_merge_median_incr.cpp

@@ -46,7 +46,7 @@ void insertSorted(unsigned size, float* values, float value){
     }
 
     // shift all values to right by one
-    for (int i = (size + 1) ; i > position; i--){        
+    for (int i = size; i > position; i--){        
         values[i] = values[i - 1];
     }
 
@@ -177,9 +177,9 @@ int main(int argc, char *argv[]){
         comments = rawls::getCommentsRAWLS(imagesPath.at(0));
     }
 
-    for (unsigned i = 1; i < maxSamples; i++){
+    for (unsigned i = 0; i < maxSamples; i++){
 
-        unsigned currentSample = i - 1;
+        unsigned currentSample = i + 1;
 
         // read into folder all `.rawls` file and merge pixels values
         float* buffer = rawls::getPixelsRAWLS(imagesPath.at(i));
@@ -192,30 +192,32 @@ int main(int argc, char *argv[]){
                     
                     float value = buffer[nbChanels * width * y + nbChanels * x + j];
 
-                    insertSorted(currentSample, outputBuffer[nbChanels * width * y + nbChanels * x + j], value);
+                    insertSorted(i, outputBuffer[nbChanels * width * y + nbChanels * x + j], value);
                 }
             }
         }
 
         // save a new 
-        if (i % step == 0){
+        if (currentSample % step == 0){
 
              // get median all samples values by number of samples used
             for (int j = 0; j < height * width * nbChanels; j++){
                 
-                outputStepBuffer[j] = getMedianValue((i), outputBuffer[j]);
+                outputStepBuffer[j] = getMedianValue(currentSample, outputBuffer[j]);
             }
-
-            std::string suffix = std::to_string(i);
-
+            
+            // add suffix with `5` digits
+            std::string suffix = std::to_string(currentSample);
+            
             while(suffix.length() < 5){
                 suffix = "0" + suffix;
             }
 
+            // build output path of image
             std::string outfileName = outputFolder + "/" + prefixImageName + "_" + suffix + "." + imageExtension;
-            // fix path 
-            outfileName = std::regex_replace(outfileName, std::regex("\\//"), "/");
+            outfileName = std::regex_replace(outfileName, std::regex("\\//"), "/"); // fix path 
 
+            // save the expected `step` image using built outpath
             saveCurrentImage(width, height, nbChanels, outputStepBuffer, outfileName, comments);
             writeProgress(progress, true);
         }

+ 50 - 0
reconstruct_png_mon.sh

@@ -0,0 +1,50 @@
+#! /bin/bash
+
+if [ -z "$1" ]
+  then
+    echo "No argument supplied"
+    echo "Need data folder"
+    exit 1
+fi
+
+if [ -z "$2" ]
+  then
+    echo "No argument supplied"
+    echo "Need output folder"
+    exit 1
+fi
+
+if [ -z "$3" ]
+  then
+    echo "No argument supplied"
+    echo "Need step output images expected (step of samples)"
+    exit 1
+fi
+
+prefix="p3d_"
+build_folder="build"
+
+data_folder=$1
+output_folder=$2
+step=$3
+
+for folder_path in $(ls -d ${data_folder}*/)
+do
+  nb_elements=$(ls -l ${folder_path} | grep ${prefix} | wc -l)
+
+  IFS='/' read -ra ADDR <<< "${folder_path}"
+  folder=${ADDR[-1]}
+
+  # get output expected path
+  output_scene_path=$output_folder/$folder
+  output_scene_path_fixed=${output_scene_path//\/\//\/}
+
+  if [ ! -d "$output_scene_path_fixed" ]; then
+    # Control will enter here if $DIRECTORY doesn't exist.
+    
+    mkdir -p $output_scene_path_fixed
+
+    ./${build_folder}/main/rawls_merge_MON_incr --folder ${folder_path} --output $output_scene_path_fixed --step ${step} --random 0 --prefix ${folder} --max ${nb_elements} --extension "png"
+      
+  fi
+done