Skip to content

Mcc add perf tests improve performance #3699

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

Merged
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
3 changes: 3 additions & 0 deletions modules/mcc/perf/perf_main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "perf_precomp.hpp"

CV_PERF_TEST_MAIN(mcc)
51 changes: 51 additions & 0 deletions modules/mcc/perf/perf_mcc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.

#include "perf_precomp.hpp"

namespace opencv_test
{
namespace
{

using namespace std;

PERF_TEST(CV_mcc_perf, detect) {
string path = cvtest::findDataFile("cv/mcc/mcc_ccm_test.jpg");
Mat img = imread(path, IMREAD_COLOR);
Ptr<CCheckerDetector> detector = CCheckerDetector::create();

// detect MCC24 board
TEST_CYCLE() {
ASSERT_TRUE(detector->process(img, MCC24, 1, false));
}
SANITY_CHECK_NOTHING();
}

PERF_TEST(CV_mcc_perf, infer) {
// read gold chartsRGB
string path = cvtest::findDataFile("cv/mcc/mcc_ccm_test.yml");
FileStorage fs(path, FileStorage::READ);
Mat chartsRGB;
FileNode node = fs["chartsRGB"];
node >> chartsRGB;
fs.release();

// compute CCM
ColorCorrectionModel model(chartsRGB.col(1).clone().reshape(3, chartsRGB.rows/3) / 255., COLORCHECKER_Macbeth);
model.run();

Mat img(1000, 4000, CV_8UC3);
randu(img, 0, 255);
img.convertTo(img, CV_64F, 1. / 255.);

TEST_CYCLE() {
model.infer(img);
}

SANITY_CHECK_NOTHING();
}

} // namespace
} // namespace opencv_test
14 changes: 14 additions & 0 deletions modules/mcc/perf/perf_precomp.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef __OPENCV_PERF_PRECOMP_HPP__
#define __OPENCV_PERF_PRECOMP_HPP__

#include "opencv2/ts.hpp"
#include "opencv2/mcc.hpp"

namespace opencv_test
{
using namespace cv::mcc;
using namespace cv::ccm;
using namespace perf;
}

#endif
7 changes: 3 additions & 4 deletions modules/mcc/src/ccm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,14 +289,13 @@ Mat ColorCorrectionModel::infer(const Mat& img, bool islinear)
CV_Error(Error::StsBadArg, "No CCM values!" );
}
Mat img_lin = (p->linear)->linearize(img);
Mat img_ccm(img_lin.size(), img_lin.type());
Mat ccm_ = p->ccm.reshape(0, p->shape / 3);
img_ccm = multiple(p->prepare(img_lin), ccm_);
Mat ccm = p->ccm.reshape(0, p->shape / 3);
Mat img_ccm = multiple(p->prepare(img_lin), ccm);
if (islinear == true)
{
return img_ccm;
}
return p->cs.fromL(img_ccm);
return p->cs.fromLFunc(img_ccm, img_lin);
}

void ColorCorrectionModel::Impl::getColor(CONST_COLOR constcolor)
Expand Down
23 changes: 12 additions & 11 deletions modules/mcc/src/checker_detector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,17 +539,18 @@ void CCheckerDetectorImpl::
// number of window sizes (scales) to apply adaptive thresholding
int nScales = (params->adaptiveThreshWinSizeMax - params->adaptiveThreshWinSizeMin) / params->adaptiveThreshWinSizeStep + 1;
thresholdImgs.create(nScales, 1, CV_8U);
std::vector<cv::Mat> _thresholdImgs;
for (int i = 0; i < nScales; i++)
{
int currScale = params->adaptiveThreshWinSizeMin + i * params->adaptiveThreshWinSizeStep;

cv::Mat tempThresholdImg;
cv::adaptiveThreshold(grayscaleImg, tempThresholdImg, 255, cv::ADAPTIVE_THRESH_MEAN_C,
cv::THRESH_BINARY_INV, currScale, params->adaptiveThreshConstant);

_thresholdImgs.push_back(tempThresholdImg);
}
std::vector<cv::Mat> _thresholdImgs(nScales);
parallel_for_(Range(0, nScales),[&](const Range& range) {
const int start = range.start;
const int end = range.end;
for (int i = start; i < end; i++) {
int currScale = params->adaptiveThreshWinSizeMin + i * params->adaptiveThreshWinSizeStep;
cv::Mat tempThresholdImg;
cv::adaptiveThreshold(grayscaleImg, tempThresholdImg, 255, ADAPTIVE_THRESH_MEAN_C,
THRESH_BINARY_INV, currScale, params->adaptiveThreshConstant);
_thresholdImgs[i] = tempThresholdImg;
}
});

