Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ccm pr #32

Merged
merged 3 commits into from
Nov 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 42 additions & 45 deletions modules/mcc/include/opencv2/mcc/ccm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ C_{sl}=f(C_s)
\f]
In practice, \f$n\le3\f$ is used to prevent overfitting.

There are many variants of polynomial fitting, the difference lies in the way of generating $f(x)$.
There are many variants of polynomial fitting, the difference lies in the way of generating \f$f(x)\f$.
It is usually necessary to use linearized reference colors and corresponding detected colors to calculate the polynomial parameters.
However, not all colors can participate in the calculation. The saturation detected colors needs to be removed. See the algorithm introduction document for details.

Expand Down Expand Up @@ -288,7 +288,7 @@ For gamma correction formula, we take the logarithm:
\f[
ln(C_{sl})={\gamma}ln(C_s),\qquad C_s\ge0\
\f]
It can be seen that there is a linear relationship between \f$ln(C_s)\f$ and \f$ln(C_{sl})\f$. It can be considered that the formula is an approximation of a polynomial relationship, that is, there exists a polynomial $f$, which makes[2]:
It can be seen that there is a linear relationship between \f$ln(C_s)\f$ and \f$ln(C_{sl})\f$. It can be considered that the formula is an approximation of a polynomial relationship, that is, there exists a polynomial \f$f\f$, which makes[2]:
\f[
ln(C_{sl})=f(ln(C_s)), \qquad C_s>0\\
C_{sl}=0, \qquad C_s=0
Expand All @@ -302,8 +302,8 @@ r=polyfit(ln(R_s),ln(R_{dl}))\\
g=polyfit(ln(G_s),ln(G_{dl}))\\
b=polyfit(ln(B_s),ln(B_{dl}))\\
\f]
Note that the parameter of $ln$ cannot be 0.
Therefore, we need to delete the channels whose values are 0 from $R_s$ and $R_{dl}$, $G_s$ and $G_{dl}$, $B_s$ and $B_{dl}$.
Note that the parameter of \f$ln(*) \f$ cannot be 0.
Therefore, we need to delete the channels whose values are 0 from \f$R_s \f$ and \f$R_{dl} \f$, \f$G_s\f$ and \f$G_{dl}\f$, \f$B_s\f$ and \f$B_{dl}\f$.

Therefore:

Expand Down Expand Up @@ -363,9 +363,9 @@ class CV_EXPORTS_W ColorCorrectionModel
/** @brief Color Correction Model

Supported list of color cards:
- @ref COLORCHECKER_Macbeth (Macbeth ColorChecker)
- @ref COLORCHECKER_Vinyl (DKK ColorChecker)
- @ref COLORCHECKER_DigitalSG (DigitalSG ColorChecker with 140 squares)
- @ref COLORCHECKER_Macbeth, the Macbeth ColorChecker
- @ref COLORCHECKER_Vinyl, the DKK ColorChecker
- @ref COLORCHECKER_DigitalSG, the DigitalSG ColorChecker with 140 squares

@param src detected colors of ColorChecker patches;\n
the color type is RGB not BGR, and the color values are in [0, 1];
Expand All @@ -376,37 +376,34 @@ class CV_EXPORTS_W ColorCorrectionModel
/** @brief Color Correction Model
@param src detected colors of ColorChecker patches;\n
the color type is RGB not BGR, and the color values are in [0, 1];
@param colors the reference color values,the color values are in [0, 1].\n
@param colors the reference color values, the color values are in [0, 1].\n
@param ref_cs the corresponding color space
NOTICE: For the list of color spaces supported, see the notes above;\n
If the color type is some RGB, the format is RGB not BGR;\n
*/
CV_WRAP ColorCorrectionModel(const Mat& src, Mat colors, COLOR_SPACE ref_cs);

