#include
#include
void zscoreNormalize(const cv::Mat& src, cv::Mat& dst)
{
cv::Mat mu(src.size(), src.type());
cv::GaussianBlur(src, mu, cv::Size(7, 7), 1.166);
cv::Mat mu_sq;
cv::multiply(mu, mu, mu_sq);
cv::Mat sigma(src.size(), src.type());
cv::multiply(src, src, sigma);
cv::GaussianBlur(sigma, sigma, cv::Size(7, 7), 1.166);
cv::subtract(sigma, mu_sq, sigma);
cv::pow(sigma, double(0.5), sigma);
cv::add(sigma, cv::Scalar(1.0 / 255), sigma);
cv::subtract(src, mu, dst);
cv::divide(dst, sigma, dst);
}
void zscoreNormalize_v2(const cv::Mat& src, cv::Mat& dst)
{
cv::Mat mu(src.size(), src.type());
cv::GaussianBlur(src, mu, cv::Size(7, 7), 1.166);
cv::subtract(src, mu, mu);
cv::Mat sigma(src.size(), src.type());
cv::multiply(mu, mu, sigma);
cv::GaussianBlur(sigma, sigma, cv::Size(7, 7), 1.166);
cv::pow(sigma, 0.5, sigma);
cv::add(sigma, cv::Scalar(1.0 / 255), sigma);
cv::divide(mu, sigma, dst);
}
template<typename Func>
double bench_(const Func& func, unsigned int iterNum = 1)
{
auto t1 = cv::getTickCount();
while (iterNum--) func();
auto t2 = cv::getTickCount();
return 1000.0 * (t2 - t1) / cv::getTickFrequency();
}
void show(const std::string& winname, const cv::Mat& src)
{
cv::Mat normalized;
cv::normalize(src, normalized, 255, 0, CV_MINMAX, CV_8U);
cv::bitwise_not(normalized, normalized);
cv::imshow(winname, normalized);
}
int main()
{
cv::Mat src = cv::imread("lena.jpg", 0);
cv::Mat src64f;
src.convertTo(src64f, CV_64F, 1.0 / 255);
cv::Mat dst64f(src.size(), src.type());
int iterNum = 10;
printf("zscoreNormalize %f ms\n", bench_([&](){zscoreNormalize(src64f, dst64f); }, iterNum));
show("zscoreNormalize", dst64f);
printf("zscoreNormalize_v2 %f ms\n", bench_([&](){zscoreNormalize_v2(src64f, dst64f); }, iterNum));
show("zscoreNormalize_v2", dst64f);
cv::waitKey();
return 0;
}