From 5b0ee9e08580efceda96ce4595ea7488450f909e Mon Sep 17 00:00:00 2001 From: siddharth Date: Fri, 26 Jul 2013 11:33:27 +0530 Subject: [PATCH] decolor module updated --- modules/photo/src/contrast_preserve.cpp | 42 +- modules/photo/src/contrast_preserve.hpp | 685 +++++++++++++----------- 2 files changed, 391 insertions(+), 336 deletions(-) diff --git a/modules/photo/src/contrast_preserve.cpp b/modules/photo/src/contrast_preserve.cpp index 570ef8059..154f997d8 100644 --- a/modules/photo/src/contrast_preserve.cpp +++ b/modules/photo/src/contrast_preserve.cpp @@ -1,6 +1,7 @@ #include "precomp.hpp" #include "opencv2/photo.hpp" #include "opencv2/imgproc.hpp" +#include #include "math.h" #include #include @@ -10,11 +11,11 @@ using namespace std; using namespace cv; -int rounding(double a); +double norm(double); -int rounding(double a) +double norm(double E) { - return int(a + 0.5); + return (sqrt(pow(E,2))); } void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _boost) @@ -37,33 +38,20 @@ void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _boost) return; } - float sigma = .02; - int maxIter = 8; + int maxIter = 15; int iterCount = 0; - - int h = I.size().height; - int w = I.size().width; + float tol = .0001; + double E = 0; + double pre_E = std::numeric_limits::infinity(); Decolor obj; Mat img; - - double sizefactor; - if((h + w) > 900) - { - sizefactor = (double)900/(h+w); - resize(I,I,Size(rounding(h*sizefactor),rounding(w*sizefactor))); - img = Mat(I.size(),CV_32FC3); - I.convertTo(img,CV_32FC3,1.0/255.0); - } - else - { - img = Mat(I.size(),CV_32FC3); - I.convertTo(img,CV_32FC3,1.0/255.0); - } + img = Mat(I.size(),CV_32FC3); + I.convertTo(img,CV_32FC3,1.0/255.0); - obj.init(); + obj.init(); vector Cg; vector < vector > polyGrad; @@ -83,9 +71,10 @@ void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _boost) //////////////////////////////// main loop starting //////////////////////////////////////// - while (iterCount < maxIter) + while(norm(E-pre_E) > tol) { iterCount +=1; + pre_E = E; vector G_pos; vector G_neg; @@ -150,6 +139,11 @@ void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _boost) for(unsigned int i =0;i maxIter) + break; + G_pos.clear(); G_neg.clear(); temp.clear(); diff --git a/modules/photo/src/contrast_preserve.hpp b/modules/photo/src/contrast_preserve.hpp index 440427fa2..77fc2195c 100644 --- a/modules/photo/src/contrast_preserve.hpp +++ b/modules/photo/src/contrast_preserve.hpp @@ -10,411 +10,472 @@ using namespace cv; class Decolor { - private: - Mat kernel; - Mat kernel1; - int order; - - public: - void init(); - vector product(vector < vector > &comb, vector &initRGB); - void singleChannelGradx(const Mat &img, Mat& dest); - void singleChannelGrady(const Mat &img, Mat& dest); - void gradvector(const Mat &img, vector &grad); - void colorGrad(Mat img, vector &Cg); - void add_vector(vector < vector > &comb, int r,int g,int b); - void add_to_vector_poly(vector < vector > &polyGrad, vector &curGrad); - void weak_order(Mat img, vector &alf); - void grad_system(Mat img, vector < vector < double > > &polyGrad, vector < double > &Cg, vector < vector >& comb); - void wei_update_matrix(vector < vector > &poly, vector &Cg, Mat &X); - void wei_inti(vector < vector > &comb, vector &wei); - void grayImContruct(vector &wei, Mat img, Mat &Gray); + private: + Mat kernel; + Mat kernel1; + int order; + + public: + void init(); + vector product(vector < vector > &comb, vector &initRGB); + double energyCalcu(vector &Cg, vector < vector > &polyGrad, vector &wei); + void singleChannelGradx(const Mat &img, Mat& dest); + void singleChannelGrady(const Mat &img, Mat& dest); + void gradvector(const Mat &img, vector &grad); + void colorGrad(Mat img, vector &Cg); + void add_vector(vector < vector > &comb, int r,int g,int b); + void add_to_vector_poly(vector < vector > &polyGrad, vector &curGrad); + void weak_order(Mat img, vector &alf); + void grad_system(Mat img, vector < vector < double > > &polyGrad, + vector < double > &Cg, vector < vector >& comb); + void wei_update_matrix(vector < vector > &poly, vector &Cg, Mat &X); + void wei_inti(vector < vector > &comb, vector &wei); + void grayImContruct(vector &wei, Mat img, Mat &Gray); }; +int rounding(double a); + +int rounding(double a) +{ + return int(a + 0.5); +} + +float sigma = .02; + +double Decolor::energyCalcu(vector &Cg, vector < vector > &polyGrad, vector &wei) +{ + vector P; + + vector temp; + vector temp1; + + double val = 0.0; + for(unsigned int i=0;i< polyGrad[0].size();i++) + { + val = 0.0; + for(unsigned int j =0;j(0,0)=1.0; - kernel.at(0,1)=-1.0; - kernel1.at(0,0)=1.0; - kernel1.at(1,0)=-1.0; - order = 2; + kernel = Mat(1,2, CV_32FC1); + kernel1 = Mat(2,1, CV_32FC1); + kernel.at(0,0)=1.0; + kernel.at(0,1)=-1.0; + kernel1.at(0,0)=1.0; + kernel1.at(1,0)=-1.0; + order = 2; } vector Decolor::product(vector < vector > &comb, vector &initRGB) { - vector res; - float dp; - for (unsigned int i=0;i res; + float dp; + for (unsigned int i=0;i(i,w-1)=0.0; + int w=img.size().width; + int h=img.size().height; + Point anchor(kernel.cols - kernel.cols/2 - 1, kernel.rows - kernel.rows/2 - 1); + filter2D(img, dest, -1, kernel, anchor, 0.0, BORDER_CONSTANT); + for(int i=0;i(i,w-1)=0.0; } void Decolor::singleChannelGrady(const Mat &img, Mat& dest) { - int w=img.size().width; - int h=img.size().height; - Point anchor(kernel1.cols - kernel1.cols/2 - 1, kernel1.rows - kernel1.rows/2 - 1); - filter2D(img, dest, -1, kernel1, anchor, 0.0, BORDER_CONSTANT); - for(int j=0;j(h-1,j)=0.0; + int w=img.size().width; + int h=img.size().height; + Point anchor(kernel1.cols - kernel1.cols/2 - 1, kernel1.rows - kernel1.rows/2 - 1); + filter2D(img, dest, -1, kernel1, anchor, 0.0, BORDER_CONSTANT); + for(int j=0;j(h-1,j)=0.0; } void Decolor::gradvector(const Mat &img, vector &grad) { - Mat dest= Mat(img.size().height,img.size().width, CV_32FC1); - Mat dest1= Mat(img.size().height,img.size().width, CV_32FC1); - singleChannelGradx(img,dest); - singleChannelGrady(img,dest1); + Mat dest= Mat(img.size().height,img.size().width, CV_32FC1); + Mat dest1= Mat(img.size().height,img.size().width, CV_32FC1); + singleChannelGradx(img,dest); + singleChannelGrady(img,dest1); - Mat d_trans=dest.t(); - Mat d1_trans=dest1.t(); + Mat d_trans=dest.t(); + Mat d1_trans=dest1.t(); - int height = d_trans.size().height; - int width = d_trans.size().width; + int height = d_trans.size().height; + int width = d_trans.size().width; - for(int i=0;i(i,j)); + for(int i=0;i(i,j)); - for(int i=0;i(i,j)); - dest.release(); - dest1.release(); + for(int i=0;i(i,j)); + dest.release(); + dest1.release(); } - + void Decolor::colorGrad(Mat img, vector &Cg) { - Mat lab = Mat(img.size(),CV_32FC3); - Mat l_channel = Mat(img.size(),CV_32FC1); - Mat a_channel = Mat(img.size(),CV_32FC1); - Mat b_channel = Mat(img.size(),CV_32FC1); + Mat lab = Mat(img.size(),CV_32FC3); + Mat l_channel = Mat(img.size(),CV_32FC1); + Mat a_channel = Mat(img.size(),CV_32FC1); + Mat b_channel = Mat(img.size(),CV_32FC1); - cvtColor(img,lab,COLOR_BGR2Lab); - for(int i=0;i(i,j) = lab.at(i,j*3+0); - a_channel.at(i,j) = lab.at(i,j*3+1); - b_channel.at(i,j) = lab.at(i,j*3+2); - } + cvtColor(img,lab,COLOR_BGR2Lab); + for(int i=0;i(i,j) = lab.at(i,j*3+0); + a_channel.at(i,j) = lab.at(i,j*3+1); + b_channel.at(i,j) = lab.at(i,j*3+2); + } - vector ImL; - vector Ima; - vector Imb; - gradvector(l_channel,ImL); - gradvector(a_channel,Ima); - gradvector(b_channel,Imb); + vector ImL; + vector Ima; + vector Imb; + gradvector(l_channel,ImL); + gradvector(a_channel,Ima); + gradvector(b_channel,Imb); - double res =0.0; - for(unsigned int i=0;i > &comb, int r,int g,int b) { - static int idx =0; - comb.push_back( vector () ); - comb.at(idx).push_back( r ); - comb.at(idx).push_back( g ); - comb.at(idx).push_back( b ); - idx++; + static int idx =0; + comb.push_back( vector () ); + comb.at(idx).push_back( r ); + comb.at(idx).push_back( g ); + comb.at(idx).push_back( b ); + idx++; } void Decolor::add_to_vector_poly(vector < vector > &polyGrad, vector &curGrad) { - static int idx1 =0; - polyGrad.push_back( vector () ); - for(unsigned int i=0;i() ); + for(unsigned int i=0;i &alf) { - Mat curIm = Mat(img.size(),CV_32FC1); - Mat red = Mat(img.size(),CV_32FC1); - Mat green = Mat(img.size(),CV_32FC1); - Mat blue = Mat(img.size(),CV_32FC1); + int h = img.size().height; + int w = img.size().width; + double sizefactor; + if((h + w) > 800) + { + sizefactor = (double)800/(h+w); + resize(img,img,Size(rounding(h*sizefactor),rounding(w*sizefactor))); + } - for(int i=0;i(i,j) = img.at(i,j*3+2); - green.at(i,j) = img.at(i,j*3+1); - blue.at(i,j) = img.at(i,j*3+0); - } - - vector Rg; - vector Gg; - vector Bg; + Mat curIm = Mat(img.size(),CV_32FC1); + Mat red = Mat(img.size(),CV_32FC1); + Mat green = Mat(img.size(),CV_32FC1); + Mat blue = Mat(img.size(),CV_32FC1); - vector t1; - vector t2; - vector t3; - - vector tmp1; - vector tmp2; - vector tmp3; + for(int i=0;i(i,j) = img.at(i,j*3+2); + green.at(i,j) = img.at(i,j*3+1); + blue.at(i,j) = img.at(i,j*3+0); + } + + vector Rg; + vector Gg; + vector Bg; - gradvector(red,Rg); - gradvector(green,Gg); - gradvector(blue,Bg); - double level = .05; + vector t1; + vector t2; + vector t3; + + vector tmp1; + vector tmp2; + vector tmp3; - for(unsigned int i=0;i level) - t1.push_back(1.0); - else - t1.push_back(0.0); - } - for(unsigned int i=0;i level) - t2.push_back(1.0); - else - t2.push_back(0.0); - } - for(unsigned int i=0;i level) - t3.push_back(1.0); - else - t3.push_back(0.0); - } - for(unsigned int i=0;i level) + t1.push_back(1.0); + else + t1.push_back(0.0); + } + for(unsigned int i=0;i level) + t2.push_back(1.0); + else + t2.push_back(0.0); + } + for(unsigned int i=0;i level) + t3.push_back(1.0); + else + t3.push_back(0.0); + } + for(unsigned int i=0;i > &polyGrad, vector < double > &Cg, vector < vector >& comb) +void Decolor::grad_system(Mat img, vector < vector < double > > &polyGrad, + vector < double > &Cg, vector < vector >& comb) { - int h = img.size().height; - int w = img.size().width; - colorGrad(img,Cg); - - Mat curIm = Mat(img.size(),CV_32FC1); - Mat red = Mat(img.size(),CV_32FC1); - Mat green = Mat(img.size(),CV_32FC1); - Mat blue = Mat(img.size(),CV_32FC1); + int h = img.size().height; + int w = img.size().width; - for(int i=0;i(i,j) = img.at(i,j*3+2); - green.at(i,j) = img.at(i,j*3+1); - blue.at(i,j) = img.at(i,j*3+0); - } - for(int r=0 ;r <=order; r++) - for(int g=0; g<=order;g++) - for(int b =0; b <=order;b++) - { - if((r+g+b)<=order && (r+g+b) > 0) - { - add_vector(comb,r,g,b); - for(int i = 0;i(i,j)= - pow(red.at(i,j),r)*pow(green.at(i,j),g)* - pow(blue.at(i,j),b); - vector curGrad; - gradvector(curIm,curGrad); - add_to_vector_poly(polyGrad,curGrad); - } - } + double sizefactor; + if((h + w) > 800) + { + sizefactor = (double)800/(h+w); + resize(img,img,Size(rounding(h*sizefactor),rounding(w*sizefactor))); + } - red.release(); - green.release(); - blue.release(); - curIm.release(); + h = img.size().height; + w = img.size().width; + colorGrad(img,Cg); + + Mat curIm = Mat(img.size(),CV_32FC1); + Mat red = Mat(img.size(),CV_32FC1); + Mat green = Mat(img.size(),CV_32FC1); + Mat blue = Mat(img.size(),CV_32FC1); + + for(int i=0;i(i,j) = img.at(i,j*3+2); + green.at(i,j) = img.at(i,j*3+1); + blue.at(i,j) = img.at(i,j*3+0); + } + + for(int r=0 ;r <=order; r++) + for(int g=0; g<=order;g++) + for(int b =0; b <=order;b++) + { + if((r+g+b)<=order && (r+g+b) > 0) + { + add_vector(comb,r,g,b); + for(int i = 0;i(i,j)= + pow(red.at(i,j),r)*pow(green.at(i,j),g)* + pow(blue.at(i,j),b); + vector curGrad; + gradvector(curIm,curGrad); + add_to_vector_poly(polyGrad,curGrad); + } + } + + red.release(); + green.release(); + blue.release(); + curIm.release(); } void Decolor::wei_update_matrix(vector < vector > &poly, vector &Cg, Mat &X) { - Mat P = Mat(poly.size(),poly[0].size(), CV_32FC1); - Mat A = Mat(poly.size(),poly.size(), CV_32FC1); + Mat P = Mat(poly.size(),poly[0].size(), CV_32FC1); + Mat A = Mat(poly.size(),poly.size(), CV_32FC1); - for(unsigned int i =0;i(i,j) = poly[i][j]; + for(unsigned int i =0;i(i,j) = poly[i][j]; - Mat P_trans = P.t(); - Mat B = Mat(poly.size(),poly[0].size(), CV_32FC1); - for(unsigned int i =0;i < poly.size();i++) - { - for(unsigned int j=0;j(i,j) = poly[i][j]*Cg[j]; - } + Mat P_trans = P.t(); + Mat B = Mat(poly.size(),poly[0].size(), CV_32FC1); + for(unsigned int i =0;i < poly.size();i++) + { + for(unsigned int j=0;j(i,j) = poly[i][j]*Cg[j]; + } - A = P*P_trans; - solve(A, B, X, DECOMP_NORMAL); + A = P*P_trans; + solve(A, B, X, DECOMP_NORMAL); - P.release(); - A.release(); - B.release(); + P.release(); + A.release(); + B.release(); } void Decolor::wei_inti(vector < vector > &comb, vector &wei) { - vector initRGB; + vector initRGB; - initRGB.push_back( .33 ); - initRGB.push_back( .33 ); - initRGB.push_back( .33 ); - wei = product(comb,initRGB); + initRGB.push_back( .33 ); + initRGB.push_back( .33 ); + initRGB.push_back( .33 ); + wei = product(comb,initRGB); - vector sum; + vector sum; - for(unsigned int i=0;i &wei, Mat img, Mat &Gray) { - int h=img.size().height; - int w=img.size().width; + int h=img.size().height; + int w=img.size().width; - Mat red = Mat(img.size(),CV_32FC1); - Mat green = Mat(img.size(),CV_32FC1); - Mat blue = Mat(img.size(),CV_32FC1); + Mat red = Mat(img.size(),CV_32FC1); + Mat green = Mat(img.size(),CV_32FC1); + Mat blue = Mat(img.size(),CV_32FC1); - for(int i=0;i(i,j) = img.at(i,j*3+2); - green.at(i,j) = img.at(i,j*3+1); - blue.at(i,j) = img.at(i,j*3+0); - } + for(int i=0;i(i,j) = img.at(i,j*3+2); + green.at(i,j) = img.at(i,j*3+1); + blue.at(i,j) = img.at(i,j*3+0); + } - int kk =0; - - for(int r =0;r<=order;r++) - for(int g=0;g<=order;g++) - for(int b=0;b<=order;b++) - if((r + g + b) <=order && (r+g+b) > 0) - { - for(int i = 0;i(i,j)=Gray.at(i,j) + - wei[kk]*pow(red.at(i,j),r)*pow(green.at(i,j),g)* - pow(blue.at(i,j),b); + int kk =0; + + for(int r =0;r<=order;r++) + for(int g=0;g<=order;g++) + for(int b=0;b<=order;b++) + if((r + g + b) <=order && (r+g+b) > 0) + { + for(int i = 0;i(i,j)=Gray.at(i,j) + + wei[kk]*pow(red.at(i,j),r)*pow(green.at(i,j),g)* + pow(blue.at(i,j),b); - kk=kk+1; - } + kk=kk+1; + } - double minval = INT_MAX; - double maxval = INT_MIN; + double minval = INT_MAX; + double maxval = INT_MIN; - for(int i=0;i(i,j) < minval) - minval = Gray.at(i,j); - - if(Gray.at(i,j) > maxval) - maxval = Gray.at(i,j); - } + for(int i=0;i(i,j) < minval) + minval = Gray.at(i,j); + + if(Gray.at(i,j) > maxval) + maxval = Gray.at(i,j); + } - for(int i=0;i(i,j) = (Gray.at(i,j) - minval)/(maxval - minval); + for(int i=0;i(i,j) = (Gray.at(i,j) - minval)/(maxval - minval); - red.release(); - green.release(); - blue.release(); + red.release(); + green.release(); + blue.release(); }