/** @brief Color Correction Model
@param src detected colors of ColorChecker patches;\n
the color type is RGB not BGR, and the color values are in [0, 1];
@param colors the reference color values,the color values are in [0, 1].
@param colors the reference color values, the color values are in [0, 1].
@param ref_cs the corresponding color space
NOTICE: For the list of color spaces supported, see the notes above;\n
If the color type is some RGB, the format is RGB not BGR;
@param colored mask of colored color
*/
CV_WRAP ColorCorrectionModel(const Mat& src, Mat colors, COLOR_SPACE ref_cs, Mat colored);

/** @brief set ColorSpace

@note It should be some RGB color space;
Supported list of color cards:
- @ref COLOR_SPACE_sRGB,
- @ref COLOR_SPACE_AdobeRGB,
- @ref COLOR_SPACE_WideGamutRGB,
- @ref COLOR_SPACE_ProPhotoRGB,
- @ref COLOR_SPACE_DCI_P3_RGB,
- @ref COLOR_SPACE_AppleRGB,
- @ref COLOR_SPACE_REC_709_RGB,
- @ref COLOR_SPACE_REC_2020_RGB,
- @param cs the absolute color space that detected colors convert to;\n
- @ref COLOR_SPACE_sRGB
- @ref COLOR_SPACE_AdobeRGB
- @ref COLOR_SPACE_WideGamutRGB
- @ref COLOR_SPACE_ProPhotoRGB
- @ref COLOR_SPACE_DCI_P3_RGB
- @ref COLOR_SPACE_AppleRGB
- @ref COLOR_SPACE_REC_709_RGB
- @ref COLOR_SPACE_REC_2020_RGB
@param cs the absolute color space that detected colors convert to;\n
default: @ref COLOR_SPACE_sRGB
*/
CV_WRAP void setColorSpace(COLOR_SPACE cs);
Expand All @@ -424,8 +421,6 @@ class CV_EXPORTS_W ColorCorrectionModel
CV_WRAP void setDistance(DISTANCE_TYPE distance);

/** @brief set Linear

Supported list:
@param linear_type the method of linearization;\n
default: @ref LINEARIZATION_GAMMA
*/
Expand All @@ -435,47 +430,49 @@ class CV_EXPORTS_W ColorCorrectionModel

@note only valid when linear is set to "gamma";\n

@param gamma the gamma value of gamma correction;
default: 2.2;\n
@param gamma the gamma value of gamma correction;\n
default: 2.2;
*/
CV_WRAP void setLinearGamma(double gamma);
CV_WRAP void setLinearGamma(const double& gamma);

/** @brief set degree
@note only valid when linear is set to
- @ref LINEARIZATION_COLORPOLYFIT
- @ref LINEARIZATION_GRAYPOLYFIT
- @ref LINEARIZATION_COLORLOGPOLYFIT
- @ref LINEARIZATION_GRAYLOGPOLYFIT

@param deg the degree of linearization polynomial;\n
NOTICE: only valid when linear is set to
@ref LINEARIZATION_COLORPOLYFIT
@ref LINEARIZATION_GRAYPOLYFIT
@ref LINEARIZATION_COLORLOGPOLYFIT
@ref LINEARIZATION_GRAYLOGPOLYFIT
default: 3
default: 3

*/
CV_WRAP void setLinearDegree(int deg);
CV_WRAP void setLinearDegree(const int& deg);

/** @brief set SaturatedThreshold
/** @brief set SaturatedThreshold.
The colors in the closed interval [lower, upper] are reserved to participate
in the calculation of the loss function and initialization parameters
@param lower the lower threshold to determine saturation;\n
default: 0;
@param upper the upper threshold to determine saturation;
NOTICE: it is a tuple of [lower, upper];
The colors in the closed interval [lower, upper] are reserved to participate
in the calculation of the loss function and initialization parameters\n
@param upper the upper threshold to determine saturation;\n
default: 0
*/
CV_WRAP void setSaturatedThreshold(double lower, double upper);
CV_WRAP void setSaturatedThreshold(const double& lower, const double& upper);

/** @brief set WeightsList
@param weights_list the list of weight of each color;\n
default: empty array
*/
CV_WRAP void setWeightsList(Mat weights_list);
CV_WRAP void setWeightsList(const Mat& weights_list);

