main
Matthew 6 months ago
parent 339ba786f9
commit 2767bab6ea

2
.gitignore vendored

@ -33,6 +33,8 @@
# CMake # CMake
build/ build/
.vs/
x64/
# MacOS / Linux # MacOS / Linux
.DS_Store .DS_Store

@ -6,8 +6,11 @@ project(hdrplus)
# set c++ standard # set c++ standard
set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall -static-openmp")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -Wall") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -Wall -static-openmp")
add_definitions(-DUSE_LCMS2)
add_definitions(-DANDROID_STL=c++_shared)
# make sure we use Release and warn otherwise # make sure we use Release and warn otherwise
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
@ -24,7 +27,7 @@ else()
endif() endif()
# require OpenCV # require OpenCV
find_package( OpenCV 4 REQUIRED ) find_package( OpenCV 4 REQUIRED)
include_directories( BEFORE ${OpenCV_INCLUDE_DIRS} ) include_directories( BEFORE ${OpenCV_INCLUDE_DIRS} )
message(STATUS "Found OpenCV ${OpenCV_INCLUDE_DIRS} ${OpenCV_LIBS}") message(STATUS "Found OpenCV ${OpenCV_INCLUDE_DIRS} ${OpenCV_LIBS}")
@ -33,13 +36,25 @@ link_directories(/home/matthew/jniLibs/lib)
list(APPEND CMAKE_LIBRARY_PATH /home/matthew/jniLibs/lib/) list(APPEND CMAKE_LIBRARY_PATH /home/matthew/jniLibs/lib/)
# LibRaw-cmake 0.20 # LibRaw-cmake 0.20
# find_library(LIBRAW_LIBRARY raw /home/matthew/jniLibs/lib/) if(CMAKE_SYSTEM_NAME STREQUAL "Android")
SET(LIBRAW_LIBRARY "")
include_directories(${LIBRAW_INCLUDE_DIR})
link_directories(${LIBRAW_DIR})
else()
find_library(LIBRAW_LIBRARY raw)
message(STATUS "Found LIBRAW_LIBRARY to be ${LIBRAW_LIBRARY}" ) message(STATUS "Found LIBRAW_LIBRARY to be ${LIBRAW_LIBRARY}" )
endif()
# Exiv2 # Exiv2
find_package(exiv2 REQUIRED CONFIG NAMES exiv2) if(CMAKE_SYSTEM_NAME STREQUAL "Android")
message(STATUS "Found Exiv2 and linked") include_directories(${exiv2_DIR}/include)
link_directories(${exiv2_DIR}/lib)
else()
#find_package(exiv2 REQUIRED CONFIG NAMES exiv2)
#message(STATUS "Found Exiv2 and linked")
endif()
# OpenMP # OpenMP
find_package(OpenMP REQUIRED) find_package(OpenMP REQUIRED)
@ -67,18 +82,24 @@ add_library(${PROJECT_NAME} STATIC ${src_files} )
target_link_libraries(${PROJECT_NAME} PUBLIC target_link_libraries(${PROJECT_NAME} PUBLIC
${OpenCV_LIBS} ${OpenCV_LIBS}
# ${LIBRAW_LIBRARY} # ${LIBRAW_LIBRARY}
raw exiv2lib lcms2 lcms2 raw exiv2 exiv2-xmp expat z
OpenMP::OpenMP_CXX ) OpenMP::OpenMP_CXX )
# example # example
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin ) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin )
add_executable( demo add_executable( hdrp
bin/demo.cpp ) ${src_files}
target_link_libraries( demo bin/hdrplus.cpp )
${PROJECT_NAME} ) target_link_libraries( hdrp PUBLIC -fopenmp -static-openmp
${OpenCV_LIBS}
# ${LIBRAW_LIBRARY}
raw lcms2 exiv2 exiv2-xmp expat z
)
# unit test # unit test
if(WITH_TEST STREQUAL "ON")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/tests ) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/tests )
add_executable( test_bayer_image tests/test_bayer_image.cpp) add_executable( test_bayer_image tests/test_bayer_image.cpp)
@ -96,3 +117,4 @@ target_link_libraries( test_burst
add_executable( test_align tests/test_align.cpp ) add_executable( test_align tests/test_align.cpp )
target_link_libraries( test_align target_link_libraries( test_align
${PROJECT_NAME} ) ${PROJECT_NAME} )
endif()

@ -1,13 +0,0 @@
#include "hdrplus/hdrplus_pipeline.h"
int main( int argc, char** argv )
{
if ( argc != 3 )
{
printf("Usage: ./demo BURST_FOLDER_PATH(no / at end) REFERENCE_IMAGE_PATH\n");
exit(1);
}
hdrplus::hdrplus_pipeline pipeline;
pipeline.run_pipeline( argv[1], argv[ 2 ]);
}

Binary file not shown.

@ -0,0 +1,19 @@
#include "hdrplus/hdrplus_pipeline.h"
int main( int argc, char** argv )
{
std::vector<std::string> paths;
for (int idx = 2; idx < argc; idx++)
{
paths.push_back(argv[idx]);
}
cv::Mat rgb;
hdrplus::hdrplus_pipeline pipeline;
pipeline.run_pipeline( paths, 0, rgb);
cv::imwrite(argv[1], rgb);
return 0;
}

@ -4,6 +4,7 @@ export INSTALL_DIR="`pwd`/jni/hdrplus"
export NDK=/usr/local/ndk/android-ndk-r25c export NDK=/usr/local/ndk/android-ndk-r25c
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64 export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
export ABI=arm64-v8a export ABI=arm64-v8a
#export ABI=armeabi-v7a
export MINSDKVERSION=24 export MINSDKVERSION=24
export JNILIBS_DIR=/home/matthew/jniLibs export JNILIBS_DIR=/home/matthew/jniLibs
# export EXPAT_DIR=/home/matthew/exiv2ForAndroid-master/expat-2.2.2/jni/expat # export EXPAT_DIR=/home/matthew/exiv2ForAndroid-master/expat-2.2.2/jni/expat
@ -25,16 +26,16 @@ cmake \
-DBUILD_SHARED_LIBS=OFF \ -DBUILD_SHARED_LIBS=OFF \
-DENABLE_EXAMPLES=OFF \ -DENABLE_EXAMPLES=OFF \
-DHDRPLUS_NO_DETAILED_OUTPUT=1 \ -DHDRPLUS_NO_DETAILED_OUTPUT=1 \
-DCMAKE_PREFIX_PATH=$JNILIBS_DIR/lib/$ABI/cmake \ -DCMAKE_PREFIX_PATH=$JNILIBS_DIR/$ABI/lib/cmake \
-DOpenCV_DIR=$JNILIBS_DIR/opencv-mobile-4.9.0-android/sdk/native/jni \ -DOpenCV_DIR=$JNILIBS_DIR/opencv-mobile-4.10.0-android/sdk/native/jni \
-DLIBRAW_INCLUDE_DIR=$JNILIBS_DIR/include \ -DLIBRAW_INCLUDE_DIR=$JNILIBS_DIR/$ABI/include \
-DLIBRAW_DIR=$JNILIBS_DIR/lib/cmake \ -DLIBRAW_DIR=$JNILIBS_DIR/$ABI/lib \
-DJPEG_INCLUDE_DIR=$JNILIBS_DIR/include \ -DJPEG_INCLUDE_DIR=$JNILIBS_DIR/include \
-DJPEG_LIBRARIES=$JNILIBS_DIR/lib/$ABI \ -DJPEG_LIBRARIES=$JNILIBS_DIR/$ABI/lib \
-Dexiv2_INCLUDE_DIR=$JNILIBS_DIR/include \ -Dexiv2_INCLUDE_DIR=$JNILIBS_DIR/$ABI/include \
-Dexiv2_DIR=$JNILIBS_DIR/lib/cmake/exiv2 \ -Dexiv2_DIR=$JNILIBS_DIR/$ABI \
-DLCMS2_INCLUDE_DIR=$JNILIBS_DIR/include \ -DLCMS2_INCLUDE_DIR=$JNILIBS_DIR/$ABI/include \
-DLCMS2_LIBRARY=$JNILIBS_DIR/lib/$ABI \ -DLCMS2_LIBRARY=$JNILIBS_DIR/$ABI/lib \
-DLCMS2_LIBRARIES=lcms2 \ -DLCMS2_LIBRARIES=lcms2 \
.. ..

File diff suppressed because it is too large Load Diff

@ -0,0 +1,78 @@
#ifndef __ANDROID_HELPER_H__
#define __ANDROID_HELPER_H__
#ifdef __ANDROID__
#include <jni.h>
#include <android/log.h>
#include <string>
#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
#include <locale>
#include <codecvt>
#if 0
#ifndef ALOG
#define ALOG(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#ifdef NDEBUG
#define ALOG(...) do { if (0) { __ALOGV(__VA_ARGS__); } } while (0)
#else
#define ALOGV(...) __ALOGV(__VA_ARGS__)
#endif
#endif
#endif // 0
#define MP_TAG "MPLOG"
#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, MP_TAG,__VA_ARGS__)
#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, MP_TAG,__VA_ARGS__)
#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, MP_TAG, __VA_ARGS__)
#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, MP_TAG, __VA_ARGS__)
#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, MP_TAG,__VA_ARGS__)
#define AASSERT(cond, fmt, ...) \
if (!(cond)) { \
__android_log_assert(#cond, MP_TAG, fmt, ##__VA_ARGS__); \
}
inline std::string jstring2string(JNIEnv *env, jstring jStr)
{
if (!jStr)
return "";
const jclass stringClass = env->GetObjectClass(jStr);
const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(jStr, getBytes, env->NewStringUTF("UTF-8"));
size_t length = (size_t) env->GetArrayLength(stringJbytes);
jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);
std::string ret = std::string((char *)pBytes, length);
env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
env->DeleteLocalRef(stringJbytes);
env->DeleteLocalRef(stringClass);
return ret;
}
inline std::wstring utf8_to_wstr(const std::string& src)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
return converter.from_bytes(src);
}
inline int property_get(const char* key, char* buf, int len)
{
int ret = 0;
std::string command = "getprop ";
command += key;
FILE* file = popen(command.c_str(), "r");
if (file)
{
std::fgets(buf, len, file);
// ret = std::atoi(output);
pclose(file);
}
return ret;
}
#endif
#endif // __ANDROID_HELPER_H__

