#include "precomp.hpp" #include "opencv2/photo.hpp" #include "opencv2/imgproc.hpp" #include "math.h" #include #include using namespace std; using namespace cv; class Decolor { 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; } vector Decolor::product(vector < vector > &comb, vector &initRGB) { vector res; float dp; for (unsigned 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; } 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 d_trans=dest.t(); Mat d1_trans=dest1.t(); 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)); 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); 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); 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++; } 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 &alf) { 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))); } 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); } vector Rg; vector Gg; vector Bg; vector t1; vector t2; vector t3; vector tmp1; vector tmp2; vector tmp3; gradvector(red,Rg); gradvector(green,Gg); gradvector(blue,Bg); double level = .05; 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) { 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))); } 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); 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]; } A = P*P_trans; solve(A, B, X, DECOMP_NORMAL); P.release(); A.release(); B.release(); } void Decolor::wei_inti(vector < vector > &comb, vector &wei) { vector initRGB; initRGB.push_back( .33 ); initRGB.push_back( .33 ); initRGB.push_back( .33 ); wei = product(comb,initRGB); vector sum; for(unsigned int i=0;i &wei, Mat img, Mat &Gray) { 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); 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); kk=kk+1; } 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) = (Gray.at(i,j) - minval)/(maxval - minval); red.release(); green.release(); blue.release(); }