1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of the copyright holders may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42
43 #include "precomp.hpp"
44 #include "opencv2/photo.hpp"
45 #include "math.h"
46 #include <vector>
47 #include <limits>
48 #include "contrast_preserve.hpp"
49
50 using namespace std;
51 using namespace cv;
52
decolor(InputArray _src,OutputArray _dst,OutputArray _color_boost)53 void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _color_boost)
54 {
55 Mat I = _src.getMat();
56 _dst.create(I.size(), CV_8UC1);
57 Mat dst = _dst.getMat();
58
59 _color_boost.create(I.size(), CV_8UC3);
60 Mat color_boost = _color_boost.getMat();
61
62 CV_Assert(!I.empty() && (I.channels()==3));
63
64 // Parameter Setting
65 int maxIter = 15;
66 int iterCount = 0;
67 double tol = .0001;
68 double E = 0;
69 double pre_E = std::numeric_limits<double>::infinity();
70
71 Decolor obj;
72
73 Mat img;
74
75 img = Mat(I.size(),CV_32FC3);
76 I.convertTo(img,CV_32FC3,1.0/255.0);
77
78 // Initialization
79 obj.init();
80
81 vector <double> Cg;
82 vector < vector <double> > polyGrad;
83 vector < vector < int > > comb;
84
85 vector <double> alf;
86
87 obj.grad_system(img,polyGrad,Cg,comb);
88 obj.weak_order(img,alf);
89
90 // Solver
91 Mat Mt = Mat((int)polyGrad.size(),(int)polyGrad[0].size(), CV_32FC1);
92 obj.wei_update_matrix(polyGrad,Cg,Mt);
93
94 vector <double> wei;
95 obj.wei_inti(comb,wei);
96
97 //////////////////////////////// main loop starting ////////////////////////////////////////
98
99 while(sqrt(pow(E-pre_E,2)) > tol)
100 {
101 iterCount +=1;
102 pre_E = E;
103
104 vector <double> G_pos;
105 vector <double> G_neg;
106
107 vector <double> temp;
108 vector <double> temp1;
109
110 double val = 0.0;
111 for(unsigned int i=0;i< polyGrad[0].size();i++)
112 {
113 val = 0.0;
114 for(unsigned int j =0;j<polyGrad.size();j++)
115 val = val + (polyGrad[j][i] * wei[j]);
116 temp.push_back(val - Cg[i]);
117 temp1.push_back(val + Cg[i]);
118 }
119
120 double pos = 0.0;
121 double neg = 0.0;
122 for(unsigned int i =0;i<alf.size();i++)
123 {
124 pos = ((1 + alf[i])/2) * exp((-1.0 * 0.5 * pow(temp[i],2))/pow(obj.sigma,2));
125 neg = ((1 - alf[i])/2) * exp((-1.0 * 0.5 * pow(temp1[i],2))/pow(obj.sigma,2));
126 G_pos.push_back(pos);
127 G_neg.push_back(neg);
128 }
129
130 vector <double> EXPsum;
131 vector <double> EXPterm;
132
133 for(unsigned int i = 0;i<G_pos.size();i++)
134 EXPsum.push_back(G_pos[i]+G_neg[i]);
135
136 vector <double> temp2;
137
138 for(unsigned int i=0;i<EXPsum.size();i++)
139 {
140 if(EXPsum[i] == 0)
141 temp2.push_back(1.0);
142 else
143 temp2.push_back(0.0);
144 }
145
146 for(unsigned int i =0; i < G_pos.size();i++)
147 EXPterm.push_back((G_pos[i] - G_neg[i])/(EXPsum[i] + temp2[i]));
148
149 double val1 = 0.0;
150 vector <double> wei1;
151
152 for(unsigned int i=0;i< polyGrad.size();i++)
153 {
154 val1 = 0.0;
155 for(unsigned int j =0;j<polyGrad[0].size();j++)
156 {
157 val1 = val1 + (Mt.at<float>(i,j) * EXPterm[j]);
158 }
159 wei1.push_back(val1);
160 }
161
162 for(unsigned int i =0;i<wei.size();i++)
163 wei[i] = wei1[i];
164
165 E = obj.energyCalcu(Cg,polyGrad,wei);
166
167 if(iterCount > maxIter)
168 break;
169
170 G_pos.clear();
171 G_neg.clear();
172 temp.clear();
173 temp1.clear();
174 EXPsum.clear();
175 EXPterm.clear();
176 temp2.clear();
177 wei1.clear();
178 }
179
180 Mat Gray = Mat::zeros(img.size(),CV_32FC1);
181 obj.grayImContruct(wei, img, Gray);
182
183 Gray.convertTo(dst,CV_8UC1,255);
184
185 /////////////////////////////////// Contrast Boosting /////////////////////////////////
186
187 Mat lab = Mat(img.size(),CV_8UC3);
188 Mat color = Mat(img.size(),CV_8UC3);
189
190 cvtColor(I,lab,COLOR_BGR2Lab);
191
192 vector <Mat> lab_channel;
193 split(lab,lab_channel);
194
195 dst.copyTo(lab_channel[0]);
196
197 merge(lab_channel,lab);
198
199 cvtColor(lab,color_boost,COLOR_Lab2BGR);
200 }
201