#ifdef _WIN32 #define _USE_MATH_DEFINES #include #else #include #endif #include #include // all opencv header #include "hdrplus/finish.h" #include "hdrplus/utility.h" #ifdef _WIN32 #include #endif #ifdef __ANDROID__ #define DBG_OUTPUT_ROOT "/sdcard/com.xypower.mpapp/tmp/" #else #define DBG_OUTPUT_ROOT "" #endif // #include namespace hdrplus { cv::Mat convert16bit2_8bit_(cv::Mat ans){ if(ans.type()==CV_16UC3){ cv::MatIterator_ it, end; for( it = ans.begin(), end = ans.end(); it != end; ++it) { // std::cout< it, end; for( it = ans.begin(), end = ans.end(); it != end; ++it) { // std::cout< it, end; for( it = ans.begin(), end = ans.end(); it != end; ++it) { // std::cout<1){ x = 1; } } x*=USHRT_MAX; return (uint16_t)x; } uint16_t uGammaDecompress_1pix(float x, float threshold,float gainMin,float gainMax,float exponent){ // Normalize pixel val x/=65535.0; // check the val against the threshold if(x<=threshold){ x = x/gainMin; }else{ x = pow((x+gainMax-1)/gainMax,exponent); } // clip if(x<0){ x=0; }else{ if(x>1){ x = 1; } } x*=65535; return (uint16_t)x; } cv::Mat uGammaCompress_(cv::Mat m,float threshold,float gainMin,float gainMax,float exponent){ if(m.type()==CV_16UC3){ cv::MatIterator_ it, end; for( it = m.begin(), end = m.end(); it != end; ++it) { (*it)[0] =uGammaCompress_1pix((*it)[0],threshold,gainMin,gainMax,exponent); (*it)[1] =uGammaCompress_1pix((*it)[1],threshold,gainMin,gainMax,exponent); (*it)[2] =uGammaCompress_1pix((*it)[2],threshold,gainMin,gainMax,exponent); } }else if(m.type()==CV_16UC1){ uint16_t* ptr = (uint16_t*)m.data; int end = m.rows*m.cols; for(int i=0;i it, end; for( it = m.begin(), end = m.end(); it != end; ++it) { (*it)[0] =uGammaDecompress_1pix((*it)[0],threshold,gainMin,gainMax,exponent); (*it)[1] =uGammaDecompress_1pix((*it)[1],threshold,gainMin,gainMax,exponent); (*it)[2] =uGammaDecompress_1pix((*it)[2],threshold,gainMin,gainMax,exponent); } }else if(m.type()==CV_16UC1){ uint16_t* ptr = (uint16_t*)m.data; int end = m.rows*m.cols; for(int i=0;i it, end; for( it = img.begin(), end = img.end(); it != end; ++it) { uint32_t tmp = (*it)[0]+(*it)[1]+(*it)[2]; uint16_t avg_val = tmp/3; *(ptr+idx) = avg_val; idx++; } return processedImg; } double getMean(cv::Mat img){ uint16_t* ptr = (uint16_t*)img.data; int max_idx = img.rows*img.cols*img.channels(); double sum=0; for(int i=0;iUSHRT_MAX){ *(ptr+i) = USHRT_MAX; }else{ *(ptr+i)=(uint16_t)tmp; } } return img; } double getSaturated(cv::Mat img, double threshold){ threshold *= USHRT_MAX; double count=0; uint16_t* ptr = (uint16_t*)img.data; int max_idx = img.rows*img.cols*img.channels(); for(int i=0;ithreshold){ count++; } } return count/(double)max_idx; } cv::Mat meanGain_(cv::Mat img,int gain){ if(img.channels()!=3){ std::cout<<"unsupport img type in meanGain_()"< it, end; for( it = img.begin(), end = img.end(); it != end; ++it) { double sum = 0; // R double tmp = (*it)[0]*gain; if(tmp<0) tmp=0; if(tmp>USHRT_MAX) tmp = USHRT_MAX; sum+=tmp; // G tmp = (*it)[1]*gain; if(tmp<0) tmp=0; if(tmp>USHRT_MAX) tmp = USHRT_MAX; sum+=tmp; // B tmp = (*it)[2]*gain; if(tmp<0) tmp=0; if(tmp>USHRT_MAX) tmp = USHRT_MAX; sum+=tmp; // put into processedImg uint16_t avg_val = sum/3; *(ptr+idx) = avg_val; idx++; } return processedImg; } } cv::Mat applyScaling_(cv::Mat mergedImage, cv::Mat shortGray, cv::Mat fusedGray){ cv::Mat result = mergedImage.clone(); uint16_t* ptr_shortg = (uint16_t*)shortGray.data; uint16_t* ptr_fusedg = (uint16_t*)fusedGray.data; int count = 0; cv::MatIterator_ it, end; for( it = result.begin(), end = result.end(); it != end; ++it) { double s = 1; if(*(ptr_shortg+count)!=0){ s = *(ptr_fusedg+count); s/=*(ptr_shortg+count); } for(int c=0;cUSHRT_MAX){ (*it)[c] = USHRT_MAX; }else{ (*it)[c] = tmp; } } } return result; } void localToneMap(cv::Mat& mergedImage, Options options, cv::Mat& shortg, cv::Mat& longg, cv::Mat& fusedg, int& gain){ std::cout<<"HDR Tone Mapping..."<(mergedImage); //mean_(mergedImage); std::cout<<"--- Compute grayscale image"< (1 - sSMean) / 2; // only works if burst underexposed saturated = getSaturated(longSg,0.95); if(options.verbose==4){ } } }else{ if(options.ltmGain>0){ gain = options.ltmGain; } } std::cout<<"--- Compute gain"< mergeMertens = cv::createMergeMertens(); std::cout<<"--- Create Mertens"< src_expos; src_expos.push_back(convert16bit2_8bit_(shortg.clone())); src_expos.push_back(convert16bit2_8bit_(longg.clone())); mergeMertens->process(src_expos, fusedg); fusedg = fusedg*USHRT_MAX; fusedg.convertTo(fusedg, CV_16UC1); std::cout<<"--- Apply Mertens"<1){ x = 1; } uint16_t result = x*USHRT_MAX; return result; } cv::Mat enhanceContrast(cv::Mat image, Options options){ if(options.gtmContrast>=0 && options.gtmContrast<=1){ uint16_t* ptr = (uint16_t*)image.data; int end = image.rows*image.cols*image.channels(); for(int idx = 0;idxUSHRT_MAX) r = USHRT_MAX; *(ptr_r+idx) = (uint16_t)r; } return result; } cv::Mat sharpenTriple(cv::Mat image, Tuning tuning, Options options){ // sharpen the image using unsharp masking std::vector amounts = tuning.sharpenAmount; std::vector sigmas = tuning.sharpenSigma; std::vector thresholds = tuning.sharpenThreshold; // Compute all Gaussian blur cv::Mat blur0,blur1,blur2; cv::GaussianBlur(image,blur0,cv::Size(0,0),sigmas[0]); cv::GaussianBlur(image,blur1,cv::Size(0,0),sigmas[1]); cv::GaussianBlur(image,blur2,cv::Size(0,0),sigmas[2]); std::cout<<" --- gaussian blur"< dvals; for(int c = 0; c < mergedImg.cols; c++) { dvals.push_back(*(ptr+r*mergedImg.cols+c)); } cv::Mat mline(dvals, true); cv::transpose(mline, mline); m.push_back(mline); } #endif int ch = CV_MAT_CN(opencv_type); m = mergedImg.clone(); m = m.reshape(ch); m.convertTo(m, opencv_type); return m; } void show20_20(cv::Mat m){ uint16_t* ptr = (uint16_t*)m.data; for(int i=0;i<20;i++){ for(int j=0;j<20;j++){ std::cout<<*(ptr+i*m.cols+j)<<", "; } std::cout<refIdx = burst_images.reference_image_idx; // this->burstPath = burstPath; // std::cout<<"processMerged:"<mergedBayer = loadFromCSV(DBG_OUTPUT_ROOT "merged.csv", CV_16UC1); // this->mergedBayer = processMergedMat(mergedB,CV_16UC1);//loadFromCSV("merged.csv", CV_16UC1); // std::cout<<"processMerged:"<mergedBayer); // this->mergedBayer = loadFromCSV(DBG_OUTPUT_ROOT "merged.csv", CV_16UC1); // this->mergedBayer = processMergedMat(burst_images.merged_bayer_image, CV_16UC1); #else // this->mergedBayer = loadFromCSV(DBG_OUTPUT_ROOT "merged.csv", CV_16UC1); this->mergedBayer = processMergedMat(burst_images.merged_bayer_image, CV_16UC1); // std::cout<<"processMerged:"<mergedBayer); // load_rawPathList(burstPath); // read in ref img // bayer_image* ref = new bayer_image(rawPathList[refIdx]); bayer_image* ref = new bayer_image(burst_images.bayer_images[burst_images.reference_image_idx]); cv::Mat processedRefImage = postprocess(ref->libraw_processor,params.rawpyArgs); std::cout<<"size ref: "<refIdx]); mergedImg->libraw_processor->imgdata.rawdata.raw_image = (uint16_t*)this->mergedBayer.data; // copy_mat_16U_3(mergedImg->libraw_processor->imgdata.rawdata.raw_image,this->mergedBayer); cv::Mat processedMerge = postprocess(mergedImg->libraw_processor,params.rawpyArgs); // write merged image #ifndef HDRPLUS_NO_DETAILED_OUTPUT if(params.flags["writeMergedImage"]){ std::cout<<"writing Merged img ..."<& libraw_ptr, cv::Mat B){ uint16_t* ptr_A = (uint16_t*)libraw_ptr->imgdata.rawdata.raw_image; uint16_t* ptr_B = (uint16_t*)B.data; for(int r = 0; r < B.rows; r++) { for(int c = 0; c < B.cols; c++) { *(ptr_A+r*B.cols+c) = *(ptr_B+r*B.cols+c); } } } } // namespace hdrplus