thresholdImgs.assign(_thresholdImgs);
}
Expand Down
37 changes: 16 additions & 21 deletions modules/mcc/src/colorspace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ Operations RGBBase_::relation(const ColorSpace& other) const
}
if (linear)
{
return Operations({ Operation(fromL) });
return Operations({ Operation([this](Mat rgbl) -> Mat { return fromLFunc(rgbl); }) });
}
return Operations({ Operation(toL) });
return Operations({ Operation([this](Mat rgb) -> Mat { return toLFunc(rgb); })});
}

/* @brief Initial operations.
Expand Down Expand Up @@ -134,36 +134,32 @@ void RGBBase_::calM()
*/
void RGBBase_::calOperations()
{
// rgb -> rgbl
toL = [this](Mat rgb) -> Mat { return toLFunc(rgb); };

// rgbl -> rgb
fromL = [this](Mat rgbl) -> Mat { return fromLFunc(rgbl); };

if (linear)
{
to = Operations({ Operation(M_to.t()) });
from = Operations({ Operation(M_from.t()) });
}
else
{
to = Operations({ Operation(toL), Operation(M_to.t()) });
from = Operations({ Operation(M_from.t()), Operation(fromL) });
// rgb -> rgbl
to = Operations({ Operation([this](Mat rgb) -> Mat { return toLFunc(rgb); }), Operation(M_to.t()) });
// rgbl -> rgb
from = Operations({ Operation(M_from.t()), Operation([this](Mat rgbl) -> Mat { return fromLFunc(rgbl); }) });
}
}

Mat RGBBase_::toLFunc(Mat& /*rgb*/) { return Mat(); }
Mat RGBBase_::toLFunc(Mat& /*rgb*/) const { return Mat(); }

Mat RGBBase_::fromLFunc(Mat& /*rgbl*/) { return Mat(); }
Mat RGBBase_::fromLFunc(Mat& /*rgbl*/, Mat dst) const { return dst; }

/* @brief Base of Adobe RGB color space;
*/

Mat AdobeRGBBase_::toLFunc(Mat& rgb) { return gammaCorrection(rgb, gamma); }
Mat AdobeRGBBase_::toLFunc(Mat& rgb) const { return gammaCorrection(rgb, gamma); }

Mat AdobeRGBBase_::fromLFunc(Mat& rgbl)
Mat AdobeRGBBase_::fromLFunc(Mat& rgbl, Mat dst) const
{
return gammaCorrection(rgbl, 1. / gamma);
return gammaCorrection(rgbl, 1. / gamma, dst);
}

