main
Matthew 6 months ago
parent 2767bab6ea
commit 38e4ef464c

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

@ -13,15 +13,15 @@
namespace hdrplus namespace hdrplus
{ {
uint16_t uGammaCompress_1pix(float x, float threshold,float gainMin,float gainMax,float exponent); uint16_t uGammaCompress_1pix(float x, float threshold, float gainMin, float gainMax, float exponent);
uint16_t uGammaDecompress_1pix(float x, float threshold,float gainMin,float gainMax,float exponent); uint16_t uGammaDecompress_1pix(float x, float threshold, float gainMin, float gainMax, float exponent);
cv::Mat uGammaCompress_(cv::Mat m,float threshold,float gainMin,float gainMax,float exponent); cv::Mat uGammaCompress_(cv::Mat m, float threshold, float gainMin, float gainMax, float exponent);
cv::Mat uGammaDecompress_(cv::Mat m,float threshold,float gainMin,float gainMax,float exponent); cv::Mat uGammaDecompress_(cv::Mat m, float threshold, float gainMin, float gainMax, float exponent);
cv::Mat gammasRGB(cv::Mat img, bool mode); cv::Mat gammasRGB(cv::Mat img, bool mode);
class finish class finish
{ {
public: public:
cv::Mat mergedBayer; // merged image from Merge Module cv::Mat mergedBayer; // merged image from Merge Module
std::string burstPath; // path to burst images std::string burstPath; // path to burst images
@ -38,28 +38,28 @@ class finish
refBayer = NULL; 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; refBayer = NULL;
this->refIdx = refIdx; this->refIdx = refIdx;
this->burstPath = burstPath; this->burstPath = burstPath;
this->mergedBayer = mergedBayer; this->mergedBayer = mergedBayer;
} }
// for local testing only // for local testing only
finish(std::string burstPath, std::string mergedBayerPath,int refIdx){ finish(std::string burstPath, std::string mergedBayerPath, int refIdx) {
this->refIdx = refIdx; this->refIdx = refIdx;
this->burstPath = burstPath; this->burstPath = burstPath;
this->mergedBayer = loadFromCSV(mergedBayerPath, CV_16UC1);// this->mergedBayer = loadFromCSV(mergedBayerPath, CV_16UC1);//
load_rawPathList(burstPath); load_rawPathList(burstPath);
refBayer= new bayer_image(this->rawPathList[refIdx]); refBayer = new bayer_image(this->rawPathList[refIdx]);
this->rawReference = refBayer->raw_image;//;grayscale_image this->rawReference = refBayer->raw_image;//;grayscale_image
// initialize parameters in libraw_processor_finish // initialize parameters in libraw_processor_finish
setLibRawParams(); setLibRawParams();
showParams(); showParams();
std::cout<<"Finish init() finished!"<<std::endl; std::cout << "Finish init() finished!" << std::endl;
} }
@ -103,42 +103,42 @@ class finish
// cv::transpose(tmp, tmp); // cv::transpose(tmp, tmp);
uint16_t* ptr = (uint16_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;
} }
} }
tmp = tmp.reshape(ch); tmp = tmp.reshape(ch);
tmp.convertTo(tmp, CV_8UC1); tmp.convertTo(tmp, CV_8UC1);
cv::imshow("test",tmp); cv::imshow("test", tmp);
cv::imwrite("test2.jpg", tmp); cv::imwrite("test2.jpg", tmp);
cv::waitKey(0); cv::waitKey(0);
std::cout<< this->mergedBayer.size()<<std::endl; std::cout << this->mergedBayer.size() << std::endl;
} }
void showMat(cv::Mat img){ void showMat(cv::Mat img) {
std::cout<<"size="<<img.size()<<std::endl; std::cout << "size=" << img.size() << std::endl;
std::cout<<"type="<<img.type()<<std::endl; std::cout << "type=" << img.type() << std::endl;
} }
void showParams() void showParams()
{ {
std::cout<<"Parameters:"<<std::endl; std::cout << "Parameters:" << std::endl;
std::cout<<"tuning_ltmGain = "<<this->params.tuning.ltmGain<<std::endl; std::cout << "tuning_ltmGain = " << this->params.tuning.ltmGain << std::endl;
std::cout<<"tuning_gtmContrast = "<<this->params.tuning.gtmContrast<<std::endl; std::cout << "tuning_gtmContrast = " << this->params.tuning.gtmContrast << std::endl;
for(auto key_val:this->params.flags){ for (auto key_val : this->params.flags) {
std::cout<<key_val.first<<","<<key_val.second<<std::endl; std::cout << key_val.first << "," << key_val.second << std::endl;
} }
std::cout<<"demosaic_algorithm = "<<refBayer->libraw_processor->imgdata.params.user_qual<<std::endl; std::cout << "demosaic_algorithm = " << refBayer->libraw_processor->imgdata.params.user_qual << std::endl;
std::cout<<"half_size = "<<refBayer->libraw_processor->imgdata.params.half_size<<std::endl; std::cout << "half_size = " << refBayer->libraw_processor->imgdata.params.half_size << std::endl;
std::cout<<"use_camera_wb = "<<refBayer->libraw_processor->imgdata.params.use_camera_wb<<std::endl; std::cout << "use_camera_wb = " << refBayer->libraw_processor->imgdata.params.use_camera_wb << std::endl;
std::cout<<"use_auto_wb = "<<refBayer->libraw_processor->imgdata.params.use_auto_wb<<std::endl; std::cout << "use_auto_wb = " << refBayer->libraw_processor->imgdata.params.use_auto_wb << std::endl;
std::cout<<"no_auto_bright = "<<refBayer->libraw_processor->imgdata.params.no_auto_bright<<std::endl; std::cout << "no_auto_bright = " << refBayer->libraw_processor->imgdata.params.no_auto_bright << std::endl;
std::cout<<"output_color = "<<refBayer->libraw_processor->imgdata.params.output_color <<std::endl; std::cout << "output_color = " << refBayer->libraw_processor->imgdata.params.output_color << std::endl;
std::cout<<"gamma[0] = "<<refBayer->libraw_processor->imgdata.params.gamm[0]<<std::endl; std::cout << "gamma[0] = " << refBayer->libraw_processor->imgdata.params.gamm[0] << std::endl;
std::cout<<"gamma[1] = "<<refBayer->libraw_processor->imgdata.params.gamm[1]<<std::endl; std::cout << "gamma[1] = " << refBayer->libraw_processor->imgdata.params.gamm[1] << std::endl;
std::cout<<"output_bps = "<<refBayer->libraw_processor->imgdata.params.output_bps<<std::endl; std::cout << "output_bps = " << refBayer->libraw_processor->imgdata.params.output_bps << std::endl;
// std::cout<<"demosaic_algorithm = "<<libraw_processor_finish.imgdata.params.user_qual<<std::endl; // std::cout<<"demosaic_algorithm = "<<libraw_processor_finish.imgdata.params.user_qual<<std::endl;
// std::cout<<"half_size = "<<libraw_processor_finish.imgdata.params.half_size<<std::endl; // std::cout<<"half_size = "<<libraw_processor_finish.imgdata.params.half_size<<std::endl;
@ -150,15 +150,15 @@ class finish
// std::cout<<"gamma[1] = "<<libraw_processor_finish.imgdata.params.gamm[1]<<std::endl; // std::cout<<"gamma[1] = "<<libraw_processor_finish.imgdata.params.gamm[1]<<std::endl;
// std::cout<<"output_bps = "<<libraw_processor_finish.imgdata.params.output_bps<<std::endl; // std::cout<<"output_bps = "<<libraw_processor_finish.imgdata.params.output_bps<<std::endl;
std::cout<<"===================="<<std::endl; std::cout << "====================" << std::endl;
} }
void showRawPathList(){ void showRawPathList() {
std::cout<<"RawPathList:"<<std::endl; std::cout << "RawPathList:" << std::endl;
for(auto pth:this->rawPathList){ for (auto pth : this->rawPathList) {
std::cout<<pth<<std::endl; std::cout << pth << std::endl;
} }
std::cout<<"===================="<<std::endl; std::cout << "====================" << std::endl;
} }
@ -168,7 +168,7 @@ class finish
cv::Mat loadFromCSV(const std::string& path, int opencv_type) cv::Mat loadFromCSV(const std::string& path, int opencv_type)
{ {
cv::Mat m; cv::Mat m;
std::ifstream csvFile (path); std::ifstream csvFile(path);
std::string line; std::string line;
@ -197,14 +197,17 @@ class finish
return m; return m;
} }
void load_rawPathList(std::string burstPath){ void load_rawPathList(std::string burstPath)
{
DIR *pDir; // pointer to root DIR *pDir; // pointer to root
struct dirent *ptr; struct dirent *ptr;
if (!(pDir = opendir(burstPath.c_str()))) { if (!(pDir = opendir(burstPath.c_str())))
std::cout<<"root dir not found!"<<std::endl; {
std::cout << "root dir not found!" << std::endl;
return; return;
} }
while ((ptr = readdir(pDir)) != nullptr) { while ((ptr = readdir(pDir)) != nullptr)
{
// ptr will move to the next file automatically // ptr will move to the next file automatically
std::string sub_file = burstPath + "/" + ptr->d_name; // current filepath that ptr points to std::string sub_file = burstPath + "/" + ptr->d_name; // current filepath that ptr points to
if (ptr->d_type != 8 && ptr->d_type != 4) { // not normal file or dir if (ptr->d_type != 8 && ptr->d_type != 4) { // not normal file or dir
@ -223,7 +226,7 @@ class finish
closedir(pDir); closedir(pDir);
} }
void setLibRawParams(){ void setLibRawParams() {
refBayer->libraw_processor->imgdata.params.user_qual = params.rawpyArgs.demosaic_algorithm; refBayer->libraw_processor->imgdata.params.user_qual = params.rawpyArgs.demosaic_algorithm;
refBayer->libraw_processor->imgdata.params.half_size = params.rawpyArgs.half_size; refBayer->libraw_processor->imgdata.params.half_size = params.rawpyArgs.half_size;
refBayer->libraw_processor->imgdata.params.use_camera_wb = params.rawpyArgs.use_camera_wb; refBayer->libraw_processor->imgdata.params.use_camera_wb = params.rawpyArgs.use_camera_wb;
@ -246,6 +249,6 @@ class finish
} }
}; };
} // namespace hdrplus } // namespace hdrplus

