Path: blob/master/modules/photo/src/contrast_preserve.cpp
16339 views
/*M///////////////////////////////////////////////////////////////////////////////////////1//2// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.3//4// By downloading, copying, installing or using the software you agree to this license.5// If you do not agree to this license, do not download, install,6// copy or use the software.7//8//9// License Agreement10// For Open Source Computer Vision Library11//12// Copyright (C) 2013, OpenCV Foundation, all rights reserved.13// Third party copyrights are property of their respective owners.14//15// Redistribution and use in source and binary forms, with or without modification,16// are permitted provided that the following conditions are met:17//18// * Redistribution's of source code must retain the above copyright notice,19// this list of conditions and the following disclaimer.20//21// * Redistribution's in binary form must reproduce the above copyright notice,22// this list of conditions and the following disclaimer in the documentation23// and/or other materials provided with the distribution.24//25// * The name of the copyright holders may not be used to endorse or promote products26// derived from this software without specific prior written permission.27//28// This software is provided by the copyright holders and contributors "as is" and29// any express or implied warranties, including, but not limited to, the implied30// warranties of merchantability and fitness for a particular purpose are disclaimed.31// In no event shall the Intel Corporation or contributors be liable for any direct,32// indirect, incidental, special, exemplary, or consequential damages33// (including, but not limited to, procurement of substitute goods or services;34// loss of use, data, or profits; or business interruption) however caused35// and on any theory of liability, whether in contract, strict liability,36// or tort (including negligence or otherwise) arising in any way out of37// the use of this software, even if advised of the possibility of such damage.38//39//M*/404142#include "precomp.hpp"43#include "opencv2/photo.hpp"44#include <cmath>45#include <vector>46#include <limits>47#include "contrast_preserve.hpp"4849using namespace std;50using namespace cv;5152void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _color_boost)53{54CV_INSTRUMENT_REGION();5556Mat I = _src.getMat();57_dst.create(I.size(), CV_8UC1);58Mat dst = _dst.getMat();5960_color_boost.create(I.size(), CV_8UC3);61Mat color_boost = _color_boost.getMat();6263CV_Assert(!I.empty() && (I.channels()==3));6465// Parameter Setting66const int maxIter = 15;67const double tol = .0001;68int iterCount = 0;69double E = 0;70double pre_E = std::numeric_limits<double>::infinity();7172Mat img;73I.convertTo(img, CV_32FC3, 1.0/255.0);7475// Initialization76Decolor obj;7778vector <double> Cg;79vector < vector <double> > polyGrad;80vector <Vec3i> comb;81vector <double> alf;8283obj.grad_system(img,polyGrad,Cg,comb);84obj.weak_order(img,alf);8586// Solver87Mat Mt = Mat(int(polyGrad.size()),int(polyGrad[0].size()), CV_32FC1);88obj.wei_update_matrix(polyGrad,Cg,Mt);8990vector <double> wei;91obj.wei_inti(comb,wei);9293//////////////////////////////// main loop starting ////////////////////////////////////////9495vector <double> G_pos(alf.size());96vector <double> G_neg(alf.size());97vector <double> EXPsum(G_pos.size());98vector <double> EXPterm(G_pos.size());99vector <double> temp(polyGrad[0].size());100vector <double> temp1(polyGrad[0].size());101vector <double> temp2(EXPsum.size());102vector <double> wei1(polyGrad.size());103104while(sqrt(pow(E-pre_E,2)) > tol)105{106iterCount +=1;107pre_E = E;108109for(size_t i=0; i<polyGrad[0].size(); i++)110{111double val = 0.0;112for(size_t j=0; j<polyGrad.size(); j++)113val = val + (polyGrad[j][i] * wei[j]);114temp[i] = val - Cg[i];115temp1[i] = val + Cg[i];116}117118for(size_t i=0; i<alf.size(); i++)119{120const double sqSigma = obj.sigma * obj.sigma;121const double pos = ((1 + alf[i])/2) * exp(-1.0 * 0.5 * (temp[i] * temp[i]) / sqSigma);122const double neg = ((1 - alf[i])/2) * exp(-1.0 * 0.5 * (temp1[i] * temp1[i]) / sqSigma);123G_pos[i] = pos;124G_neg[i] = neg;125}126127for(size_t i=0; i<G_pos.size(); i++)128EXPsum[i] = G_pos[i]+G_neg[i];129130for(size_t i=0; i<EXPsum.size(); i++)131temp2[i] = (EXPsum[i] == 0) ? 1.0 : 0.0;132133for(size_t i=0; i<G_pos.size(); i++)134EXPterm[i] = (G_pos[i] - G_neg[i])/(EXPsum[i] + temp2[i]);135136for(int i=0; i<int(polyGrad.size()); i++)137{138double val1 = 0.0;139for(int j=0; j<int(polyGrad[0].size()); j++)140{141val1 = val1 + (Mt.at<float>(i,j) * EXPterm[j]);142}143wei1[i] = val1;144}145146for(size_t i=0; i<wei.size(); i++)147wei[i] = wei1[i];148149E = obj.energyCalcu(Cg, polyGrad, wei);150151if(iterCount > maxIter)152break;153}154155Mat Gray = Mat::zeros(img.size(),CV_32FC1);156obj.grayImContruct(wei, img, Gray);157158Gray.convertTo(dst,CV_8UC1,255);159160/////////////////////////////////// Contrast Boosting /////////////////////////////////161162Mat lab;163cvtColor(I,lab,COLOR_BGR2Lab);164165vector <Mat> lab_channel;166split(lab,lab_channel);167168dst.copyTo(lab_channel[0]);169170merge(lab_channel,lab);171172cvtColor(lab,color_boost,COLOR_Lab2BGR);173}174175176