/* @brief Base of sRGB color space;
Expand All @@ -179,7 +175,7 @@ void sRGBBase_::calLinear()

/* @brief Used by toLFunc.
*/
double sRGBBase_::toLFuncEW(double& x)
double sRGBBase_::toLFuncEW(double& x) const
{
if (x > K0)
{
Expand All @@ -199,15 +195,15 @@ double sRGBBase_::toLFuncEW(double& x)
* @param rgb the input array, type of cv::Mat.
* @return the output array, type of cv::Mat.
*/
Mat sRGBBase_::toLFunc(Mat& rgb)
Mat sRGBBase_::toLFunc(Mat& rgb) const
{
return elementWise(rgb,
[this](double a_) -> double { return toLFuncEW(a_); });
}

/* @brief Used by fromLFunc.
*/
double sRGBBase_::fromLFuncEW(double& x)
double sRGBBase_::fromLFuncEW(const double& x) const
{
if (x > beta)
{
Expand All @@ -227,10 +223,9 @@ double sRGBBase_::fromLFuncEW(double& x)
* @param rgbl the input array, type of cv::Mat.
* @return the output array, type of cv::Mat.
*/
Mat sRGBBase_::fromLFunc(Mat& rgbl)
Mat sRGBBase_::fromLFunc(Mat& rgbl, Mat dst) const
{
return elementWise(rgbl,
[this](double a_) -> double { return fromLFuncEW(a_); });
return elementWise(rgbl, [this](double a_) -> double { return fromLFuncEW(a_); }, dst);
}

/* @brief sRGB color space.
Expand Down
21 changes: 9 additions & 12 deletions modules/mcc/src/colorspace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,6 @@ class RGBBase_ : public ColorSpace
double yg;
double xb;
double yb;
MatFunc toL;
MatFunc fromL;
Mat M_to;
Mat M_from;

Expand All @@ -108,6 +106,9 @@ class RGBBase_ : public ColorSpace
*/
void bind(RGBBase_& rgbl);

virtual Mat toLFunc(Mat& /*rgb*/) const;

virtual Mat fromLFunc(Mat& /*rgbl*/, Mat dst=Mat()) const;
private:
virtual void setParameter() {};

Expand All @@ -120,10 +121,6 @@ class RGBBase_ : public ColorSpace
virtual void calOperations();

virtual void calLinear() {};

virtual Mat toLFunc(Mat& /*rgb*/);

virtual Mat fromLFunc(Mat& /*rgbl*/);
};

/** @brief Base of Adobe RGB color space;
Expand All @@ -136,8 +133,8 @@ class AdobeRGBBase_ : public RGBBase_
double gamma;

private:
Mat toLFunc(Mat& rgb) CV_OVERRIDE;
Mat fromLFunc(Mat& rgbl) CV_OVERRIDE;
Mat toLFunc(Mat& rgb) const CV_OVERRIDE;
Mat fromLFunc(Mat& rgbl, Mat dst=Mat()) const CV_OVERRIDE;
};

/** @brief Base of sRGB color space;
Expand All @@ -160,23 +157,23 @@ class sRGBBase_ : public RGBBase_
virtual void calLinear() CV_OVERRIDE;
/** @brief Used by toLFunc.
*/
double toLFuncEW(double& x);
double toLFuncEW(double& x) const;

/** @brief Linearization.
@param rgb the input array, type of cv::Mat.
@return the output array, type of cv::Mat.
*/
Mat toLFunc(Mat& rgb) CV_OVERRIDE;
Mat toLFunc(Mat& rgb) const CV_OVERRIDE;

/** @brief Used by fromLFunc.
*/
double fromLFuncEW(double& x);
double fromLFuncEW(const double& x) const;

/** @brief Delinearization.
@param rgbl the input array, type of cv::Mat.
@return the output array, type of cv::Mat.
*/
Mat fromLFunc(Mat& rgbl) CV_OVERRIDE;
Mat fromLFunc(Mat& rgbl, Mat dst=Mat()) const CV_OVERRIDE;
};

/** @brief sRGB color space.
Expand Down
6 changes: 3 additions & 3 deletions modules/mcc/src/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@
namespace cv {
namespace ccm {

double gammaCorrection_(const double& element, const double& gamma)
inline double gammaCorrection_(const double& element, const double& gamma)
{
return (element >= 0 ? pow(element, gamma) : -pow((-element), gamma));
}

Mat gammaCorrection(const Mat& src, const double& gamma)
Mat gammaCorrection(const Mat& src, const double& gamma, Mat dst)
{
return elementWise(src, [gamma](double element) -> double { return gammaCorrection_(element, gamma); });
return elementWise(src, [gamma](double element) -> double { return gammaCorrection_(element, gamma); }, dst);
}

Mat maskCopyTo(const Mat& src, const Mat& mask)
Expand Down
23 changes: 20 additions & 3 deletions modules/mcc/src/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ double gammaCorrection_(const double& element, const double& gamma);
\f]
@param src the input array,type of Mat.
@param gamma a constant for gamma correction.
@param dst the output array, type of Mat.
*/
Mat gammaCorrection(const Mat& src, const double& gamma);
Mat gammaCorrection(const Mat& src, const double& gamma, Mat dst=Mat());

/** @brief maskCopyTo a function to delete unsatisfied elementwise.
@param src the input array, type of Mat.
Expand Down Expand Up @@ -77,10 +78,26 @@ Mat rgb2gray(const Mat& rgb);
@param lambda a for operation
*/
template <typename F>
Mat elementWise(const Mat& src, F&& lambda)
Mat elementWise(const Mat& src, F&& lambda, Mat dst=Mat())
{
Mat dst = src.clone();
if (dst.empty() || !dst.isContinuous() || dst.total() != src.total() || dst.type() != src.type())
dst = Mat(src.rows, src.cols, src.type());
const int channel = src.channels();
if (src.isContinuous()) {
const int num_elements = (int)src.total()*channel;
const double *psrc = (double*)src.data;
double *pdst = (double*)dst.data;
const int batch = getNumThreads() > 1 ? 128 : num_elements;
const int N = (num_elements / batch) + ((num_elements % batch) > 0);
parallel_for_(Range(0, N),[&](const Range& range) {
const int start = range.start * batch;
const int end = std::min(range.end*batch, num_elements);
for (int i = start; i < end; i++) {
pdst[i] = lambda(psrc[i]);
}
});
return dst;
}
switch (channel)
{
case 1:
Expand Down