@ -8,7 +8,7 @@
namespace hdrplus namespace hdrplus
{ {
class RawpyArgs{ class RawpyArgs {
public: public:
int demosaic_algorithm = 3;// 3 - AHD interpolation <->int user_qual int demosaic_algorithm = 3;// 3 - AHD interpolation <->int user_qual
bool half_size = false; bool half_size = false;
@ -16,36 +16,36 @@ class RawpyArgs{
bool use_auto_wb = false; bool use_auto_wb = false;
bool no_auto_bright = true; bool no_auto_bright = true;
int output_color = LIBRAW_COLORSPACE_sRGB; int output_color = LIBRAW_COLORSPACE_sRGB;
int gamma[2] = {1,1}; //# gamma correction not applied by rawpy (not quite understand) int gamma[2] = { 1,1 }; //# gamma correction not applied by rawpy (not quite understand)
int output_bps = 16; int output_bps = 16;
}; };
class Options{ class Options {
public: public:
std::string input = ""; std::string input = "";
std::string output = ""; std::string output = "";
std::string mode = "full"; //'full' 'align' 'merge' 'finish' std::string mode = "full"; //'full' 'align' 'merge' 'finish'
int reference = 0; int reference = 0;
float temporalfactor=75.0; float temporalfactor = 75.0;
float spatialfactor = 0.1; float spatialfactor = 0.1;
int ltmGain=-1; int ltmGain = -1;
double gtmContrast=0.075; double gtmContrast = 0.075;
int verbose=2; // (0, 1, 2, 3, 4, 5) int verbose = 2; // (0, 1, 2, 3, 4, 5)
}; };
class Tuning{ class Tuning {
public: public:
std::string ltmGain = "auto"; std::string ltmGain = "auto";
double gtmContrast = 0.075; double gtmContrast = 0.075;
std::vector<float> sharpenAmount{1,0.5,0.5}; std::vector<float> sharpenAmount{ 1,0.5,0.5 };
std::vector<float> sharpenSigma{1,2,4}; std::vector<float> sharpenSigma{ 1,2,4 };
std::vector<float> sharpenThreshold{0.02,0.04,0.06}; std::vector<float> sharpenThreshold{ 0.02,0.04,0.06 };
}; };
class Parameters{ class Parameters {
public: public:
std::unordered_map<std::string,bool> flags; std::unordered_map<std::string, bool> flags;
RawpyArgs rawpyArgs; RawpyArgs rawpyArgs;
Options options; Options options;
@ -53,17 +53,17 @@ class Parameters{
Parameters() Parameters()
{ {
const char* keys[] = {"writeReferenceImage", "writeGammaReference", "writeMergedImage", "writeGammaMerged", const char* keys[] = { "writeReferenceImage", "writeGammaReference", "writeMergedImage", "writeGammaMerged",
"writeShortExposure", "writeLongExposure", "writeFusedExposure", "writeLTMImage", "writeShortExposure", "writeLongExposure", "writeFusedExposure", "writeLTMImage",
"writeLTMGamma", "writeGTMImage", "writeReferenceFinal", "writeFinalImage"}; "writeLTMGamma", "writeGTMImage", "writeReferenceFinal", "writeFinalImage" };
for (int idx = 0; idx < sizeof(keys) / sizeof(const char*); idx++) { for (int idx = 0; idx < sizeof(keys) / sizeof(const char*); idx++) {
flags[keys[idx]] = true; flags[keys[idx]] = true;
} }
} }
}; };
cv::Mat postprocess(std::shared_ptr<LibRaw>& libraw_ptr, RawpyArgs rawpyArgs); cv::Mat postprocess(std::shared_ptr<LibRaw>& libraw_ptr, RawpyArgs rawpyArgs);
void setParams(std::shared_ptr<LibRaw>& libraw_ptr, RawpyArgs rawpyArgs); void setParams(std::shared_ptr<LibRaw>& libraw_ptr, RawpyArgs rawpyArgs);
} // namespace hdrplus } // namespace hdrplus

File diff suppressed because it is too large Load Diff

@ -12,35 +12,35 @@
namespace hdrplus namespace hdrplus
{ {
bayer_image::bayer_image( const std::string& bayer_image_path ) bayer_image::bayer_image(const std::string& bayer_image_path)
{ {
libraw_processor = std::make_shared<LibRaw>(); libraw_processor = std::make_shared<LibRaw>();
// Open RAW image file // Open RAW image file
int return_code; int return_code;
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__ #ifdef __ANDROID__
return; return;
#else #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 #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__ #ifdef __ANDROID__
return; return;
#else #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 #endif
} }
// Get image basic info // Get image basic info
width = int( libraw_processor->imgdata.rawdata.sizes.raw_width ); width = int(libraw_processor->imgdata.rawdata.sizes.raw_width);
height = int( libraw_processor->imgdata.rawdata.sizes.raw_height ); height = int(libraw_processor->imgdata.rawdata.sizes.raw_height);
// Read exif tags // Read exif tags
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(bayer_image_path); Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(bayer_image_path);
@ -54,7 +54,7 @@ bayer_image::bayer_image( const std::string& bayer_image_path )
} }
white_level = exifData["Exif.Image.WhiteLevel"].toLong(); white_level = exifData["Exif.Image.WhiteLevel"].toLong();
black_level_per_channel.resize( 4 ); black_level_per_channel.resize(4);
black_level_per_channel.at(0) = exifData["Exif.Image.BlackLevel"].toLong(0); 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(1) = exifData["Exif.Image.BlackLevel"].toLong(1);
black_level_per_channel.at(2) = exifData["Exif.Image.BlackLevel"].toLong(2); black_level_per_channel.at(2) = exifData["Exif.Image.BlackLevel"].toLong(2);
@ -64,26 +64,26 @@ bayer_image::bayer_image( const std::string& bayer_image_path )
// Create CV mat // Create CV mat
// https://answers.opencv.org/question/105972/de-bayering-a-cr2-image/ // https://answers.opencv.org/question/105972/de-bayering-a-cr2-image/
// https://www.libraw.org/node/2141 // 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 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 // 2x2 box filter
grayscale_image = box_filter_kxk<uint16_t, 2>( raw_image ); grayscale_image = box_filter_kxk<uint16_t, 2>(raw_image);
#ifndef NDEBUG #ifndef NDEBUG
printf("%s::%s read bayer image %s with\n width %zu\n height %zu\n iso %.3f\n white level %d\n black level %d %d %d %d\n", \ printf("%s::%s read bayer image %s with\n width %zu\n height %zu\n iso %.3f\n white level %d\n black level %d %d %d %d\n", \
__FILE__, __func__, bayer_image_path.c_str(), width, height, iso, white_level, \ __FILE__, __func__, bayer_image_path.c_str(), 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] ); black_level_per_channel[0], black_level_per_channel[1], black_level_per_channel[2], black_level_per_channel[3]);
fflush( stdout ); fflush(stdout);
#endif #endif
} }
bayer_image::bayer_image( const std::vector<uint8_t>& bayer_image_content ) bayer_image::bayer_image(const std::vector<uint8_t>& bayer_image_content)
{ {
libraw_processor = std::make_shared<LibRaw>(); libraw_processor = std::make_shared<LibRaw>();
// Open RAW image file // Open RAW image file
int return_code; int return_code;
if ( ( return_code = libraw_processor->open_buffer( (void *)(&bayer_image_content[0]), bayer_image_content.size() ) ) != LIBRAW_SUCCESS ) if ((return_code = libraw_processor->open_buffer((void *)(&bayer_image_content[0]), bayer_image_content.size())) != LIBRAW_SUCCESS)
{ {
libraw_processor->recycle(); libraw_processor->recycle();
#ifdef __ANDROID__ || _WIN32 #ifdef __ANDROID__ || _WIN32
@ -95,7 +95,7 @@ bayer_image::bayer_image( const std::vector<uint8_t>& bayer_image_content )
} }
// 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__ || _WIN32 #ifdef __ANDROID__ || _WIN32
return; return;
@ -106,8 +106,8 @@ bayer_image::bayer_image( const std::vector<uint8_t>& bayer_image_content )
} }
// Get image basic info // Get image basic info
width = int( libraw_processor->imgdata.rawdata.sizes.raw_width ); width = int(libraw_processor->imgdata.rawdata.sizes.raw_width);
height = int( libraw_processor->imgdata.rawdata.sizes.raw_height ); height = int(libraw_processor->imgdata.rawdata.sizes.raw_height);
// Read exif tags // Read exif tags
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(&bayer_image_content[0], bayer_image_content.size()); Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(&bayer_image_content[0], bayer_image_content.size());
@ -120,7 +120,7 @@ bayer_image::bayer_image( const std::vector<uint8_t>& bayer_image_content )
} }
white_level = exifData["Exif.Image.WhiteLevel"].toLong(); white_level = exifData["Exif.Image.WhiteLevel"].toLong();
black_level_per_channel.resize( 4 ); black_level_per_channel.resize(4);
black_level_per_channel.at(0) = exifData["Exif.Image.BlackLevel"].toLong(0); 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(1) = exifData["Exif.Image.BlackLevel"].toLong(1);
black_level_per_channel.at(2) = exifData["Exif.Image.BlackLevel"].toLong(2); black_level_per_channel.at(2) = exifData["Exif.Image.BlackLevel"].toLong(2);
@ -130,20 +130,20 @@ bayer_image::bayer_image( const std::vector<uint8_t>& bayer_image_content )
// Create CV mat // Create CV mat
// https://answers.opencv.org/question/105972/de-bayering-a-cr2-image/ // https://answers.opencv.org/question/105972/de-bayering-a-cr2-image/
// https://www.libraw.org/node/2141 // 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 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 // 2x2 box filter
grayscale_image = box_filter_kxk<uint16_t, 2>( raw_image ); grayscale_image = box_filter_kxk<uint16_t, 2>(raw_image);
#ifndef NDEBUG #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", \ 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, \ __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] ); black_level_per_channel[0], black_level_per_channel[1], black_level_per_channel[2], black_level_per_channel[3]);
fflush( stdout ); fflush(stdout);
#endif #endif
} }
bayer_image::bayer_image( std::shared_ptr<MemFile> bayer_image_file ) bayer_image::bayer_image(std::shared_ptr<MemFile> bayer_image_file)
{ {
libraw_processor = std::make_shared<LibRaw>(); libraw_processor = std::make_shared<LibRaw>();
@ -151,7 +151,7 @@ bayer_image::bayer_image( const std::vector<uint8_t>& bayer_image_content )
int return_code; int return_code;
{ {
std::vector<uint8_t>& fileData = bayer_image_file->content; std::vector<uint8_t>& fileData = bayer_image_file->content;
if ( ( return_code = libraw_processor->open_buffer( (void *)(&fileData[0]), fileData.size() ) ) != LIBRAW_SUCCESS ) if ((return_code = libraw_processor->open_buffer((void *)(&fileData[0]), fileData.size())) != LIBRAW_SUCCESS)
{ {
libraw_processor->recycle(); libraw_processor->recycle();
#ifdef __ANDROID__ #ifdef __ANDROID__
@ -165,7 +165,7 @@ bayer_image::bayer_image( const std::vector<uint8_t>& bayer_image_content )
// 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__ #ifdef __ANDROID__
return; return;
@ -176,8 +176,8 @@ bayer_image::bayer_image( const std::vector<uint8_t>& bayer_image_content )
} }
// Get image basic info // Get image basic info
width = int( libraw_processor->imgdata.rawdata.sizes.raw_width ); width = int(libraw_processor->imgdata.rawdata.sizes.raw_width);
height = int( libraw_processor->imgdata.rawdata.sizes.raw_height ); height = int(libraw_processor->imgdata.rawdata.sizes.raw_height);
// Read exif tags // Read exif tags
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(&bayer_image_file->content[0], bayer_image_file->content.size()); Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(&bayer_image_file->content[0], bayer_image_file->content.size());
@ -190,7 +190,7 @@ bayer_image::bayer_image( const std::vector<uint8_t>& bayer_image_content )
} }
white_level = exifData["Exif.Image.WhiteLevel"].toLong(); white_level = exifData["Exif.Image.WhiteLevel"].toLong();
black_level_per_channel.resize( 4 ); black_level_per_channel.resize(4);
black_level_per_channel.at(0) = exifData["Exif.Image.BlackLevel"].toLong(0); 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(1) = exifData["Exif.Image.BlackLevel"].toLong(1);
black_level_per_channel.at(2) = exifData["Exif.Image.BlackLevel"].toLong(2); black_level_per_channel.at(2) = exifData["Exif.Image.BlackLevel"].toLong(2);
@ -200,21 +200,21 @@ bayer_image::bayer_image( const std::vector<uint8_t>& bayer_image_content )
// Create CV mat // Create CV mat
// https://answers.opencv.org/question/105972/de-bayering-a-cr2-image/ // https://answers.opencv.org/question/105972/de-bayering-a-cr2-image/
// https://www.libraw.org/node/2141 // 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 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 // 2x2 box filter
grayscale_image = box_filter_kxk<uint16_t, 2>( raw_image ); grayscale_image = box_filter_kxk<uint16_t, 2>(raw_image);
#ifndef NDEBUG #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", \ 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, \ __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] ); black_level_per_channel[0], black_level_per_channel[1], black_level_per_channel[2], black_level_per_channel[3]);
fflush( stdout ); fflush(stdout);
#endif #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
double iso_ = iso <= 0 ? 100 : iso; double iso_ = iso <= 0 ? 100 : iso;
@ -233,6 +233,6 @@ std::pair<double, double> bayer_image::get_noise_params() const
// return pair // return pair
return std::make_pair(lambda_shot, lambda_read); return std::make_pair(lambda_shot, lambda_read);
} }
} }