/** @brief set WeightCoeff
@param weights_coeff the exponent number of L* component of the reference color in CIE Lab color space;\n
default: 0
*/
CV_WRAP void setWeightCoeff(double weights_coeff);
CV_WRAP void setWeightCoeff(const double& weights_coeff);

/** @brief set InitialMethod
@param initial_method_type the method of calculating CCM initial value;\n
default: INITIAL_METHOD_LEAST_SQUARE
*/
CV_WRAP void setInitialMethod(INITIAL_METHOD_TYPE initial_method_type);

Expand All @@ -484,14 +481,14 @@ class CV_EXPORTS_W ColorCorrectionModel
Terminal criteria to the algorithm;\n
default: 5000;
*/
CV_WRAP void setMaxCount(int max_count);
CV_WRAP void setMaxCount(const int& max_count);

/** @brief set Epsilon
@param epsilon used in MinProblemSolver-DownhillSolver;\n
Terminal criteria to the algorithm;\n
default: 1e-4;
*/
CV_WRAP void setEpsilon(double epsilon);
CV_WRAP void setEpsilon(const double& epsilon);

/** @brief make color correction */
CV_WRAP void run();
Expand All @@ -500,8 +497,8 @@ class CV_EXPORTS_W ColorCorrectionModel
CV_WRAP double getLoss() const;
CV_WRAP Mat get_src_rgbl() const;
CV_WRAP Mat get_dst_rgbl() const;
CV_WRAP Mat get_mask() const;
CV_WRAP Mat get_weights() const;
CV_WRAP Mat getMask() const;
CV_WRAP Mat getWeights() const;

/** @brief Infer using fitting ccm.
@param img the input image.
Expand Down
2 changes: 1 addition & 1 deletion modules/mcc/samples/color_correction_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ int main(int argc, char *argv[])
Ptr<CCheckerDraw> cdraw = CCheckerDraw::create(checker);
cdraw->draw(image);
Mat chartsRGB = checker->getChartsRGB();
Mat src = chartsRGB.col(1).clone().reshape(3, 18);
Mat src = chartsRGB.col(1).clone().reshape(3, chartsRGB.rows/3);
src /= 255.0;
//! [create]

Expand Down
44 changes: 22 additions & 22 deletions modules/mcc/src/ccm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class ColorCorrectionModel::Impl
@param weights_coeff type of double.
@param saturate_mask the input array, type of cv::Mat.
*/
void calWeightsMasks(Mat weights_list, double weights_coeff, Mat saturate_mask);
void calWeightsMasks(const Mat& weights_list, double weights_coeff, Mat saturate_mask);

/** @brief Fitting nonlinear - optimization initial value by white balance.
@return the output array, type of Mat
Expand All @@ -99,10 +99,10 @@ class ColorCorrectionModel::Impl
*/
void fitting(void);

void get_color(Mat& img_, bool islinear = false);
void get_color(CONST_COLOR constcolor);
void get_color(Mat colors_, COLOR_SPACE cs_, Mat colored_);
void get_color(Mat colors_, COLOR_SPACE ref_cs_);
void getColor(Mat& img_, bool islinear = false);
void getColor(CONST_COLOR constcolor);
void getColor(Mat colors_, COLOR_SPACE cs_, Mat colored_);
void getColor(Mat colors_, COLOR_SPACE ref_cs_);