@ -10,10 +10,29 @@
namespace hdrplus namespace hdrplus
{ {
class MemFile
{
public:
std::vector<uint8_t> content;
const std::vector<uint8_t> GetConstData() const
{
return content;
}
std::vector<uint8_t> GetData()
{
return content;
}
};
class bayer_image class bayer_image
{ {
public: public:
explicit bayer_image( const std::string& bayer_image_path ); explicit bayer_image( const std::string& bayer_image_path );
explicit bayer_image( const std::vector<uint8_t>& bayer_image_content );
explicit bayer_image( std::shared_ptr<MemFile> bayer_image_file );
~bayer_image() = default; ~bayer_image() = default;
std::pair<double, double> get_noise_params() const; std::pair<double, double> get_noise_params() const;

@ -8,11 +8,14 @@
namespace hdrplus namespace hdrplus
{ {
class burst class burst
{ {
public: public:
explicit burst( const std::string& burst_path, const std::string& reference_image_path ); explicit burst( const std::string& burst_path, const std::string& reference_image_path );
explicit burst(const std::vector<std::string>& burst_paths, int reference_image_index); explicit burst(const std::vector<std::string>& burst_paths, int reference_image_index);
explicit burst( const std::vector<std::vector<uint8_t> >& bayer_image_contents, int reference_image_index );
explicit burst( const std::vector<std::shared_ptr<MemFile> >& bayer_image_files, int reference_image_index );
~burst() = default; ~burst() = default;

@ -33,10 +33,14 @@ class finish
bayer_image* refBayer; bayer_image* refBayer;
std::string mergedImgPath; std::string mergedImgPath;
finish() = default; finish()
{
refBayer = NULL;
}
// please use this initialization after merging part finish // please use this initialization after merging part finish
finish(std::string burstPath, cv::Mat mergedBayer,int refIdx){ finish(std::string burstPath, cv::Mat mergedBayer,int refIdx) {
refBayer = NULL;
this->refIdx = refIdx; this->refIdx = refIdx;
this->burstPath = burstPath; this->burstPath = burstPath;
this->mergedBayer = mergedBayer; this->mergedBayer = mergedBayer;
@ -60,7 +64,14 @@ class finish
~finish() = default; ~finish()
{
if (refBayer != NULL)
{
delete refBayer;
refBayer = NULL;
}
}
// finish pipeline func // finish pipeline func
// void process(std::string burstPath, cv::Mat mergedBayer,int refIdx); // void process(std::string burstPath, cv::Mat mergedBayer,int refIdx);
@ -79,8 +90,8 @@ class finish
// cv::Mat tmp(4208,3120,CV_16UC1); // cv::Mat tmp(4208,3120,CV_16UC1);
cv::Mat tmp(img); cv::Mat tmp(img);
// u_int16_t* ptr_tmp = (u_int16_t*)tmp.data; // uint16_t* ptr_tmp = (uint16_t*)tmp.data;
// u_int16_t* ptr_img = (u_int16_t*)img.data; // uint16_t* ptr_img = (uint16_t*)img.data;
// // col major to row major // // col major to row major
// for(int r = 0; r < tmp.rows; r++) { // for(int r = 0; r < tmp.rows; r++) {
// for(int c = 0; c < tmp.cols; c++) { // for(int c = 0; c < tmp.cols; c++) {
@ -91,7 +102,7 @@ class finish
// std::cout<<"width="<<tmp.cols<<std::endl; // std::cout<<"width="<<tmp.cols<<std::endl;
// cv::transpose(tmp, tmp); // cv::transpose(tmp, tmp);
u_int16_t* ptr = (u_int16_t*)tmp.data; uint16_t* ptr = (uint16_t*)tmp.data;
for(int r = 0; r < tmp.rows; r++) { for(int r = 0; r < tmp.rows; r++) {
for(int c = 0; c < tmp.cols; c++) { for(int c = 0; c < tmp.cols; c++) {
*(ptr+r*tmp.cols+c) = *(ptr+r*tmp.cols+c)/2048.0*255.0; *(ptr+r*tmp.cols+c) = *(ptr+r*tmp.cols+c)/2048.0*255.0;

@ -19,7 +19,10 @@ class hdrplus_pipeline
public: public:
void run_pipeline( const std::string& burst_path, const std::string& reference_image_path ); void run_pipeline( const std::string& burst_path, const std::string& reference_image_path );
void run_pipeline( const std::vector<std::string>& burst_paths, int reference_image_index, cv::Mat& finalImg ); bool run_pipeline( const std::vector<std::string>& burst_paths, int reference_image_index, cv::Mat& finalImg );
bool run_pipeline( const std::vector<std::vector<uint8_t> >& burst_contents, int reference_image_index, cv::Mat& finalImg );
bool run_pipeline( const std::vector<std::shared_ptr<MemFile> >& burst_contents, int reference_image_index, cv::Mat& finalImg );
hdrplus_pipeline() = default; hdrplus_pipeline() = default;
~hdrplus_pipeline() = default; ~hdrplus_pipeline() = default;
}; };

@ -1,8 +1,14 @@
#pragma once #pragma once
#ifdef _WIN32
#define _USE_MATH_DEFINES
#include <math.h>
#else
#include <cmath>
#endif
#include <vector> #include <vector>
#include <opencv2/opencv.hpp> // all opencv header #include <opencv2/opencv.hpp> // all opencv header
#include <cmath>
#include "hdrplus/burst.h" #include "hdrplus/burst.h"
#define TILE_SIZE 16 #define TILE_SIZE 16
@ -163,7 +169,7 @@ class merge
circshift(out, pt); circshift(out, pt);
} }
std::vector<cv::Mat> getReferenceTiles(cv::Mat reference_image); void getReferenceTiles(cv::Mat reference_image, std::vector<cv::Mat>& reference_tiles);
cv::Mat mergeTiles(std::vector<cv::Mat> tiles, int rows, int cols); cv::Mat mergeTiles(std::vector<cv::Mat> tiles, int rows, int cols);
@ -175,8 +181,8 @@ class merge
float lambda_read); float lambda_read);
//temporal denoise //temporal denoise
std::vector<cv::Mat> temporal_denoise(std::vector<cv::Mat> tiles, std::vector<std::vector<cv::Mat>> alt_tiles, std::vector<float> noise_variance, float temporal_factor); void temporal_denoise(std::vector<cv::Mat> tiles, std::vector<std::vector<cv::Mat>> alt_tiles, std::vector<float> noise_variance, float temporal_factor, std::vector<cv::Mat>& );
std::vector<cv::Mat> spatial_denoise(std::vector<cv::Mat> tiles, int num_alts, std::vector<float> noise_variance, float spatial_factor); void spatial_denoise(std::vector<cv::Mat> tiles, int num_alts, std::vector<float> noise_variance, float spatial_factor, std::vector<cv::Mat>&);
}; };

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <memory> // std::shared_ptr #include <memory> // std::shared_ptr
#include <opencv2/opencv.hpp> // all opencv header #include <opencv2/opencv.hpp> // all opencv header
#include <libraw/libraw.h> #include <libraw/libraw.h>
@ -45,26 +45,21 @@ class Tuning{
class Parameters{ class Parameters{
public: public:
std::unordered_map<std::string,bool> flags{ std::unordered_map<std::string,bool> flags;
{"writeReferenceImage",true},
{"writeGammaReference", true},
{"writeMergedImage", true},
{"writeGammaMerged", true},
{"writeShortExposure", true},
{"writeLongExposure", true},
{"writeFusedExposure", true},
{"writeLTMImage", true},
{"writeLTMGamma", true},
{"writeGTMImage", true},
{"writeReferenceFinal", true},
{"writeFinalImage", true}
};
RawpyArgs rawpyArgs; RawpyArgs rawpyArgs;
Options options; Options options;
Tuning tuning; Tuning tuning;
Parameters()= default; Parameters()
{
const char* keys[] = {"writeReferenceImage", "writeGammaReference", "writeMergedImage", "writeGammaMerged",
"writeShortExposure", "writeLongExposure", "writeFusedExposure", "writeLTMImage",
"writeLTMGamma", "writeGTMImage", "writeReferenceFinal", "writeFinalImage"};
for (int idx = 0; idx < sizeof(keys) / sizeof(const char*); idx++) {
flags[keys[idx]] = true;
}
}
}; };

@ -40,7 +40,11 @@ cv::Mat box_filter_kxk( const cv::Mat& src_image )
if ( kernel <= 0 ) if ( kernel <= 0 )
{ {
#ifdef __ANDROID__
return cv::Mat();
#else
throw std::runtime_error(std::string( __FILE__ ) + "::" + __func__ + " box filter only support kernel size >= 1"); throw std::runtime_error(std::string( __FILE__ ) + "::" + __func__ + " box filter only support kernel size >= 1");
#endif
} }
// int(src_height / kernel) = floor(src_height / kernel) // int(src_height / kernel) = floor(src_height / kernel)
@ -150,7 +154,10 @@ void print_cvmat( cv::Mat image )
} }
else else
{ {
#ifdef __ANDROID__
#else
throw std::runtime_error("cv::Mat number of channel currently not support to print\n"); throw std::runtime_error("cv::Mat number of channel currently not support to print\n");
#endif
} }
} }
@ -175,7 +182,10 @@ void extract_rgb_from_bayer( const cv::Mat& bayer_img, \
if ( bayer_width % 2 != 0 || bayer_height % 2 != 0 ) if ( bayer_width % 2 != 0 || bayer_height % 2 != 0 )
{ {
#ifdef __ANDROID__
#else
throw std::runtime_error("Bayer image data size incorrect, must be multiplier of 2\n"); throw std::runtime_error("Bayer image data size incorrect, must be multiplier of 2\n");
#endif
} }
// RGB image is half the size of bayer image // RGB image is half the size of bayer image

@ -106,7 +106,11 @@ static void build_per_grayimg_pyramid( \
images_pyramid.at( i ) = downsample_image.clone(); images_pyramid.at( i ) = downsample_image.clone();
break; break;
default: default:
#ifdef __ANDROID__
break;
#else
throw std::runtime_error("inv scale factor " + std::to_string( inv_scale_factors[ i ]) + "invalid" ); throw std::runtime_error("inv scale factor " + std::to_string( inv_scale_factors[ i ]) + "invalid" );
#endif
} }
} }
} }
@ -139,7 +143,11 @@ static void build_upsampled_prev_aligement( \
if ( dst_num_tiles_main_h > num_tiles_h || dst_num_tiles_main_w > num_tiles_w ) if ( dst_num_tiles_main_h > num_tiles_h || dst_num_tiles_main_w > num_tiles_w )
{ {
#ifdef __ANDROID__
return;
#else
throw std::runtime_error("current level number of tiles smaller than upsampled tiles\n"); throw std::runtime_error("current level number of tiles smaller than upsampled tiles\n");
#endif
} }
// Allocate data for dst_alignment // Allocate data for dst_alignment
@ -286,24 +294,40 @@ static unsigned long long l1_distance( const cv::Mat& img1, const cv::Mat& img2,
// Range check for safety // Range check for safety
if ( img1_tile_row_start_idx < 0 || img1_tile_row_start_idx > img1_height - tile_size ) if ( img1_tile_row_start_idx < 0 || img1_tile_row_start_idx > img1_height - tile_size )
{ {
#ifdef __ANDROID__
return 0;
#else
throw std::runtime_error("l1 distance img1_tile_row_start_idx" + std::to_string( img1_tile_row_start_idx ) + \ throw std::runtime_error("l1 distance img1_tile_row_start_idx" + std::to_string( img1_tile_row_start_idx ) + \
" out of valid range (0, " + std::to_string( img1_height - tile_size ) + ")\n" ); " out of valid range (0, " + std::to_string( img1_height - tile_size ) + ")\n" );
#endif
} }
if ( img1_tile_col_start_idx < 0 || img1_tile_col_start_idx > img1_width - tile_size ) if ( img1_tile_col_start_idx < 0 || img1_tile_col_start_idx > img1_width - tile_size )
{ {
#ifdef __ANDROID__
return 0;
#else
throw std::runtime_error("l1 distance img1_tile_col_start_idx" + std::to_string( img1_tile_col_start_idx ) + \ throw std::runtime_error("l1 distance img1_tile_col_start_idx" + std::to_string( img1_tile_col_start_idx ) + \
" out of valid range (0, " + std::to_string( img1_width - tile_size ) + ")\n" ); " out of valid range (0, " + std::to_string( img1_width - tile_size ) + ")\n" );
#endif
} }
if ( img2_tile_row_start_idx < 0 || img2_tile_row_start_idx > img2_height - tile_size ) if ( img2_tile_row_start_idx < 0 || img2_tile_row_start_idx > img2_height - tile_size )
{ {
#ifdef __ANDROID__
return 0;
#else
throw std::runtime_error("l1 distance img2_tile_row_start_idx out of valid range\n"); throw std::runtime_error("l1 distance img2_tile_row_start_idx out of valid range\n");
#endif
} }
if ( img2_tile_col_start_idx < 0 || img2_tile_col_start_idx > img2_width - tile_size ) if ( img2_tile_col_start_idx < 0 || img2_tile_col_start_idx > img2_width - tile_size )
{ {
#ifdef __ANDROID__
return 0;
#else
throw std::runtime_error("l1 distance img2_tile_col_start_idx out of valid range\n"); throw std::runtime_error("l1 distance img2_tile_col_start_idx out of valid range\n");
#endif
} }
return_type sum(0); return_type sum(0);
@ -350,24 +374,40 @@ static return_type l2_distance( const cv::Mat& img1, const cv::Mat& img2, \
// Range check for safety // Range check for safety
if ( img1_tile_row_start_idx < 0 || img1_tile_row_start_idx > img1_height - tile_size ) if ( img1_tile_row_start_idx < 0 || img1_tile_row_start_idx > img1_height - tile_size )
{ {
#ifdef __ANDROID__
return 0;
#else
throw std::runtime_error("l2 distance img1_tile_row_start_idx" + std::to_string( img1_tile_row_start_idx ) + \ throw std::runtime_error("l2 distance img1_tile_row_start_idx" + std::to_string( img1_tile_row_start_idx ) + \
" out of valid range (0, " + std::to_string( img1_height - tile_size ) + ")\n" ); " out of valid range (0, " + std::to_string( img1_height - tile_size ) + ")\n" );
#endif
} }
if ( img1_tile_col_start_idx < 0 || img1_tile_col_start_idx > img1_width - tile_size ) if ( img1_tile_col_start_idx < 0 || img1_tile_col_start_idx > img1_width - tile_size )
{ {
#ifdef __ANDROID__
return 0;
#else
throw std::runtime_error("l2 distance img1_tile_col_start_idx" + std::to_string( img1_tile_col_start_idx ) + \ throw std::runtime_error("l2 distance img1_tile_col_start_idx" + std::to_string( img1_tile_col_start_idx ) + \
" out of valid range (0, " + std::to_string( img1_width - tile_size ) + ")\n" ); " out of valid range (0, " + std::to_string( img1_width - tile_size ) + ")\n" );
#endif
} }
if ( img2_tile_row_start_idx < 0 || img2_tile_row_start_idx > img2_height - tile_size ) if ( img2_tile_row_start_idx < 0 || img2_tile_row_start_idx > img2_height - tile_size )
{ {
#ifdef __ANDROID__
return 0;
#else
throw std::runtime_error("l2 distance img2_tile_row_start_idx out of valid range\n"); throw std::runtime_error("l2 distance img2_tile_row_start_idx out of valid range\n");
#endif
} }
if ( img2_tile_col_start_idx < 0 || img2_tile_col_start_idx > img2_width - tile_size ) if ( img2_tile_col_start_idx < 0 || img2_tile_col_start_idx > img2_width - tile_size )
{ {
#ifdef __ANDROID__
return 0;
#else
throw std::runtime_error("l2 distance img2_tile_col_start_idx out of valid range\n"); throw std::runtime_error("l2 distance img2_tile_col_start_idx out of valid range\n");
#endif
} }
// printf("Search two tile with ref : \n"); // printf("Search two tile with ref : \n");
@ -407,14 +447,22 @@ static cv::Mat extract_img_tile( const cv::Mat& img, int img_tile_row_start_idx,
if ( img_tile_row_start_idx < 0 || img_tile_row_start_idx > img_height - tile_size ) if ( img_tile_row_start_idx < 0 || img_tile_row_start_idx > img_height - tile_size )
{ {
#ifdef __ANDROID__
return cv::Mat();
#else
throw std::runtime_error("extract_img_tile img_tile_row_start_idx " + std::to_string( img_tile_row_start_idx ) + \ throw std::runtime_error("extract_img_tile img_tile_row_start_idx " + std::to_string( img_tile_row_start_idx ) + \
" out of valid range (0, " + std::to_string( img_height - tile_size ) + ")\n" ); " out of valid range (0, " + std::to_string( img_height - tile_size ) + ")\n" );
#endif
} }
if ( img_tile_col_start_idx < 0 || img_tile_col_start_idx > img_width - tile_size ) if ( img_tile_col_start_idx < 0 || img_tile_col_start_idx > img_width - tile_size )
{ {
#ifdef __ANDROID__
return cv::Mat();
#else
throw std::runtime_error("extract_img_tile img_tile_col_start_idx " + std::to_string( img_tile_col_start_idx ) + \ throw std::runtime_error("extract_img_tile img_tile_col_start_idx " + std::to_string( img_tile_col_start_idx ) + \
" out of valid range (0, " + std::to_string( img_width - tile_size ) + ")\n" ); " out of valid range (0, " + std::to_string( img_width - tile_size ) + ")\n" );
#endif
} }
cv::Mat img_tile( tile_size, tile_size, img.type() ); cv::Mat img_tile( tile_size, tile_size, img.type() );
@ -494,7 +542,11 @@ void align_image_level( \
} }
else else
{ {
#ifdef __ANDROID__
return;
#else
throw std::runtime_error("Something wrong with upsampling function setting\n"); throw std::runtime_error("Something wrong with upsampling function setting\n");
#endif
} }
} }
@ -510,12 +562,20 @@ void align_image_level( \
} }
else else
{ {
#ifdef __ANDROID__
return;
#else
throw std::runtime_error("Something wrong with upsampling function setting\n"); throw std::runtime_error("Something wrong with upsampling function setting\n");
#endif
} }
} }
else else
{ {
#ifdef __ANDROID__
return;
#else
throw std::runtime_error("Something wrong with upsampling function setting\n"); throw std::runtime_error("Something wrong with upsampling function setting\n");
#endif
} }
} }
else if ( scale_factor_prev_curr == 4 ) else if ( scale_factor_prev_curr == 4 )
@ -532,7 +592,11 @@ void align_image_level( \
} }
else else
{ {
#ifdef __ANDROID__
return;
#else
throw std::runtime_error("Something wrong with upsampling function setting\n"); throw std::runtime_error("Something wrong with upsampling function setting\n");
#endif
} }
} }
@ -548,12 +612,20 @@ void align_image_level( \
} }
else else
{ {
#ifdef __ANDROID__
return;
#else
throw std::runtime_error("Something wrong with upsampling function setting\n"); throw std::runtime_error("Something wrong with upsampling function setting\n");
#endif
} }
} }
else else
{ {
#ifdef __ANDROID__
return;
#else
throw std::runtime_error("Something wrong with upsampling function setting\n"); throw std::runtime_error("Something wrong with upsampling function setting\n");
#endif
} }
} }
@ -713,7 +785,11 @@ void align_image_level( \
// print_tile<uint16_t>( alt_img_pad, curr_tile_size + 2 * search_radiou, alt_tile_row_start_idx_i, alt_tile_col_start_idx_i ); // print_tile<uint16_t>( alt_img_pad, curr_tile_size + 2 * search_radiou, alt_tile_row_start_idx_i, alt_tile_col_start_idx_i );
// Search based on L1/L2 distance // Search based on L1/L2 distance
#ifdef _WIN32
unsigned long long min_distance_i = ULLONG_MAX;
#else
unsigned long long min_distance_i = ULONG_LONG_MAX; unsigned long long min_distance_i = ULONG_LONG_MAX;
#endif
int min_distance_row_i = -1; int min_distance_row_i = -1;
int min_distance_col_i = -1; int min_distance_col_i = -1;
for ( int search_row_j = 0; search_row_j < ( search_radiou * 2 + 1 ); search_row_j++ ) for ( int search_row_j = 0; search_row_j < ( search_radiou * 2 + 1 ); search_row_j++ )
@ -861,6 +937,8 @@ void align::process( const hdrplus::burst& burst_images, \
// Align every image // Align every image
const std::vector<cv::Mat>& ref_grayimg_pyramid = per_grayimg_pyramid[ burst_images.reference_image_idx ]; const std::vector<cv::Mat>& ref_grayimg_pyramid = per_grayimg_pyramid[ burst_images.reference_image_idx ];
std::vector<std::vector<std::pair<int, int>>> curr_alignment;
std::vector<std::vector<std::pair<int, int>>> prev_alignment;
for ( int img_idx = 0; img_idx < burst_images.num_images; ++img_idx ) for ( int img_idx = 0; img_idx < burst_images.num_images; ++img_idx )
{ {
// Do not align with reference image // Do not align with reference image
@ -872,8 +950,8 @@ void align::process( const hdrplus::burst& burst_images, \
// Align every level from coarse to grain // Align every level from coarse to grain
// level 0 : finest level, the original image // level 0 : finest level, the original image
// level 3 : coarsest level // level 3 : coarsest level
std::vector<std::vector<std::pair<int, int>>> curr_alignment; curr_alignment.clear();
std::vector<std::vector<std::pair<int, int>>> prev_alignment; prev_alignment.clear();
for ( int level_i = num_levels - 1; level_i >= 0; level_i-- ) // 3,2,1,0 for ( int level_i = num_levels - 1; level_i >= 0; level_i-- ) // 3,2,1,0
{ {
// make curr alignment as previous alignment // make curr alignment as previous alignment
@ -913,6 +991,8 @@ void align::process( const hdrplus::burst& burst_images, \
} // for alternative image } // for alternative image
per_grayimg_pyramid.clear();
} }
} // namespace hdrplus } // namespace hdrplus

@ -21,13 +21,21 @@ bayer_image::bayer_image( const std::string& bayer_image_path )
if ( ( return_code = libraw_processor->open_file( bayer_image_path.c_str() ) ) != LIBRAW_SUCCESS ) if ( ( return_code = libraw_processor->open_file( bayer_image_path.c_str() ) ) != LIBRAW_SUCCESS )
{ {
libraw_processor->recycle(); libraw_processor->recycle();
#ifdef __ANDROID__
return;
#else
throw std::runtime_error("Error opening file " + bayer_image_path + " " + libraw_strerror( return_code )); throw std::runtime_error("Error opening file " + bayer_image_path + " " + libraw_strerror( return_code ));
#endif
} }
// Unpack the raw image // Unpack the raw image
if ( ( return_code = libraw_processor->unpack() ) != LIBRAW_SUCCESS ) if ( ( return_code = libraw_processor->unpack() ) != LIBRAW_SUCCESS )
{ {
#ifdef __ANDROID__
return;
#else
throw std::runtime_error("Error unpack file " + bayer_image_path + " " + libraw_strerror( return_code )); throw std::runtime_error("Error unpack file " + bayer_image_path + " " + libraw_strerror( return_code ));
#endif
} }
// Get image basic info // Get image basic info
@ -69,6 +77,142 @@ bayer_image::bayer_image( const std::string& bayer_image_path )
#endif #endif
} }
bayer_image::bayer_image( const std::vector<uint8_t>& bayer_image_content )
{
libraw_processor = std::make_shared<LibRaw>();
// Open RAW image file
int return_code;
if ( ( return_code = libraw_processor->open_buffer( (void *)(&bayer_image_content[0]), bayer_image_content.size() ) ) != LIBRAW_SUCCESS )
{
libraw_processor->recycle();
#ifdef __ANDROID__ || _WIN32
return;
#else
// throw std::runtime_error("Error opening file " + bayer_image_path + " " + libraw_strerror( return_code ));
return;
#endif
}
// Unpack the raw image
if ( ( return_code = libraw_processor->unpack() ) != LIBRAW_SUCCESS )
{
#ifdef __ANDROID__ || _WIN32
return;
#else
// throw std::runtime_error("Error unpack file " + bayer_image_path + " " + libraw_strerror( return_code ));
return;
#endif
}
// Get image basic info
width = int( libraw_processor->imgdata.rawdata.sizes.raw_width );
height = int( libraw_processor->imgdata.rawdata.sizes.raw_height );
// Read exif tags
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(&bayer_image_content[0], bayer_image_content.size());
assert(image.get() != 0);
image->readMetadata();
Exiv2::ExifData &exifData = image->exifData();
if (exifData.empty()) {
std::string error = "No Exif data found in the file";
std::cout << error << std::endl;
}
white_level = exifData["Exif.Image.WhiteLevel"].toLong();
black_level_per_channel.resize( 4 );
black_level_per_channel.at(0) = exifData["Exif.Image.BlackLevel"].toLong(0);
black_level_per_channel.at(1) = exifData["Exif.Image.BlackLevel"].toLong(1);
black_level_per_channel.at(2) = exifData["Exif.Image.BlackLevel"].toLong(2);
black_level_per_channel.at(3) = exifData["Exif.Image.BlackLevel"].toLong(3);
iso = exifData["Exif.Image.ISOSpeedRatings"].toLong();
// Create CV mat
// https://answers.opencv.org/question/105972/de-bayering-a-cr2-image/
// https://www.libraw.org/node/2141
raw_image = cv::Mat( height, width, CV_16U, libraw_processor->imgdata.rawdata.raw_image ).clone(); // changed the order of width and height
// 2x2 box filter
grayscale_image = box_filter_kxk<uint16_t, 2>( raw_image );
#ifndef NDEBUG
printf("%s::%s read bayer image with\n width %zu\n height %zu\n iso %.3f\n white level %d\n black level %d %d %d %d\n", \
__FILE__, __func__, width, height, iso, white_level, \
black_level_per_channel[0], black_level_per_channel[1], black_level_per_channel[2], black_level_per_channel[3] );
fflush( stdout );
#endif
}
bayer_image::bayer_image( std::shared_ptr<MemFile> bayer_image_file )
{
libraw_processor = std::make_shared<LibRaw>();
// Open RAW image file
int return_code;
{
std::vector<uint8_t>& fileData = bayer_image_file->content;
if ( ( return_code = libraw_processor->open_buffer( (void *)(&fileData[0]), fileData.size() ) ) != LIBRAW_SUCCESS )
{
libraw_processor->recycle();
#ifdef __ANDROID__
return;
#else
return;
// throw std::runtime_error("Error opening file " + bayer_image_path + " " + libraw_strerror( return_code ));
#endif
}
}
// Unpack the raw image
if ( ( return_code = libraw_processor->unpack() ) != LIBRAW_SUCCESS )
{
#ifdef __ANDROID__
return;
#else
return;
// throw std::runtime_error("Error unpack file " + bayer_image_path + " " + libraw_strerror( return_code ));
#endif
}
// Get image basic info
width = int( libraw_processor->imgdata.rawdata.sizes.raw_width );
height = int( libraw_processor->imgdata.rawdata.sizes.raw_height );
// Read exif tags
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(&bayer_image_file->content[0], bayer_image_file->content.size());
assert(image.get() != 0);
image->readMetadata();
Exiv2::ExifData &exifData = image->exifData();
if (exifData.empty()) {
std::string error = "No Exif data found in the file";
std::cout << error << std::endl;
}
white_level = exifData["Exif.Image.WhiteLevel"].toLong();
black_level_per_channel.resize( 4 );
black_level_per_channel.at(0) = exifData["Exif.Image.BlackLevel"].toLong(0);
black_level_per_channel.at(1) = exifData["Exif.Image.BlackLevel"].toLong(1);
black_level_per_channel.at(2) = exifData["Exif.Image.BlackLevel"].toLong(2);
black_level_per_channel.at(3) = exifData["Exif.Image.BlackLevel"].toLong(3);
iso = exifData["Exif.Image.ISOSpeedRatings"].toLong();
// Create CV mat
// https://answers.opencv.org/question/105972/de-bayering-a-cr2-image/
// https://www.libraw.org/node/2141
raw_image = cv::Mat( height, width, CV_16U, libraw_processor->imgdata.rawdata.raw_image ).clone(); // changed the order of width and height
// 2x2 box filter
grayscale_image = box_filter_kxk<uint16_t, 2>( raw_image );
#ifndef NDEBUG
printf("%s::%s read bayer image with\n width %zu\n height %zu\n iso %.3f\n white level %d\n black level %d %d %d %d\n", \
__FILE__, __func__, width, height, iso, white_level, \
black_level_per_channel[0], black_level_per_channel[1], black_level_per_channel[2], black_level_per_channel[3] );
fflush( stdout );
#endif
}
std::pair<double, double> bayer_image::get_noise_params() const std::pair<double, double> bayer_image::get_noise_params() const
{ {
// Set ISO to 100 if not positive // Set ISO to 100 if not positive

@ -41,7 +41,8 @@ burst::burst( const std::string& burst_path, const std::string& reference_image_
if ( reference_image_idx == -1 ) if ( reference_image_idx == -1 )
{ {
throw std::runtime_error("Error unable to locate reference image " + reference_image_path ); return;
// throw std::runtime_error("Error unable to locate reference image " + reference_image_path );
} }
#ifndef NDEBUG #ifndef NDEBUG
@ -109,14 +110,15 @@ burst::burst( const std::vector<std::string>& bayer_image_paths, int reference_i
// Find reference image path in input directory // Find reference image path in input directory
// reference image path need to be absolute path // reference image path need to be absolute path
reference_image_idx = -1; reference_image_idx = -1;
if ( reference_image_index > 0 && reference_image_index < bayer_image_paths.size() ) if ( reference_image_index >= 0 && reference_image_index < bayer_image_paths.size() )
{ {
reference_image_idx = reference_image_index; reference_image_idx = reference_image_index;
} }
if ( reference_image_idx == -1 ) if ( reference_image_idx == -1 )
{ {
throw std::runtime_error("Error reference image index is out of range " ); return;
// throw std::runtime_error("Error reference image index is out of range " );
} }
#ifndef NDEBUG #ifndef NDEBUG
@ -176,4 +178,144 @@ burst::burst( const std::vector<std::string>& bayer_image_paths, int reference_i
#endif #endif
} }
burst::burst( const std::vector<std::vector<uint8_t> >& bayer_image_contents, int reference_image_index )
{
// Number of images
num_images = bayer_image_contents.size();
// Find reference image path in input directory
// reference image path need to be absolute path
reference_image_idx = -1;
if ( reference_image_index >= 0 && reference_image_index < bayer_image_contents.size() )
{
reference_image_idx = reference_image_index;
}
if ( reference_image_idx == -1 )
{
return;
// throw std::runtime_error("Error reference image index is out of range " );
}
#ifndef NDEBUG
printf("%s::%s reference image idx %d\n", \
__FILE__, __func__, reference_image_idx );
#endif
// Get source bayer image
// Downsample original bayer image by 2x2 box filter
for ( const auto& bayer_image_content : bayer_image_contents )
{
bayer_images.emplace_back( bayer_image_content );
}
// Pad information
int tile_size_bayer = 32;
int padding_top = tile_size_bayer / 2;
int padding_bottom = tile_size_bayer / 2 + \
( (bayer_images[ 0 ].height % tile_size_bayer) == 0 ? \
0 : tile_size_bayer - bayer_images[ 0 ].height % tile_size_bayer );
int padding_left = tile_size_bayer / 2;
int padding_right = tile_size_bayer / 2 + \
( (bayer_images[ 0 ].width % tile_size_bayer) == 0 ? \
0 : tile_size_bayer - bayer_images[ 0 ].width % tile_size_bayer );
padding_info_bayer = std::vector<int>{ padding_top, padding_bottom, padding_left, padding_right };
// Pad bayer image
for ( const auto& bayer_image_i : bayer_images )
{
cv::Mat bayer_image_pad_i;
cv::copyMakeBorder( bayer_image_i.raw_image, \
bayer_image_pad_i, \
padding_top, padding_bottom, padding_left, padding_right, \
cv::BORDER_REFLECT );
// cv::Mat use internal reference count
bayer_images_pad.emplace_back( bayer_image_pad_i );
grayscale_images_pad.emplace_back( box_filter_kxk<uint16_t, 2>( bayer_image_pad_i ) );
}
#ifndef NDEBUG
printf("%s::%s Pad bayer image from (%d, %d) -> (%d, %d)\n", \
__FILE__, __func__, \
bayer_images[ 0 ].height, \
bayer_images[ 0 ].width, \
bayer_images_pad[ 0 ].size().height, \
bayer_images_pad[ 0 ].size().width );
printf("%s::%s pad top %d, buttom %d, left %d, right %d\n", \
__FILE__, __func__, \
padding_top, padding_bottom, padding_left, padding_right );
#endif
}
burst::burst( const std::vector<std::shared_ptr<MemFile> >& bayer_image_files, int reference_image_index )
{
// Number of images
num_images = bayer_image_files.size();
// Find reference image path in input directory
// reference image path need to be absolute path
reference_image_idx = -1;
if ( reference_image_index >= 0 && reference_image_index < bayer_image_files.size() )
{
reference_image_idx = reference_image_index;
}
if ( reference_image_idx == -1 )
{
return;
// throw std::runtime_error("Error reference image index is out of range " );
}
#ifndef NDEBUG
printf("%s::%s reference image idx %d\n", \
__FILE__, __func__, reference_image_idx );
#endif
// Get source bayer image
// Downsample original bayer image by 2x2 box filter
for ( const auto& bayer_image_file : bayer_image_files )
{
bayer_images.emplace_back( bayer_image_file );
}
// Pad information
int tile_size_bayer = 32;
int padding_top = tile_size_bayer / 2;
int padding_bottom = tile_size_bayer / 2 + \
( (bayer_images[ 0 ].height % tile_size_bayer) == 0 ? \
0 : tile_size_bayer - bayer_images[ 0 ].height % tile_size_bayer );
int padding_left = tile_size_bayer / 2;
int padding_right = tile_size_bayer / 2 + \
( (bayer_images[ 0 ].width % tile_size_bayer) == 0 ? \
0 : tile_size_bayer - bayer_images[ 0 ].width % tile_size_bayer );
padding_info_bayer = std::vector<int>{ padding_top, padding_bottom, padding_left, padding_right };
// Pad bayer image
for ( const auto& bayer_image_i : bayer_images )
{
cv::Mat bayer_image_pad_i;
cv::copyMakeBorder( bayer_image_i.raw_image, \
bayer_image_pad_i, \
padding_top, padding_bottom, padding_left, padding_right, \
cv::BORDER_REFLECT );
// cv::Mat use internal reference count
bayer_images_pad.emplace_back( bayer_image_pad_i );
grayscale_images_pad.emplace_back( box_filter_kxk<uint16_t, 2>( bayer_image_pad_i ) );
}
#ifndef NDEBUG
printf("%s::%s Pad bayer image from (%d, %d) -> (%d, %d)\n", \
__FILE__, __func__, \
bayer_images[ 0 ].height, \
bayer_images[ 0 ].width, \
bayer_images_pad[ 0 ].size().height, \
bayer_images_pad[ 0 ].size().width );
printf("%s::%s pad top %d, buttom %d, left %d, right %d\n", \
__FILE__, __func__, \
padding_top, padding_bottom, padding_left, padding_right );
#endif
}
} // namespace hdrplus } // namespace hdrplus

@ -1,15 +1,27 @@
#ifdef _WIN32
#define _USE_MATH_DEFINES
#include <math.h>
#else
#include <cmath>
#endif
#include <iostream> #include <iostream>
#include <opencv2/opencv.hpp> // all opencv header #include <opencv2/opencv.hpp> // all opencv header
#include "hdrplus/finish.h" #include "hdrplus/finish.h"
#include "hdrplus/utility.h" #include "hdrplus/utility.h"
#include <cmath> #ifdef _WIN32
#include <stdint.h>
#endif
#ifdef __ANDROID__
#define DBG_OUTPUT_ROOT "/sdcard/com.xypower.mpapp/tmp/"
#else
#define DBG_OUTPUT_ROOT ""
#endif
// #include <type_traits> // #include <type_traits>
namespace hdrplus namespace hdrplus
{ {
cv::Mat convert16bit2_8bit_(cv::Mat ans){ cv::Mat convert16bit2_8bit_(cv::Mat ans){
if(ans.type()==CV_16UC3){ if(ans.type()==CV_16UC3){
cv::MatIterator_<cv::Vec3w> it, end; cv::MatIterator_<cv::Vec3w> it, end;
@ -22,7 +34,7 @@ namespace hdrplus
} }
ans.convertTo(ans, CV_8UC3); ans.convertTo(ans, CV_8UC3);
}else if(ans.type()==CV_16UC1){ }else if(ans.type()==CV_16UC1){
u_int16_t* ptr = (u_int16_t*)ans.data; uint16_t* ptr = (uint16_t*)ans.data;
int end = ans.rows*ans.cols; int end = ans.rows*ans.cols;
for(int i=0;i<end;i++){ for(int i=0;i<end;i++){
*(ptr+i) *=(255.0/USHRT_MAX); *(ptr+i) *=(255.0/USHRT_MAX);
@ -48,7 +60,7 @@ namespace hdrplus
}else if(ans.type()==CV_8UC1){ }else if(ans.type()==CV_8UC1){
ans.convertTo(ans, CV_16UC1); ans.convertTo(ans, CV_16UC1);
u_int16_t* ptr = (u_int16_t*)ans.data; uint16_t* ptr = (uint16_t*)ans.data;
int end = ans.rows*ans.cols; int end = ans.rows*ans.cols;
for(int i=0;i<end;i++){ for(int i=0;i<end;i++){
*(ptr+i) *=(65535.0/255.0); *(ptr+i) *=(65535.0/255.0);
@ -129,7 +141,7 @@ namespace hdrplus
(*it)[2] =uGammaCompress_1pix((*it)[2],threshold,gainMin,gainMax,exponent); (*it)[2] =uGammaCompress_1pix((*it)[2],threshold,gainMin,gainMax,exponent);
} }
}else if(m.type()==CV_16UC1){ }else if(m.type()==CV_16UC1){
u_int16_t* ptr = (u_int16_t*)m.data; uint16_t* ptr = (uint16_t*)m.data;
int end = m.rows*m.cols; int end = m.rows*m.cols;
for(int i=0;i<end;i++){ for(int i=0;i<end;i++){
*(ptr+i) = uGammaCompress_1pix(*(ptr+i),threshold,gainMin,gainMax,exponent); *(ptr+i) = uGammaCompress_1pix(*(ptr+i),threshold,gainMin,gainMax,exponent);
@ -151,7 +163,7 @@ namespace hdrplus
(*it)[2] =uGammaDecompress_1pix((*it)[2],threshold,gainMin,gainMax,exponent); (*it)[2] =uGammaDecompress_1pix((*it)[2],threshold,gainMin,gainMax,exponent);
} }
}else if(m.type()==CV_16UC1){ }else if(m.type()==CV_16UC1){
u_int16_t* ptr = (u_int16_t*)m.data; uint16_t* ptr = (uint16_t*)m.data;
int end = m.rows*m.cols; int end = m.rows*m.cols;
for(int i=0;i<end;i++){ for(int i=0;i<end;i++){
*(ptr+i) = uGammaDecompress_1pix(*(ptr+i),threshold,gainMin,gainMax,exponent); *(ptr+i) = uGammaDecompress_1pix(*(ptr+i),threshold,gainMin,gainMax,exponent);
@ -172,9 +184,10 @@ namespace hdrplus
} }
} }
void copy_mat_16U_2(u_int16_t* ptr_A, cv::Mat B){ void copy_mat_16U_2(uint16_t* ptr_A, cv::Mat B)
// u_int16_t* ptr_A = (u_int16_t*)A.data; {
u_int16_t* ptr_B = (u_int16_t*)B.data; // uint16_t* ptr_A = (uint16_t*)A.data;
uint16_t* ptr_B = (uint16_t*)B.data;
for(int r = 0; r < B.rows; r++) { for(int r = 0; r < B.rows; r++) {
for(int c = 0; c < B.cols; c++) { for(int c = 0; c < B.cols; c++) {
*(ptr_A+r*B.cols+c) = *(ptr_B+r*B.cols+c); *(ptr_A+r*B.cols+c) = *(ptr_B+r*B.cols+c);
@ -187,7 +200,7 @@ namespace hdrplus
int H = img.rows; int H = img.rows;
int W = img.cols; int W = img.cols;
cv::Mat processedImg = cv::Mat(H,W,CV_16UC1); cv::Mat processedImg = cv::Mat(H,W,CV_16UC1);
u_int16_t* ptr = (u_int16_t*)processedImg.data; uint16_t* ptr = (uint16_t*)processedImg.data;
// traverse img // traverse img
int idx = 0; int idx = 0;
@ -204,7 +217,7 @@ namespace hdrplus
} }
double getMean(cv::Mat img){ double getMean(cv::Mat img){
u_int16_t* ptr = (u_int16_t*)img.data; uint16_t* ptr = (uint16_t*)img.data;
int max_idx = img.rows*img.cols*img.channels(); int max_idx = img.rows*img.cols*img.channels();
double sum=0; double sum=0;
for(int i=0;i<max_idx;i++){ for(int i=0;i<max_idx;i++){
@ -216,7 +229,7 @@ namespace hdrplus
} }
cv::Mat matMultiply_scalar(cv::Mat img,float gain){ cv::Mat matMultiply_scalar(cv::Mat img,float gain){
u_int16_t* ptr = (u_int16_t*)img.data; uint16_t* ptr = (uint16_t*)img.data;
int max_idx = img.rows*img.cols*img.channels(); int max_idx = img.rows*img.cols*img.channels();
for(int i=0;i<max_idx;i++){ for(int i=0;i<max_idx;i++){
double tmp = *(ptr+i)*gain; double tmp = *(ptr+i)*gain;
@ -225,7 +238,7 @@ namespace hdrplus
}else if(tmp>USHRT_MAX){ }else if(tmp>USHRT_MAX){
*(ptr+i) = USHRT_MAX; *(ptr+i) = USHRT_MAX;
}else{ }else{
*(ptr+i)=(u_int16_t)tmp; *(ptr+i)=(uint16_t)tmp;
} }
} }
return img; return img;
@ -234,7 +247,7 @@ namespace hdrplus
double getSaturated(cv::Mat img, double threshold){ double getSaturated(cv::Mat img, double threshold){
threshold *= USHRT_MAX; threshold *= USHRT_MAX;
double count=0; double count=0;
u_int16_t* ptr = (u_int16_t*)img.data; uint16_t* ptr = (uint16_t*)img.data;
int max_idx = img.rows*img.cols*img.channels(); int max_idx = img.rows*img.cols*img.channels();
for(int i=0;i<max_idx;i++){ for(int i=0;i<max_idx;i++){
if(*(ptr+i)>threshold){ if(*(ptr+i)>threshold){
@ -253,7 +266,7 @@ namespace hdrplus
int H = img.rows; int H = img.rows;
int W = img.cols; int W = img.cols;
cv::Mat processedImg = cv::Mat(H,W,CV_16UC1); cv::Mat processedImg = cv::Mat(H,W,CV_16UC1);
u_int16_t* ptr = (u_int16_t*)processedImg.data; uint16_t* ptr = (uint16_t*)processedImg.data;
int idx=0; int idx=0;
cv::MatIterator_<cv::Vec3w> it, end; cv::MatIterator_<cv::Vec3w> it, end;
@ -290,8 +303,8 @@ namespace hdrplus
cv::Mat applyScaling_(cv::Mat mergedImage, cv::Mat shortGray, cv::Mat fusedGray){ cv::Mat applyScaling_(cv::Mat mergedImage, cv::Mat shortGray, cv::Mat fusedGray){
cv::Mat result = mergedImage.clone(); cv::Mat result = mergedImage.clone();
u_int16_t* ptr_shortg = (u_int16_t*)shortGray.data; uint16_t* ptr_shortg = (uint16_t*)shortGray.data;
u_int16_t* ptr_fusedg = (u_int16_t*)fusedGray.data; uint16_t* ptr_fusedg = (uint16_t*)fusedGray.data;
int count = 0; int count = 0;
cv::MatIterator_<cv::Vec3w> it, end; cv::MatIterator_<cv::Vec3w> it, end;
for( it = result.begin<cv::Vec3w>(), end = result.end<cv::Vec3w>(); it != end; ++it) for( it = result.begin<cv::Vec3w>(), end = result.end<cv::Vec3w>(); it != end; ++it)
@ -384,7 +397,7 @@ namespace hdrplus
std::cout<<"--- Scale channels"<<std::endl; std::cout<<"--- Scale channels"<<std::endl;
} }
u_int16_t enhanceContrast_1pix(u_int16_t pix_val,double gain){ uint16_t enhanceContrast_1pix(uint16_t pix_val,double gain){
double x = pix_val; double x = pix_val;
x/=USHRT_MAX; x/=USHRT_MAX;
x = x - gain*sin(2*M_PI*x); x = x - gain*sin(2*M_PI*x);
@ -393,13 +406,13 @@ namespace hdrplus
}else if(x>1){ }else if(x>1){
x = 1; x = 1;
} }
u_int16_t result = x*USHRT_MAX; uint16_t result = x*USHRT_MAX;
return result; return result;
} }
cv::Mat enhanceContrast(cv::Mat image, Options options){ cv::Mat enhanceContrast(cv::Mat image, Options options){
if(options.gtmContrast>=0 && options.gtmContrast<=1){ if(options.gtmContrast>=0 && options.gtmContrast<=1){
u_int16_t* ptr = (u_int16_t*)image.data; uint16_t* ptr = (uint16_t*)image.data;
int end = image.rows*image.cols*image.channels(); int end = image.rows*image.cols*image.channels();
for(int idx = 0;idx<end;idx++){ for(int idx = 0;idx<end;idx++){
*(ptr+idx) = enhanceContrast_1pix(*(ptr+idx),options.gtmContrast); *(ptr+idx) = enhanceContrast_1pix(*(ptr+idx),options.gtmContrast);
@ -415,9 +428,9 @@ namespace hdrplus
int end_y = Y.rows*Y.cols*Y.channels(); int end_y = Y.rows*Y.cols*Y.channels();
cv::Mat result = cv::Mat(X.rows,X.cols,X.type()); cv::Mat result = cv::Mat(X.rows,X.cols,X.type());
if(end_x==end_y){ if(end_x==end_y){
u_int16_t* ptr_x = (u_int16_t*)X.data; uint16_t* ptr_x = (uint16_t*)X.data;
u_int16_t* ptr_y = (u_int16_t*)Y.data; uint16_t* ptr_y = (uint16_t*)Y.data;
u_int16_t* ptr_r = (u_int16_t*)result.data; uint16_t* ptr_r = (uint16_t*)result.data;
for(int i=0;i<end_x;i++){ for(int i=0;i<end_x;i++){
if(*(ptr_x+i)<*(ptr_y+i)){ if(*(ptr_x+i)<*(ptr_y+i)){
*(ptr_r+i) = *(ptr_y+i) - *(ptr_x+i); *(ptr_r+i) = *(ptr_y+i) - *(ptr_x+i);
@ -438,14 +451,14 @@ namespace hdrplus
// create result mat // create result mat
cv::Mat result = cv::Mat(image.rows,image.cols,image.type()); cv::Mat result = cv::Mat(image.rows,image.cols,image.type());
// initialize iteraters // initialize iteraters
u_int16_t* ptr_r = (u_int16_t*)result.data; uint16_t* ptr_r = (uint16_t*)result.data;
u_int16_t* ptr_img = (u_int16_t*)image.data; uint16_t* ptr_img = (uint16_t*)image.data;
u_int16_t* ptr_blur0 = (u_int16_t*)blur0.data; uint16_t* ptr_blur0 = (uint16_t*)blur0.data;
u_int16_t* ptr_low0 = (u_int16_t*)low0.data; uint16_t* ptr_low0 = (uint16_t*)low0.data;
u_int16_t* ptr_blur1 = (u_int16_t*)blur1.data; uint16_t* ptr_blur1 = (uint16_t*)blur1.data;
u_int16_t* ptr_low1 = (u_int16_t*)low1.data; uint16_t* ptr_low1 = (uint16_t*)low1.data;
u_int16_t* ptr_blur2 = (u_int16_t*)blur2.data; uint16_t* ptr_blur2 = (uint16_t*)blur2.data;
u_int16_t* ptr_low2 = (u_int16_t*)low2.data; uint16_t* ptr_low2 = (uint16_t*)low2.data;
int n_channels = image.channels(); int n_channels = image.channels();
int end = image.rows*image.cols*n_channels; int end = image.rows*image.cols*n_channels;
// traverse Image // traverse Image
@ -464,7 +477,7 @@ namespace hdrplus
r = (r0+r1+r2)/3.0; r = (r0+r1+r2)/3.0;
if(r<0) r=0; if(r<0) r=0;
if(r>USHRT_MAX) r = USHRT_MAX; if(r>USHRT_MAX) r = USHRT_MAX;
*(ptr_r+idx) = (u_int16_t)r; *(ptr_r+idx) = (uint16_t)r;
} }
return result; return result;
} }
@ -496,9 +509,9 @@ namespace hdrplus
return sharpImage; return sharpImage;
} }
void copy_mat_16U_3(u_int16_t* ptr_A, cv::Mat B){ void copy_mat_16U_3(uint16_t* ptr_A, cv::Mat B){
// u_int16_t* ptr_A = (u_int16_t*)A.data; // uint16_t* ptr_A = (uint16_t*)A.data;
u_int16_t* ptr_B = (u_int16_t*)B.data; uint16_t* ptr_B = (uint16_t*)B.data;
int H = B.rows; int H = B.rows;
int W = B.cols; int W = B.cols;
int end = H*W; int end = H*W;
@ -507,9 +520,9 @@ namespace hdrplus
} }
} }
// void copy_mat_16U_3(u_int16_t* ptr_A, cv::Mat B){ // void copy_mat_16U_3(uint16_t* ptr_A, cv::Mat B){
// // u_int16_t* ptr_A = (u_int16_t*)A.data; // // uint16_t* ptr_A = (uint16_t*)A.data;
// u_int16_t* ptr_B = (u_int16_t*)B.data; // uint16_t* ptr_B = (uint16_t*)B.data;
// for(int r = 0; r < B.rows; r++) { // for(int r = 0; r < B.rows; r++) {
// for(int c = 0; c < B.cols; c++) { // for(int c = 0; c < B.cols; c++) {
// *(ptr_A+r*B.cols+c) = *(ptr_B+r*B.cols+c); // *(ptr_A+r*B.cols+c) = *(ptr_B+r*B.cols+c);
@ -518,6 +531,7 @@ namespace hdrplus
// } // }
cv::Mat processMergedMat(cv::Mat mergedImg, int opencv_type){ cv::Mat processMergedMat(cv::Mat mergedImg, int opencv_type){
cv::Mat m; cv::Mat m;
#if 0
uint16_t* ptr = (uint16_t*)mergedImg.data; uint16_t* ptr = (uint16_t*)mergedImg.data;
for(int r = 0; r < mergedImg.rows; r++) { for(int r = 0; r < mergedImg.rows; r++) {
std::vector<int> dvals; std::vector<int> dvals;
@ -528,17 +542,18 @@ namespace hdrplus
cv::transpose(mline, mline); cv::transpose(mline, mline);
m.push_back(mline); m.push_back(mline);
} }
#endif
int ch = CV_MAT_CN(opencv_type); int ch = CV_MAT_CN(opencv_type);
m = mergedImg.clone();
m = m.reshape(ch); m = m.reshape(ch);
m.convertTo(m, opencv_type); m.convertTo(m, opencv_type);
return m; return m;
} }
void show20_20(cv::Mat m){ void show20_20(cv::Mat m){
u_int16_t* ptr = (u_int16_t*)m.data; uint16_t* ptr = (uint16_t*)m.data;
for(int i=0;i<20;i++){ for(int i=0;i<20;i++){
for(int j=0;j<20;j++){ for(int j=0;j<20;j++){
std::cout<<*(ptr+i*m.cols+j)<<", "; std::cout<<*(ptr+i*m.cols+j)<<", ";
@ -561,7 +576,7 @@ namespace hdrplus
// save merged Image value // save merged Image value
#ifndef HDRPLUS_NO_DETAILED_OUTPUT #ifndef HDRPLUS_NO_DETAILED_OUTPUT
writeCSV("merged.csv",burst_images.merged_bayer_image); writeCSV(DBG_OUTPUT_ROOT "merged.csv",burst_images.merged_bayer_image);
#endif #endif
this->refIdx = burst_images.reference_image_idx; this->refIdx = burst_images.reference_image_idx;
@ -570,20 +585,21 @@ namespace hdrplus
// show20_20(mergedB); // show20_20(mergedB);
#ifndef HDRPLUS_NO_DETAILED_OUTPUT #ifndef HDRPLUS_NO_DETAILED_OUTPUT
this->mergedBayer = loadFromCSV(DBG_OUTPUT_ROOT "merged.csv", CV_16UC1);
// this->mergedBayer = processMergedMat(mergedB,CV_16UC1);//loadFromCSV("merged.csv", CV_16UC1); // this->mergedBayer = processMergedMat(mergedB,CV_16UC1);//loadFromCSV("merged.csv", CV_16UC1);
// std::cout<<"processMerged:"<<std::endl; // std::cout<<"processMerged:"<<std::endl;
// show20_20(this->mergedBayer); // show20_20(this->mergedBayer);
this->mergedBayer = loadFromCSV("merged.csv", CV_16UC1); // this->mergedBayer = loadFromCSV(DBG_OUTPUT_ROOT "merged.csv", CV_16UC1);
// this->mergedBayer = processMergedMat(burst_images.merged_bayer_image, CV_16UC1);
#else #else
this->mergedBayer = processMergedMat(burst_images.merged_bayer_image, CV_16UC1); // this->mergedBayer = loadFromCSV(DBG_OUTPUT_ROOT "merged.csv", CV_16UC1);
this->mergedBayer = processMergedMat(burst_images.merged_bayer_image, CV_16UC1);
// std::cout<<"processMerged:"<<std::endl; // std::cout<<"processMerged:"<<std::endl;
#endif #endif
// std::cout<<"csv:"<<std::endl; // std::cout<<"csv:"<<std::endl;
// show20_20(this->mergedBayer); // show20_20(this->mergedBayer);
// load_rawPathList(burstPath); // load_rawPathList(burstPath);
// read in ref img // read in ref img
// bayer_image* ref = new bayer_image(rawPathList[refIdx]); // bayer_image* ref = new bayer_image(rawPathList[refIdx]);
bayer_image* ref = new bayer_image(burst_images.bayer_images[burst_images.reference_image_idx]); bayer_image* ref = new bayer_image(burst_images.bayer_images[burst_images.reference_image_idx]);
@ -598,7 +614,7 @@ namespace hdrplus
cv::Mat outputImg = convert16bit2_8bit_(processedRefImage.clone()); cv::Mat outputImg = convert16bit2_8bit_(processedRefImage.clone());
cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR); cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR);
// cv::imshow("test",processedImage); // cv::imshow("test",processedImage);
cv::imwrite("processedRef.jpg", outputImg); cv::imwrite(DBG_OUTPUT_ROOT "processedRef.jpg", outputImg);
// cv::waitKey(0); // cv::waitKey(0);
} }
#endif #endif
@ -610,7 +626,7 @@ namespace hdrplus
cv::Mat outputImg = gammasRGB(processedRefImage.clone(),true); cv::Mat outputImg = gammasRGB(processedRefImage.clone(),true);
outputImg = convert16bit2_8bit_(outputImg); outputImg = convert16bit2_8bit_(outputImg);
cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR); cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR);
cv::imwrite("processedRefGamma.jpg", outputImg); cv::imwrite(DBG_OUTPUT_ROOT "processedRefGamma.jpg", outputImg);
} }
#endif #endif
@ -627,7 +643,7 @@ namespace hdrplus
std::cout<<"writing Merged img ..."<<std::endl; std::cout<<"writing Merged img ..."<<std::endl;
cv::Mat outputImg = convert16bit2_8bit_(processedMerge.clone()); cv::Mat outputImg = convert16bit2_8bit_(processedMerge.clone());
cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR); cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR);
cv::imwrite("mergedImg.jpg", outputImg); cv::imwrite(DBG_OUTPUT_ROOT "mergedImg.jpg", outputImg);
} }
#endif #endif
@ -638,7 +654,7 @@ namespace hdrplus
cv::Mat outputImg = gammasRGB(processedMerge.clone(),true); cv::Mat outputImg = gammasRGB(processedMerge.clone(),true);
outputImg = convert16bit2_8bit_(outputImg); outputImg = convert16bit2_8bit_(outputImg);
cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR); cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR);
cv::imwrite("mergedImgGamma.jpg", outputImg); cv::imwrite(DBG_OUTPUT_ROOT "mergedImgGamma.jpg", outputImg);
} }
#endif #endif
@ -654,7 +670,7 @@ namespace hdrplus
if(params.flags["writeShortExposure"]){ if(params.flags["writeShortExposure"]){
std::cout<<"writing ShortExposure img ..."<<std::endl; std::cout<<"writing ShortExposure img ..."<<std::endl;
cv::Mat outputImg = convert16bit2_8bit_(shortExposure); cv::Mat outputImg = convert16bit2_8bit_(shortExposure);
cv::imwrite("shortg.jpg", outputImg); cv::imwrite(DBG_OUTPUT_ROOT "shortg.jpg", outputImg);
} }
#endif #endif
@ -662,7 +678,7 @@ namespace hdrplus
if(params.flags["writeLongExposure"]){ if(params.flags["writeLongExposure"]){
std::cout<<"writing LongExposure img ..."<<std::endl; std::cout<<"writing LongExposure img ..."<<std::endl;
cv::Mat outputImg = convert16bit2_8bit_(longExposure); cv::Mat outputImg = convert16bit2_8bit_(longExposure);
cv::imwrite("longg.jpg", outputImg); cv::imwrite(DBG_OUTPUT_ROOT "longg.jpg", outputImg);
} }
#endif #endif
@ -670,7 +686,7 @@ namespace hdrplus
if(params.flags["writeFusedExposure"]){ if(params.flags["writeFusedExposure"]){
std::cout<<"writing FusedExposure img ..."<<std::endl; std::cout<<"writing FusedExposure img ..."<<std::endl;
cv::Mat outputImg = convert16bit2_8bit_(fusedExposure); cv::Mat outputImg = convert16bit2_8bit_(fusedExposure);
cv::imwrite("fusedg.jpg", outputImg); cv::imwrite(DBG_OUTPUT_ROOT "fusedg.jpg", outputImg);
} }
#endif #endif
@ -679,7 +695,7 @@ namespace hdrplus
std::cout<<"writing LTMImage ..."<<std::endl; std::cout<<"writing LTMImage ..."<<std::endl;
cv::Mat outputImg = convert16bit2_8bit_(processedMerge.clone()); cv::Mat outputImg = convert16bit2_8bit_(processedMerge.clone());
cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR); cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR);
cv::imwrite("ltmGain.jpg", outputImg); cv::imwrite(DBG_OUTPUT_ROOT "ltmGain.jpg", outputImg);
} }
#endif #endif
@ -689,7 +705,7 @@ namespace hdrplus
cv::Mat outputImg = gammasRGB(processedMerge.clone(),true); cv::Mat outputImg = gammasRGB(processedMerge.clone(),true);
outputImg = convert16bit2_8bit_(outputImg); outputImg = convert16bit2_8bit_(outputImg);
cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR); cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR);
cv::imwrite("ltmGain_gamma.jpg", outputImg); cv::imwrite(DBG_OUTPUT_ROOT "ltmGain_gamma.jpg", outputImg);
} }
#endif #endif
} }
@ -710,7 +726,7 @@ namespace hdrplus
cv::Mat outputImg = convert16bit2_8bit_(processedMerge.clone()); cv::Mat outputImg = convert16bit2_8bit_(processedMerge.clone());
cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR); cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR);
cv::imwrite("GTM_gamma.jpg", outputImg); cv::imwrite(DBG_OUTPUT_ROOT "GTM_gamma.jpg", outputImg);
} }
#endif #endif
@ -723,7 +739,7 @@ namespace hdrplus
cv::Mat outputImg = convert16bit2_8bit_(processedImage.clone()); cv::Mat outputImg = convert16bit2_8bit_(processedImage.clone());
cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR); cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR);
cv::imwrite("FinalImage.jpg", outputImg); cv::imwrite(DBG_OUTPUT_ROOT "FinalImage.jpg", outputImg);
} }
#endif #endif
@ -745,15 +761,15 @@ namespace hdrplus
cv::Mat outputImg = convert16bit2_8bit_(processedRefImage.clone()); cv::Mat outputImg = convert16bit2_8bit_(processedRefImage.clone());
cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR); cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR);
cv::imwrite("FinalReference.jpg", outputImg); cv::imwrite(DBG_OUTPUT_ROOT "FinalReference.jpg", outputImg);
} }
#endif #endif
// End of finishing // End of finishing
} }
void finish::copy_mat_16U(cv::Mat& A, cv::Mat B){ void finish::copy_mat_16U(cv::Mat& A, cv::Mat B){
u_int16_t* ptr_A = (u_int16_t*)A.data; uint16_t* ptr_A = (uint16_t*)A.data;
u_int16_t* ptr_B = (u_int16_t*)B.data; uint16_t* ptr_B = (uint16_t*)B.data;
for(int r = 0; r < A.rows; r++) { for(int r = 0; r < A.rows; r++) {
for(int c = 0; c < A.cols; c++) { for(int c = 0; c < A.cols; c++) {
*(ptr_A+r*A.cols+c) = *(ptr_B+r*B.cols+c); *(ptr_A+r*A.cols+c) = *(ptr_B+r*B.cols+c);
@ -764,8 +780,8 @@ namespace hdrplus
void finish::copy_rawImg2libraw(std::shared_ptr<LibRaw>& libraw_ptr, cv::Mat B){ void finish::copy_rawImg2libraw(std::shared_ptr<LibRaw>& libraw_ptr, cv::Mat B){
u_int16_t* ptr_A = (u_int16_t*)libraw_ptr->imgdata.rawdata.raw_image; uint16_t* ptr_A = (uint16_t*)libraw_ptr->imgdata.rawdata.raw_image;
u_int16_t* ptr_B = (u_int16_t*)B.data; uint16_t* ptr_B = (uint16_t*)B.data;
for(int r = 0; r < B.rows; r++) { for(int r = 0; r < B.rows; r++) {
for(int c = 0; c < B.cols; c++) { for(int c = 0; c < B.cols; c++) {
*(ptr_A+r*B.cols+c) = *(ptr_B+r*B.cols+c); *(ptr_A+r*B.cols+c) = *(ptr_B+r*B.cols+c);

@ -10,6 +10,10 @@
#include "hdrplus/finish.h" #include "hdrplus/finish.h"
#include <fstream> #include <fstream>
#ifdef __ANDROID__
// #include <AndroidHelper.h>
#endif
namespace hdrplus namespace hdrplus
{ {
@ -19,6 +23,7 @@ void hdrplus_pipeline::run_pipeline( \
{ {
// Create burst of images // Create burst of images
burst burst_images( burst_path, reference_image_path ); burst burst_images( burst_path, reference_image_path );
std::vector<std::vector<std::vector<std::pair<int, int>>>> alignments; std::vector<std::vector<std::vector<std::pair<int, int>>>> alignments;
// Run align // Run align
@ -27,27 +32,107 @@ void hdrplus_pipeline::run_pipeline( \
// Run merging // Run merging
merge_module.process( burst_images, alignments ); merge_module.process( burst_images, alignments );
// Run finishing // Run finishing
cv::Mat finalImg; cv::Mat finalImg;
finish_module.process( burst_images, finalImg); finish_module.process( burst_images, finalImg);
} }
void hdrplus_pipeline::run_pipeline( \ bool hdrplus_pipeline::run_pipeline( \
const std::vector<std::string>& burst_paths, \ const std::vector<std::string>& burst_paths, \
int reference_image_index, cv::Mat& finalImg ) int reference_image_index, cv::Mat& finalImg )
{ {
// Create burst of images // Create burst of images
burst burst_images( burst_paths, reference_image_index ); burst burst_images( burst_paths, reference_image_index );
std::vector<std::vector<std::vector<std::pair<int, int>>>> alignments; std::vector<std::vector<std::vector<std::pair<int, int>>>> alignments;
#ifdef __ANDROID__
// ALOGI("Finish loading images");
#endif
// Run align
align_module.process( burst_images, alignments );
#ifdef __ANDROID__
// ALOGI("Finish align");
#endif
// Run merging
merge_module.process( burst_images, alignments );
#ifdef __ANDROID__
// ALOGI("Finish merging");
#endif
// Run finishing
finish_module.process( burst_images, finalImg);
#ifdef __ANDROID__
// ALOGI("Finish process");
#endif
return true;
}
bool hdrplus_pipeline::run_pipeline( \
const std::vector<std::vector<uint8_t> >& burst_contents, \
int reference_image_index, cv::Mat& finalImg )
{
// Create burst of images
burst burst_images( burst_contents, reference_image_index );
std::vector<std::vector<std::vector<std::pair<int, int>>>> alignments;
#ifdef __ANDROID__
// ALOGI("Finish loading images");
#endif
// Run align // Run align
align_module.process( burst_images, alignments ); align_module.process( burst_images, alignments );
#ifdef __ANDROID__
// ALOGI("Finish align");
#endif
// Run merging // Run merging
merge_module.process( burst_images, alignments ); merge_module.process( burst_images, alignments );
#ifdef __ANDROID__
// ALOGI("Finish merging");
#endif
// Run finishing // Run finishing
finish_module.process( burst_images, finalImg); finish_module.process( burst_images, finalImg);
#ifdef __ANDROID__
// ALOGI("Finish process");
#endif
return true;
} }
bool hdrplus_pipeline::run_pipeline( \
const std::vector<std::shared_ptr<MemFile> >& burst_files, \
int reference_image_index, cv::Mat& finalImg )
{
// Create burst of images
burst burst_images( burst_files, reference_image_index );
std::vector<std::vector<std::vector<std::pair<int, int>>>> alignments;
#ifdef __ANDROID__
// ALOGI("Finish loading images");
#endif
// Run align
align_module.process( burst_images, alignments );
#ifdef __ANDROID__
// ALOGI("Finish align");
#endif
// Run merging
merge_module.process( burst_images, alignments );
#ifdef __ANDROID__
// ALOGI("Finish merging");
#endif
// Run finishing
finish_module.process( burst_images, finalImg);
#ifdef __ANDROID__
// ALOGI("Finish process");
#endif
return true;
}
} // namespace hdrplus } // namespace hdrplus

@ -20,7 +20,9 @@ namespace hdrplus
// Get padded bayer image // Get padded bayer image
cv::Mat reference_image = burst_images.bayer_images_pad[burst_images.reference_image_idx]; cv::Mat reference_image = burst_images.bayer_images_pad[burst_images.reference_image_idx];
cv::imwrite("ref.jpg", reference_image); #ifndef NDEBUG
// cv::imwrite("ref.jpg", reference_image);
#endif
// Get raw channels // Get raw channels
std::vector<cv::Mat> channels(4); std::vector<cv::Mat> channels(4);
@ -98,26 +100,25 @@ namespace hdrplus
cv::Range horizontal = cv::Range(padding[2], reference_image.cols - padding[3]); cv::Range horizontal = cv::Range(padding[2], reference_image.cols - padding[3]);
cv::Range vertical = cv::Range(padding[0], reference_image.rows - padding[1]); cv::Range vertical = cv::Range(padding[0], reference_image.rows - padding[1]);
burst_images.merged_bayer_image = merged(vertical, horizontal); burst_images.merged_bayer_image = merged(vertical, horizontal);
cv::imwrite("merged.jpg", burst_images.merged_bayer_image); // cv::imwrite("merged.jpg", burst_images.merged_bayer_image);
} }
std::vector<cv::Mat> merge::getReferenceTiles(cv::Mat reference_image) { void merge::getReferenceTiles(cv::Mat reference_image, std::vector<cv::Mat>& reference_tiles) {
std::vector<cv::Mat> reference_tiles;
for (int y = 0; y < reference_image.rows - offset; y += offset) { for (int y = 0; y < reference_image.rows - offset; y += offset) {
for (int x = 0; x < reference_image.cols - offset; x += offset) { for (int x = 0; x < reference_image.cols - offset; x += offset) {
cv::Mat tile = reference_image(cv::Rect(x, y, TILE_SIZE, TILE_SIZE)); cv::Mat tile = reference_image(cv::Rect(x, y, TILE_SIZE, TILE_SIZE));
reference_tiles.push_back(tile); reference_tiles.push_back(tile);
} }
} }
return reference_tiles;
} }
cv::Mat merge::mergeTiles(std::vector<cv::Mat> tiles, int num_rows, int num_cols) { cv::Mat merge::mergeTiles(std::vector<cv::Mat> tiles, int num_rows, int num_cols) {
// 1. get all four subsets: original (evenly split), horizontal overlapped, // 1. get all four subsets: original (evenly split), horizontal overlapped,
// vertical overlapped, 2D overlapped // vertical overlapped, 2D overlapped
std::vector<std::vector<cv::Mat>> tiles_original; std::vector<std::vector<cv::Mat>> tiles_original;
std::vector<cv::Mat> row;
for (int y = 0; y < num_rows / offset - 1; y += 2) { for (int y = 0; y < num_rows / offset - 1; y += 2) {
std::vector<cv::Mat> row; row.clear();
for (int x = 0; x < num_cols / offset - 1; x += 2) { for (int x = 0; x < num_cols / offset - 1; x += 2) {
row.push_back(tiles[y * (num_cols / offset - 1) + x]); row.push_back(tiles[y * (num_cols / offset - 1) + x]);
} }
@ -125,8 +126,9 @@ namespace hdrplus
} }
std::vector<std::vector<cv::Mat>> tiles_horizontal; std::vector<std::vector<cv::Mat>> tiles_horizontal;
// std::vector<cv::Mat> row;
for (int y = 0; y < num_rows / offset - 1; y += 2) { for (int y = 0; y < num_rows / offset - 1; y += 2) {
std::vector<cv::Mat> row; row.clear();
for (int x = 1; x < num_cols / offset - 1; x += 2) { for (int x = 1; x < num_cols / offset - 1; x += 2) {
row.push_back(tiles[y * (num_cols / offset - 1) + x]); row.push_back(tiles[y * (num_cols / offset - 1) + x]);
} }
@ -134,8 +136,9 @@ namespace hdrplus
} }
std::vector<std::vector<cv::Mat>> tiles_vertical; std::vector<std::vector<cv::Mat>> tiles_vertical;
// std::vector<cv::Mat> row;
for (int y = 1; y < num_rows / offset - 1; y += 2) { for (int y = 1; y < num_rows / offset - 1; y += 2) {
std::vector<cv::Mat> row; row.clear();
for (int x = 0; x < num_cols / offset - 1; x += 2) { for (int x = 0; x < num_cols / offset - 1; x += 2) {
row.push_back(tiles[y * (num_cols / offset - 1) + x]); row.push_back(tiles[y * (num_cols / offset - 1) + x]);
} }
@ -143,8 +146,9 @@ namespace hdrplus
} }
std::vector<std::vector<cv::Mat>> tiles_2d; std::vector<std::vector<cv::Mat>> tiles_2d;
// std::vector<cv::Mat> row;
for (int y = 1; y < num_rows / offset - 1; y += 2) { for (int y = 1; y < num_rows / offset - 1; y += 2) {
std::vector<cv::Mat> row; row.clear();
for (int x = 1; x < num_cols / offset - 1; x += 2) { for (int x = 1; x < num_cols / offset - 1; x += 2) {
row.push_back(tiles[y * (num_cols / offset - 1) + x]); row.push_back(tiles[y * (num_cols / offset - 1) + x]);
} }
@ -172,7 +176,8 @@ namespace hdrplus
float lambda_shot, \ float lambda_shot, \
float lambda_read) { float lambda_read) {
// Get tiles of the reference image // Get tiles of the reference image
std::vector<cv::Mat> reference_tiles = getReferenceTiles(channel_image); std::vector<cv::Mat> reference_tiles;
getReferenceTiles(channel_image, reference_tiles);
// Get noise variance (sigma**2 = lambda_shot * tileRMS + lambda_read) // Get noise variance (sigma**2 = lambda_shot * tileRMS + lambda_read)
std::vector<float> noise_variance = getNoiseVariance(reference_tiles, lambda_shot, lambda_read); std::vector<float> noise_variance = getNoiseVariance(reference_tiles, lambda_shot, lambda_read);
@ -190,9 +195,10 @@ namespace hdrplus
std::vector<std::vector<cv::Mat>> alt_tiles_list(reference_tiles.size()); std::vector<std::vector<cv::Mat>> alt_tiles_list(reference_tiles.size());
int num_tiles_row = alternate_channel_i_list[0].rows / offset - 1; int num_tiles_row = alternate_channel_i_list[0].rows / offset - 1;
int num_tiles_col = alternate_channel_i_list[0].cols / offset - 1; int num_tiles_col = alternate_channel_i_list[0].cols / offset - 1;
std::vector<cv::Mat> alt_tiles;
for (int y = 0; y < num_tiles_row; ++y) { for (int y = 0; y < num_tiles_row; ++y) {
for (int x = 0; x < num_tiles_col; ++x) { for (int x = 0; x < num_tiles_col; ++x) {
std::vector<cv::Mat> alt_tiles; alt_tiles.clear();
// Get reference tile location // Get reference tile location
int top_left_y = y * offset; int top_left_y = y * offset;
int top_left_x = x * offset; int top_left_x = x * offset;
@ -214,10 +220,19 @@ namespace hdrplus
} }
// 4.2 Temporal Denoising // 4.2 Temporal Denoising
reference_tiles_DFT = temporal_denoise(reference_tiles_DFT, alt_tiles_list, noise_variance, TEMPORAL_FACTOR);
std::vector<cv::Mat> reference_tiles_DFTNew;
temporal_denoise(reference_tiles_DFT, alt_tiles_list, noise_variance, TEMPORAL_FACTOR, reference_tiles_DFTNew);
reference_tiles_DFT.swap(reference_tiles_DFTNew);
// 4.3 Spatial Denoising // 4.3 Spatial Denoising
reference_tiles_DFT = spatial_denoise(reference_tiles_DFT, alternate_channel_i_list.size(), noise_variance, SPATIAL_FACTOR); reference_tiles_DFTNew.clear();
spatial_denoise(reference_tiles_DFT, alternate_channel_i_list.size(), noise_variance, SPATIAL_FACTOR, reference_tiles_DFTNew);
reference_tiles_DFT.swap(reference_tiles_DFTNew);
{
std::vector<cv::Mat> empty;
reference_tiles_DFTNew.swap(empty);
}
//now reference tiles are temporally and spatially denoised //now reference tiles are temporally and spatially denoised
// Apply IFFT on reference tiles (frequency to spatial) // Apply IFFT on reference tiles (frequency to spatial)
@ -228,7 +243,13 @@ namespace hdrplus
cv::dft(dft_tile, denoised_tile, cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT); cv::dft(dft_tile, denoised_tile, cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT);
denoised_tiles.push_back(denoised_tile); denoised_tiles.push_back(denoised_tile);
} }
reference_tiles = denoised_tiles;
{
reference_tiles.swap(denoised_tiles);
std::vector<cv::Mat> empty;
denoised_tiles.swap(empty);
}
// 4.4 Cosine Window Merging // 4.4 Cosine Window Merging
// Process tiles through 2D cosine window // Process tiles through 2D cosine window
@ -241,7 +262,8 @@ namespace hdrplus
return mergeTiles(windowed_tiles, channel_image.rows, channel_image.cols); return mergeTiles(windowed_tiles, channel_image.rows, channel_image.cols);
} }
std::vector<cv::Mat> merge::temporal_denoise(std::vector<cv::Mat> tiles, std::vector<std::vector<cv::Mat>> alt_tiles, std::vector<float> noise_variance, float temporal_factor) { void merge::temporal_denoise(std::vector<cv::Mat> tiles, std::vector<std::vector<cv::Mat>> alt_tiles, std::vector<float> noise_variance, float temporal_factor, std::vector<cv::Mat>& denoised)
{
// goal: temporially denoise using the weiner filter // goal: temporially denoise using the weiner filter
// input: // input:
// 1. array of 2D dft tiles of the reference image // 1. array of 2D dft tiles of the reference image
@ -254,7 +276,6 @@ namespace hdrplus
double temporal_noise_scaling = (TILE_SIZE * TILE_SIZE * (2.0 / 16)) * TEMPORAL_FACTOR; double temporal_noise_scaling = (TILE_SIZE * TILE_SIZE * (2.0 / 16)) * TEMPORAL_FACTOR;
// loop across tiles // loop across tiles
std::vector<cv::Mat> denoised;
for (int i = 0; i < tiles.size(); ++i) { for (int i = 0; i < tiles.size(); ++i) {
// sum of pairwise denoising // sum of pairwise denoising
cv::Mat tile_sum = tiles[i].clone(); cv::Mat tile_sum = tiles[i].clone();
@ -290,10 +311,10 @@ namespace hdrplus
denoised.push_back(tile_sum); denoised.push_back(tile_sum);
} }
return denoised;
} }
std::vector<cv::Mat> merge::spatial_denoise(std::vector<cv::Mat> tiles, int num_alts, std::vector<float> noise_variance, float spatial_factor) { void merge::spatial_denoise(std::vector<cv::Mat> tiles, int num_alts, std::vector<float> noise_variance, float spatial_factor, std::vector<cv::Mat>& denoised) {
double spatial_noise_scaling = (TILE_SIZE * TILE_SIZE * (1.0 / 16)) * spatial_factor; double spatial_noise_scaling = (TILE_SIZE * TILE_SIZE * (1.0 / 16)) * spatial_factor;
@ -308,7 +329,6 @@ namespace hdrplus
cv::sqrt(row_distances.mul(row_distances) + col_distances.mul(col_distances), distances); cv::sqrt(row_distances.mul(row_distances) + col_distances.mul(col_distances), distances);
ifftshift(distances); ifftshift(distances);
std::vector<cv::Mat> denoised;
// Loop through all tiles // Loop through all tiles
for (int i = 0; i < tiles.size(); ++i) { for (int i = 0; i < tiles.size(); ++i) {
cv::Mat tile = tiles[i]; cv::Mat tile = tiles[i];
@ -326,7 +346,6 @@ namespace hdrplus
cv::merge(std::vector<cv::Mat>{scale, scale}, scale); cv::merge(std::vector<cv::Mat>{scale, scale}, scale);
denoised.push_back(tile.mul(scale)); denoised.push_back(tile.mul(scale));
} }
return denoised;
} }

@ -0,0 +1,20 @@
// TestHDRplus.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
int main()
{
std::cout << "Hello World!\n";
}
// Run program: Ctrl + F5 or Debug > Start Without Debugging menu
// Debug program: F5 or Debug > Start Debugging menu
// Tips for Getting Started:
// 1. Use the Solution Explorer window to add/manage files
// 2. Use the Team Explorer window to connect to source control
// 3. Use the Output window to see build output and other messages
// 4. Use the Error List window to view errors
// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.34829.251
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestHDRplus", "TestHDRplus.vcxproj", "{98A6E8C6-16F7-480A-AD0C-DCFE94FD9BC8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{98A6E8C6-16F7-480A-AD0C-DCFE94FD9BC8}.Debug|x64.ActiveCfg = Debug|x64
{98A6E8C6-16F7-480A-AD0C-DCFE94FD9BC8}.Debug|x64.Build.0 = Debug|x64
{98A6E8C6-16F7-480A-AD0C-DCFE94FD9BC8}.Debug|x86.ActiveCfg = Debug|Win32
{98A6E8C6-16F7-480A-AD0C-DCFE94FD9BC8}.Debug|x86.Build.0 = Debug|Win32
{98A6E8C6-16F7-480A-AD0C-DCFE94FD9BC8}.Release|x64.ActiveCfg = Release|x64
{98A6E8C6-16F7-480A-AD0C-DCFE94FD9BC8}.Release|x64.Build.0 = Release|x64
{98A6E8C6-16F7-480A-AD0C-DCFE94FD9BC8}.Release|x86.ActiveCfg = Release|Win32
{98A6E8C6-16F7-480A-AD0C-DCFE94FD9BC8}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {ECEDF19B-B6B3-4AC2-841C-B64ECB21A38B}
EndGlobalSection
EndGlobal

@ -0,0 +1,188 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\bin\hdrplus.cpp" />
<ClCompile Include="..\src\align.cpp" />
<ClCompile Include="..\src\bayer_image.cpp" />
<ClCompile Include="..\src\burst.cpp" />
<ClCompile Include="..\src\finish.cpp" />
<ClCompile Include="..\src\hdrplus_pipeline.cpp" />
<ClCompile Include="..\src\merge.cpp" />
<ClCompile Include="..\src\params.cpp" />
<ClCompile Include="pcb.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\hdrplus\align.h" />
<ClInclude Include="..\include\hdrplus\AndroidHelper.h" />
<ClInclude Include="..\include\hdrplus\bayer_image.h" />
<ClInclude Include="..\include\hdrplus\burst.h" />
<ClInclude Include="..\include\hdrplus\finish.h" />
<ClInclude Include="..\include\hdrplus\hdrplus_pipeline.h" />
<ClInclude Include="..\include\hdrplus\merge.h" />
<ClInclude Include="..\include\hdrplus\params.h" />
<ClInclude Include="..\include\hdrplus\utility.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{98A6E8C6-16F7-480A-AD0C-DCFE94FD9BC8}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>TestHDRplus</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>D:\Workspace\Github\imx291\opencv-4.10.0\build\install\include;D:\Workspace\deps\include;$(ProjectDir)\..\include;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
<LibraryPath>D:\Workspace\Github\imx291\opencv-4.10.0\build\install\x64\vc15\staticlib;D:\Workspace\deps\x64\dbg;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>D:\Workspace\Github\imx291\opencv-4.10.0\build\install\include;D:\Workspace\deps\include;$(ProjectDir)\..\include;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
<LibraryPath>D:\Workspace\Github\imx291\opencv-4.10.0\build\install\x64\vc15\staticlib;D:\Workspace\deps\x64\rel;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>HDRPLUS_NO_DETAILED_OUTPUT;LIBRAW_BUILDLIB;EXV_HAVE_ICONV;exiv2lib_STATIC;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalOptions>/FORCE:MULTIPLE %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>Psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>LIBRAW_BUILDLIB;EXV_HAVE_ICONV;exiv2lib_STATIC;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/FORCE:MULTIPLE %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\bin\hdrplus.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\align.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\bayer_image.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\burst.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\finish.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\hdrplus_pipeline.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\merge.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\params.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pcb.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\hdrplus\align.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\hdrplus\AndroidHelper.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\hdrplus\bayer_image.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\hdrplus\burst.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\hdrplus\finish.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\hdrplus\hdrplus_pipeline.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\hdrplus\merge.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\hdrplus\params.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\hdrplus\utility.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerCommandArguments>1.dng 2.dng 3.dng 4.dng 5.dng 6.dng 7.dng 8.dng</LocalDebuggerCommandArguments>
<LocalDebuggerWorkingDirectory>D:\Workspace\Github\imx291\dngs\291</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommandArguments>out.jpg 1.dng 2.dng 3.dng 4.dng 5.dng 6.dng 7.dng 8.dng</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerWorkingDirectory>D:\Workspace\Github\imx291\dngs\291</LocalDebuggerWorkingDirectory>
</PropertyGroup>
</Project>

@ -0,0 +1,88 @@
// pch.cpp: source file corresponding to the pre-compiled header
// #include "pch.h"
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
#ifdef _DEBUG
#pragma comment(lib, "opencv_core4100d.lib")
#pragma comment(lib, "opencv_highgui4100d.lib")
#pragma comment(lib, "opencv_imgproc4100d.lib")
#pragma comment(lib, "opencv_photo4100d.lib")
#pragma comment(lib, "opencv_imgcodecs4100d.lib")
#pragma comment(lib, "opencv_dnn4100d.lib")
#pragma comment(lib, "opencv_xphoto4100d.lib")
#pragma comment(lib, "opencv_mcc4100d.lib")
#pragma comment(lib, "ittnotifyd.lib")
#pragma comment(lib, "libclapackd.lib")
#pragma comment(lib, "zlibd.lib")
#pragma comment(lib, "libwebp.lib")
#pragma comment(lib, "tiffd.lib")
#pragma comment(lib, "jpeg.lib")
#pragma comment(lib, "libpng16d.lib")
#pragma comment(lib, "libsharpyuv.lib")
#pragma comment(lib, "lzma.lib")
#pragma comment(lib, "libopenjp2d.lib")
#pragma comment(lib, "ippicvmt.lib")
#pragma comment(lib, "ippiwd.lib")
#pragma comment(lib, "IlmImfd.lib")
// #pragma comment(lib, "ncnnd.lib")
#pragma comment(lib, "freetyped.lib")
#pragma comment(lib, "bz2d.lib")
#pragma comment(lib, "brotlidec.lib")
#pragma comment(lib, "brotlicommon.lib")
#pragma comment(lib, "libprotobufd.lib")
#pragma comment(lib, "libjpeg-turbo.lib")
#pragma comment(lib, "exiv2.lib")
#pragma comment(lib, "expatd.lib")
#pragma comment(lib, "libraw.lib")
#pragma comment(lib, "libiconv.lib")
#pragma comment(lib, "libcharset.lib")
#else
#pragma comment(lib, "opencv_core4100.lib")
#pragma comment(lib, "opencv_highgui4100.lib")
#pragma comment(lib, "opencv_imgproc4100.lib")
#pragma comment(lib, "opencv_photo4100.lib")
#pragma comment(lib, "opencv_imgcodecs4100.lib")
#pragma comment(lib, "opencv_dnn4100.lib")
#pragma comment(lib, "opencv_xphoto4100.lib")
#pragma comment(lib, "opencv_mcc4100.lib")
#pragma comment(lib, "ittnotify.lib")
// #pragma comment(lib, "libclapack.lib")
#pragma comment(lib, "zlib.lib")
#pragma comment(lib, "libwebp.lib")
#pragma comment(lib, "libtiff.lib")
#pragma comment(lib, "libopenjp2.lib")
#pragma comment(lib, "libjpeg-turbo.lib")
#pragma comment(lib, "libpng.lib")
// #pragma comment(lib, "libsharpyuv.lib")
// #pragma comment(lib, "lzma.lib")
#pragma comment(lib, "libopenjp2d.lib")
// #pragma comment(lib, "ippicvmt.lib")
// #pragma comment(lib, "ippiwd.lib")
#pragma comment(lib, "IlmImf.lib")
// #pragma comment(lib, "freetype.lib")
// #pragma comment(lib, "bz2.lib")
// #pragma comment(lib, "brotlidec.lib")
// #pragma comment(lib, "brotlicommon.lib")
#pragma comment(lib, "libprotobuf.lib")
#pragma comment(lib, "exiv2.lib")
#pragma comment(lib, "expat.lib")
#pragma comment(lib, "libraw.lib")
#pragma comment(lib, "libiconv.lib")
#pragma comment(lib, "libcharset.lib")
#endif
Loading…
Cancel
Save