File diff suppressed because it is too large Load Diff

@ -17,117 +17,117 @@
namespace hdrplus namespace hdrplus
{ {
void hdrplus_pipeline::run_pipeline( \ void hdrplus_pipeline::run_pipeline(\
const std::string& burst_path, \ const std::string& burst_path, \
const std::string& reference_image_path ) const std::string& reference_image_path)
{ {
// 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
align_module.process( burst_images, alignments ); align_module.process(burst_images, alignments);
// 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);
} }
bool 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__ #ifdef __ANDROID__
// ALOGI("Finish loading images"); // ALOGI("Finish loading images");
#endif #endif
// Run align // Run align
align_module.process( burst_images, alignments ); align_module.process(burst_images, alignments);
#ifdef __ANDROID__ #ifdef __ANDROID__
// ALOGI("Finish align"); // ALOGI("Finish align");
#endif #endif
// Run merging // Run merging
merge_module.process( burst_images, alignments ); merge_module.process(burst_images, alignments);
#ifdef __ANDROID__ #ifdef __ANDROID__
// ALOGI("Finish merging"); // ALOGI("Finish merging");
#endif #endif
// Run finishing // Run finishing
finish_module.process( burst_images, finalImg); finish_module.process(burst_images, finalImg);
#ifdef __ANDROID__ #ifdef __ANDROID__
// ALOGI("Finish process"); // ALOGI("Finish process");
#endif #endif
return true; return true;
} }
bool hdrplus_pipeline::run_pipeline( \ bool hdrplus_pipeline::run_pipeline(\
const std::vector<std::vector<uint8_t> >& burst_contents, \ const std::vector<std::vector<uint8_t> >& burst_contents, \
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_contents, reference_image_index ); burst burst_images(burst_contents, 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__ #ifdef __ANDROID__
// ALOGI("Finish loading images"); // ALOGI("Finish loading images");
#endif #endif
// Run align // Run align
align_module.process( burst_images, alignments ); align_module.process(burst_images, alignments);
#ifdef __ANDROID__ #ifdef __ANDROID__
// ALOGI("Finish align"); // ALOGI("Finish align");
#endif #endif
// Run merging // Run merging
merge_module.process( burst_images, alignments ); merge_module.process(burst_images, alignments);
#ifdef __ANDROID__ #ifdef __ANDROID__
// ALOGI("Finish merging"); // ALOGI("Finish merging");
#endif #endif
// Run finishing // Run finishing
finish_module.process( burst_images, finalImg); finish_module.process(burst_images, finalImg);
#ifdef __ANDROID__ #ifdef __ANDROID__
// ALOGI("Finish process"); // ALOGI("Finish process");
#endif #endif
return true; return true;
} }
bool hdrplus_pipeline::run_pipeline( \ bool hdrplus_pipeline::run_pipeline(\
const std::vector<std::shared_ptr<MemFile> >& burst_files, \ const std::vector<std::shared_ptr<MemFile> >& burst_files, \
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_files, reference_image_index ); burst burst_images(burst_files, 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__ #ifdef __ANDROID__
// ALOGI("Finish loading images"); // ALOGI("Finish loading images");
#endif #endif
// Run align // Run align
align_module.process( burst_images, alignments ); align_module.process(burst_images, alignments);
#ifdef __ANDROID__ #ifdef __ANDROID__
// ALOGI("Finish align"); // ALOGI("Finish align");
#endif #endif
// Run merging // Run merging
merge_module.process( burst_images, alignments ); merge_module.process(burst_images, alignments);
#ifdef __ANDROID__ #ifdef __ANDROID__
// ALOGI("Finish merging"); // ALOGI("Finish merging");
#endif #endif
// Run finishing // Run finishing
finish_module.process( burst_images, finalImg); finish_module.process(burst_images, finalImg);
#ifdef __ANDROID__ #ifdef __ANDROID__
// ALOGI("Finish process"); // ALOGI("Finish process");
#endif #endif

@ -63,13 +63,13 @@ namespace hdrplus
// Write all channels back to a bayer mat // Write all channels back to a bayer mat
cv::Mat merged(reference_image.rows, reference_image.cols, CV_16U); cv::Mat merged(reference_image.rows, reference_image.cols, CV_16U);
int x, y; int x, y;
for (y = 0; y < reference_image.rows; ++y){ for (y = 0; y < reference_image.rows; ++y) {
uint16_t* row = merged.ptr<uint16_t>(y); uint16_t* row = merged.ptr<uint16_t>(y);
if (y % 2 == 0){ if (y % 2 == 0) {
uint16_t* i0 = processed_channels[0].ptr<uint16_t>(y / 2); uint16_t* i0 = processed_channels[0].ptr<uint16_t>(y / 2);
uint16_t* i1 = processed_channels[1].ptr<uint16_t>(y / 2); uint16_t* i1 = processed_channels[1].ptr<uint16_t>(y / 2);
for (x = 0; x < reference_image.cols;){ for (x = 0; x < reference_image.cols;) {
//R //R
row[x] = i0[x / 2]; row[x] = i0[x / 2];
x++; x++;
@ -83,7 +83,7 @@ namespace hdrplus
uint16_t* i2 = processed_channels[2].ptr<uint16_t>(y / 2); uint16_t* i2 = processed_channels[2].ptr<uint16_t>(y / 2);
uint16_t* i3 = processed_channels[3].ptr<uint16_t>(y / 2); uint16_t* i3 = processed_channels[3].ptr<uint16_t>(y / 2);
for(x = 0; x < reference_image.cols;){ for (x = 0; x < reference_image.cols;) {
//G2 //G2
row[x] = i2[x / 2]; row[x] = i2[x / 2];
x++; x++;
@ -172,7 +172,7 @@ namespace hdrplus
cv::Mat merge::processChannel(hdrplus::burst& burst_images, \ cv::Mat merge::processChannel(hdrplus::burst& burst_images, \
std::vector<std::vector<std::vector<std::pair<int, int>>>>& alignments, \ std::vector<std::vector<std::vector<std::pair<int, int>>>>& alignments, \
cv::Mat channel_image, \ cv::Mat channel_image, \
std::vector<cv::Mat> alternate_channel_i_list,\ std::vector<cv::Mat> alternate_channel_i_list, \
float lambda_shot, \ float lambda_shot, \
float lambda_read) { float lambda_read) {
// Get tiles of the reference image // Get tiles of the reference image
@ -320,7 +320,7 @@ namespace hdrplus
// Calculate |w| using ifftshift // Calculate |w| using ifftshift
cv::Mat row_distances = cv::Mat::zeros(1, TILE_SIZE, CV_32F); cv::Mat row_distances = cv::Mat::zeros(1, TILE_SIZE, CV_32F);
for(int i = 0; i < TILE_SIZE; ++i) { for (int i = 0; i < TILE_SIZE; ++i) {
row_distances.at<float>(i) = i - offset; row_distances.at<float>(i) = i - offset;
} }
row_distances = cv::repeat(row_distances.t(), 1, TILE_SIZE); row_distances = cv::repeat(row_distances.t(), 1, TILE_SIZE);

Loading…
Cancel
Save