/** @brief Loss function base on cv::MinProblemSolver::Function.
see details in https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/optim.hpp
Expand Down Expand Up @@ -174,7 +174,7 @@ Mat ColorCorrectionModel::Impl::prepare(const Mat& inp)
}
}

void ColorCorrectionModel::Impl::calWeightsMasks(Mat weights_list_, double weights_coeff_, Mat saturate_mask)
void ColorCorrectionModel::Impl::calWeightsMasks(const Mat& weights_list_, double weights_coeff_, Mat saturate_mask)
{
// weights
if (!weights_list_.empty())
Expand Down Expand Up @@ -299,35 +299,35 @@ Mat ColorCorrectionModel::infer(const Mat& img, bool islinear)
return p->cs.fromL(img_ccm);
}

void ColorCorrectionModel::Impl::get_color(CONST_COLOR constcolor)
void ColorCorrectionModel::Impl::getColor(CONST_COLOR constcolor)
{
dst = (GetColor::get_color(constcolor));
dst = (GetColor::getColor(constcolor));
}
void ColorCorrectionModel::Impl::get_color(Mat colors_, COLOR_SPACE ref_cs_)
void ColorCorrectionModel::Impl::getColor(Mat colors_, COLOR_SPACE ref_cs_)
{
dst.reset(new Color(colors_, *GetCS::getInstance().get_cs(ref_cs_)));
}
void ColorCorrectionModel::Impl::get_color(Mat colors_, COLOR_SPACE cs_, Mat colored_)
void ColorCorrectionModel::Impl::getColor(Mat colors_, COLOR_SPACE cs_, Mat colored_)
{
dst.reset(new Color(colors_, *GetCS::getInstance().get_cs(cs_), colored_));
}
ColorCorrectionModel::ColorCorrectionModel(const Mat& src_, CONST_COLOR constcolor)
: p(std::make_shared<Impl>())
{
p->src = src_;
p->get_color(constcolor);
p->getColor(constcolor);
}
ColorCorrectionModel::ColorCorrectionModel(const Mat& src_, Mat colors_, COLOR_SPACE ref_cs_)
: p(std::make_shared<Impl>())
{
p->src = src_;
p->get_color(colors_, ref_cs_);
p->getColor(colors_, ref_cs_);
}
ColorCorrectionModel::ColorCorrectionModel(const Mat& src_, Mat colors_, COLOR_SPACE cs_, Mat colored_)
: p(std::make_shared<Impl>())
{
p->src = src_;
p->get_color(colors_, cs_, colored_);
p->getColor(colors_, cs_, colored_);
}

void ColorCorrectionModel::setColorSpace(COLOR_SPACE cs_)
Expand All @@ -346,35 +346,35 @@ void ColorCorrectionModel::setLinear(LINEAR_TYPE linear_type)
{
p->linear_type = linear_type;
}
void ColorCorrectionModel::setLinearGamma(double gamma)
void ColorCorrectionModel::setLinearGamma(const double& gamma)
{
p->gamma = gamma;
}
void ColorCorrectionModel::setLinearDegree(int deg)
void ColorCorrectionModel::setLinearDegree(const int& deg)
{
p->deg = deg;
}
void ColorCorrectionModel::setSaturatedThreshold(double lower, double upper)
void ColorCorrectionModel::setSaturatedThreshold(const double& lower, const double& upper)
{ //std::vector<double> saturated_threshold
p->saturated_threshold = { lower, upper };
}
void ColorCorrectionModel::setWeightsList(Mat weights_list)
void ColorCorrectionModel::setWeightsList(const Mat& weights_list)
{
p->weights_list = weights_list;
}
void ColorCorrectionModel::setWeightCoeff(double weights_coeff)
void ColorCorrectionModel::setWeightCoeff(const double& weights_coeff)
{
p->weights_coeff = weights_coeff;
}
void ColorCorrectionModel::setInitialMethod(INITIAL_METHOD_TYPE initial_method_type)
{
p->initial_method_type = initial_method_type;
}
void ColorCorrectionModel::setMaxCount(int max_count_)
void ColorCorrectionModel::setMaxCount(const int& max_count_)
{
p->max_count = max_count_;
}
void ColorCorrectionModel::setEpsilon(double epsilon_)
void ColorCorrectionModel::setEpsilon(const double& epsilon_)
{
p->epsilon = epsilon_;
}
Expand Down Expand Up @@ -428,10 +428,10 @@ Mat ColorCorrectionModel::get_src_rgbl() const{
Mat ColorCorrectionModel::get_dst_rgbl() const{
return p->dst_rgbl;
}
Mat ColorCorrectionModel::get_mask() const{
Mat ColorCorrectionModel::getMask() const{
return p->mask;
}
Mat ColorCorrectionModel::get_weights() const{
Mat ColorCorrectionModel::getWeights() const{
return p->weights;
}
}
Expand Down
16 changes: 8 additions & 8 deletions modules/mcc/src/color.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ Color Color::operator[](Mat mask)
return Color(maskCopyTo(colors, mask), cs);
}

Mat GetColor::get_ColorChecker(const double* checker, int row)
Mat GetColor::getColorChecker(const double* checker, int row)
{
Mat res(row, 1, CV_64FC3);
for (int i = 0; i < row; ++i)
Expand All @@ -158,7 +158,7 @@ Mat GetColor::get_ColorChecker(const double* checker, int row)
return res;
}

Mat GetColor::get_ColorChecker_MASK(const uchar* checker, int row)
Mat GetColor::getColorCheckerMASK(const uchar* checker, int row)
{
Mat res(row, 1, CV_8U);
for (int i = 0; i < row; ++i)
Expand All @@ -168,7 +168,7 @@ Mat GetColor::get_ColorChecker_MASK(const uchar* checker, int row)
return res;
}

std::shared_ptr<Color> GetColor::get_color(CONST_COLOR const_color)
std::shared_ptr<Color> GetColor::getColor(CONST_COLOR const_color)
{

/** @brief Data is from https://www.imatest.com/wp-content/uploads/2011/11/Lab-data-Iluminate-D65-D50-spectro.xls
Expand Down Expand Up @@ -370,23 +370,23 @@ std::shared_ptr<Color> GetColor::get_color(CONST_COLOR const_color)

case cv::ccm::COLORCHECKER_Macbeth:
{
Mat ColorChecker2005_LAB_D50_2_ = GetColor::get_ColorChecker(*ColorChecker2005_LAB_D50_2, 24);
Mat ColorChecker2005_COLORED_MASK_ = GetColor::get_ColorChecker_MASK(ColorChecker2005_COLORED_MASK, 24);
Mat ColorChecker2005_LAB_D50_2_ = GetColor::getColorChecker(*ColorChecker2005_LAB_D50_2, 24);
Mat ColorChecker2005_COLORED_MASK_ = GetColor::getColorCheckerMASK(ColorChecker2005_COLORED_MASK, 24);
std::shared_ptr<Color> Macbeth_D50_2 = std::make_shared<Color>(ColorChecker2005_LAB_D50_2_, COLOR_SPACE_Lab_D50_2, ColorChecker2005_COLORED_MASK_);
return Macbeth_D50_2;
}

case cv::ccm::COLORCHECKER_Vinyl:
{
Mat Vinyl_LAB_D50_2__ = GetColor::get_ColorChecker(*Vinyl_LAB_D50_2, 18);
Mat Vinyl_COLORED_MASK__ = GetColor::get_ColorChecker_MASK(Vinyl_COLORED_MASK, 18);
Mat Vinyl_LAB_D50_2__ = GetColor::getColorChecker(*Vinyl_LAB_D50_2, 18);
Mat Vinyl_COLORED_MASK__ = GetColor::getColorCheckerMASK(Vinyl_COLORED_MASK, 18);
std::shared_ptr<Color> Vinyl_D50_2 = std::make_shared<Color>(Vinyl_LAB_D50_2__, COLOR_SPACE_Lab_D50_2, Vinyl_COLORED_MASK__);
return Vinyl_D50_2;
}

case cv::ccm::COLORCHECKER_DigitalSG:
{
Mat DigitalSG_LAB_D50_2__ = GetColor::get_ColorChecker(*DigitalSG_LAB_D50_2, 140);
Mat DigitalSG_LAB_D50_2__ = GetColor::getColorChecker(*DigitalSG_LAB_D50_2, 140);
std::shared_ptr<Color> DigitalSG_D50_2 = std::make_shared<Color>(DigitalSG_LAB_D50_2__, COLOR_SPACE_Lab_D50_2);
return DigitalSG_D50_2;
}
Expand Down
Loading