Merge branch 'master' of https://github.com/Itseez/opencv
After Width: | Height: | Size: 84 KiB |
@ -0,0 +1,61 @@ |
||||
#ifndef FISHEYE_INTERNAL_H |
||||
#define FISHEYE_INTERNAL_H |
||||
#include "precomp.hpp" |
||||
|
||||
namespace cv { namespace internal { |
||||
|
||||
struct CV_EXPORTS IntrinsicParams |
||||
{ |
||||
Vec2d f; |
||||
Vec2d c; |
||||
Vec4d k; |
||||
double alpha; |
||||
std::vector<int> isEstimate; |
||||
|
||||
IntrinsicParams(); |
||||
IntrinsicParams(Vec2d f, Vec2d c, Vec4d k, double alpha = 0); |
||||
IntrinsicParams operator+(const Mat& a); |
||||
IntrinsicParams& operator =(const Mat& a); |
||||
void Init(const cv::Vec2d& f, const cv::Vec2d& c, const cv::Vec4d& k = Vec4d(0,0,0,0), const double& alpha = 0); |
||||
}; |
||||
|
||||
void projectPoints(cv::InputArray objectPoints, cv::OutputArray imagePoints, |
||||
cv::InputArray _rvec,cv::InputArray _tvec, |
||||
const IntrinsicParams& param, cv::OutputArray jacobian); |
||||
|
||||
void ComputeExtrinsicRefine(const Mat& imagePoints, const Mat& objectPoints, Mat& rvec, |
||||
Mat& tvec, Mat& J, const int MaxIter, |
||||
const IntrinsicParams& param, const double thresh_cond); |
||||
CV_EXPORTS Mat ComputeHomography(Mat m, Mat M); |
||||
|
||||
CV_EXPORTS Mat NormalizePixels(const Mat& imagePoints, const IntrinsicParams& param); |
||||
|
||||
void InitExtrinsics(const Mat& _imagePoints, const Mat& _objectPoints, const IntrinsicParams& param, Mat& omckk, Mat& Tckk); |
||||
|
||||
void CalibrateExtrinsics(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, |
||||
const IntrinsicParams& param, const int check_cond, |
||||
const double thresh_cond, InputOutputArray omc, InputOutputArray Tc); |
||||
|
||||
void ComputeJacobians(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, |
||||
const IntrinsicParams& param, InputArray omc, InputArray Tc, |
||||
const int& check_cond, const double& thresh_cond, Mat& JJ2_inv, Mat& ex3); |
||||
|
||||
CV_EXPORTS void EstimateUncertainties(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, |
||||
const IntrinsicParams& params, InputArray omc, InputArray Tc, |
||||
IntrinsicParams& errors, Vec2d& std_err, double thresh_cond, int check_cond, double& rms); |
||||
|
||||
void dAB(cv::InputArray A, InputArray B, OutputArray dABdA, OutputArray dABdB); |
||||
|
||||
void JRodriguesMatlab(const Mat& src, Mat& dst); |
||||
|
||||
void compose_motion(InputArray _om1, InputArray _T1, InputArray _om2, InputArray _T2, |
||||
Mat& om3, Mat& T3, Mat& dom3dom1, Mat& dom3dT1, Mat& dom3dom2, |
||||
Mat& dom3dT2, Mat& dT3dom1, Mat& dT3dT1, Mat& dT3dom2, Mat& dT3dT2); |
||||
|
||||
double median(const Mat& row); |
||||
|
||||
Vec3d median3d(InputArray m); |
||||
|
||||
}} |
||||
|
||||
#endif |
@ -0,0 +1,613 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp" |
||||
#include <opencv2/ts/cuda_test.hpp> |
||||
#include "../src/fisheye.hpp" |
||||
|
||||
class fisheyeTest : public ::testing::Test { |
||||
|
||||
protected: |
||||
const static cv::Size imageSize; |
||||
const static cv::Matx33d K; |
||||
const static cv::Vec4d D; |
||||
const static cv::Matx33d R; |
||||
const static cv::Vec3d T; |
||||
std::string datasets_repository_path; |
||||
|
||||
virtual void SetUp() { |
||||
datasets_repository_path = combine(cvtest::TS::ptr()->get_data_path(), "cv/cameracalibration/fisheye"); |
||||
} |
||||
|
||||
protected: |
||||
std::string combine(const std::string& _item1, const std::string& _item2); |
||||
cv::Mat mergeRectification(const cv::Mat& l, const cv::Mat& r); |
||||
}; |
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// TESTS::
|
||||
|
||||
TEST_F(fisheyeTest, projectPoints) |
||||
{ |
||||
double cols = this->imageSize.width, |
||||
rows = this->imageSize.height; |
||||
|
||||
const int N = 20; |
||||
cv::Mat distorted0(1, N*N, CV_64FC2), undist1, undist2, distorted1, distorted2; |
||||
undist2.create(distorted0.size(), CV_MAKETYPE(distorted0.depth(), 3)); |
||||
cv::Vec2d* pts = distorted0.ptr<cv::Vec2d>(); |
||||
|
||||
cv::Vec2d c(this->K(0, 2), this->K(1, 2)); |
||||
for(int y = 0, k = 0; y < N; ++y) |
||||
for(int x = 0; x < N; ++x) |
||||
{ |
||||
cv::Vec2d point(x*cols/(N-1.f), y*rows/(N-1.f)); |
||||
pts[k++] = (point - c) * 0.85 + c; |
||||
} |
||||
|
||||
cv::fisheye::undistortPoints(distorted0, undist1, this->K, this->D); |
||||
|
||||
cv::Vec2d* u1 = undist1.ptr<cv::Vec2d>(); |
||||
cv::Vec3d* u2 = undist2.ptr<cv::Vec3d>(); |
||||
for(int i = 0; i < (int)distorted0.total(); ++i) |
||||
u2[i] = cv::Vec3d(u1[i][0], u1[i][1], 1.0); |
||||
|
||||
cv::fisheye::distortPoints(undist1, distorted1, this->K, this->D); |
||||
cv::fisheye::projectPoints(undist2, distorted2, cv::Vec3d::all(0), cv::Vec3d::all(0), this->K, this->D); |
||||
|
||||
EXPECT_MAT_NEAR(distorted0, distorted1, 1e-10); |
||||
EXPECT_MAT_NEAR(distorted0, distorted2, 1e-10); |
||||
} |
||||
|
||||
TEST_F(fisheyeTest, DISABLED_undistortImage) |
||||
{ |
||||
cv::Matx33d K = this->K; |
||||
cv::Mat D = cv::Mat(this->D); |
||||
std::string file = combine(datasets_repository_path, "/calib-3_stereo_from_JY/left/stereo_pair_014.jpg"); |
||||
cv::Matx33d newK = K; |
||||
cv::Mat distorted = cv::imread(file), undistorted; |
||||
{ |
||||
newK(0, 0) = 100; |
||||
newK(1, 1) = 100; |
||||
cv::fisheye::undistortImage(distorted, undistorted, K, D, newK); |
||||
cv::Mat correct = cv::imread(combine(datasets_repository_path, "new_f_100.png")); |
||||
if (correct.empty()) |
||||
CV_Assert(cv::imwrite(combine(datasets_repository_path, "new_f_100.png"), undistorted)); |
||||
else |
||||
EXPECT_MAT_NEAR(correct, undistorted, 1e-10); |
||||
} |
||||
{ |
||||
double balance = 1.0; |
||||
cv::fisheye::estimateNewCameraMatrixForUndistortRectify(K, D, distorted.size(), cv::noArray(), newK, balance); |
||||
cv::fisheye::undistortImage(distorted, undistorted, K, D, newK); |
||||
cv::Mat correct = cv::imread(combine(datasets_repository_path, "balance_1.0.png")); |
||||
if (correct.empty()) |
||||
CV_Assert(cv::imwrite(combine(datasets_repository_path, "balance_1.0.png"), undistorted)); |
||||
else |
||||
EXPECT_MAT_NEAR(correct, undistorted, 1e-10); |
||||
} |
||||
|
||||
{ |
||||
double balance = 0.0; |
||||
cv::fisheye::estimateNewCameraMatrixForUndistortRectify(K, D, distorted.size(), cv::noArray(), newK, balance); |
||||
cv::fisheye::undistortImage(distorted, undistorted, K, D, newK); |
||||
cv::Mat correct = cv::imread(combine(datasets_repository_path, "balance_0.0.png")); |
||||
if (correct.empty()) |
||||
CV_Assert(cv::imwrite(combine(datasets_repository_path, "balance_0.0.png"), undistorted)); |
||||
else |
||||
EXPECT_MAT_NEAR(correct, undistorted, 1e-10); |
||||
} |
||||
} |
||||
|
||||
TEST_F(fisheyeTest, jacobians) |
||||
{ |
||||
int n = 10; |
||||
cv::Mat X(1, n, CV_64FC3); |
||||
cv::Mat om(3, 1, CV_64F), T(3, 1, CV_64F); |
||||
cv::Mat f(2, 1, CV_64F), c(2, 1, CV_64F); |
||||
cv::Mat k(4, 1, CV_64F); |
||||
double alpha; |
||||
|
||||
cv::RNG r; |
||||
|
||||
r.fill(X, cv::RNG::NORMAL, 2, 1); |
||||
X = cv::abs(X) * 10; |
||||
|
||||
r.fill(om, cv::RNG::NORMAL, 0, 1); |
||||
om = cv::abs(om); |
||||
|
||||
r.fill(T, cv::RNG::NORMAL, 0, 1); |
||||
T = cv::abs(T); T.at<double>(2) = 4; T *= 10; |
||||
|
||||
r.fill(f, cv::RNG::NORMAL, 0, 1); |
||||
f = cv::abs(f) * 1000; |
||||
|
||||
r.fill(c, cv::RNG::NORMAL, 0, 1); |
||||
c = cv::abs(c) * 1000; |
||||
|
||||
r.fill(k, cv::RNG::NORMAL, 0, 1); |
||||
k*= 0.5; |
||||
|
||||
alpha = 0.01*r.gaussian(1); |
||||
|
||||
cv::Mat x1, x2, xpred; |
||||
cv::Matx33d K(f.at<double>(0), alpha * f.at<double>(0), c.at<double>(0), |
||||
0, f.at<double>(1), c.at<double>(1), |
||||
0, 0, 1); |
||||
|
||||
cv::Mat jacobians; |
||||
cv::fisheye::projectPoints(X, x1, om, T, K, k, alpha, jacobians); |
||||
|
||||
//test on T:
|
||||
cv::Mat dT(3, 1, CV_64FC1); |
||||
r.fill(dT, cv::RNG::NORMAL, 0, 1); |
||||
dT *= 1e-9*cv::norm(T); |
||||
cv::Mat T2 = T + dT; |
||||
cv::fisheye::projectPoints(X, x2, om, T2, K, k, alpha, cv::noArray()); |
||||
xpred = x1 + cv::Mat(jacobians.colRange(11,14) * dT).reshape(2, 1); |
||||
CV_Assert (cv::norm(x2 - xpred) < 1e-10); |
||||
|
||||
//test on om:
|
||||
cv::Mat dom(3, 1, CV_64FC1); |
||||
r.fill(dom, cv::RNG::NORMAL, 0, 1); |
||||
dom *= 1e-9*cv::norm(om); |
||||
cv::Mat om2 = om + dom; |
||||
cv::fisheye::projectPoints(X, x2, om2, T, K, k, alpha, cv::noArray()); |
||||
xpred = x1 + cv::Mat(jacobians.colRange(8,11) * dom).reshape(2, 1); |
||||
CV_Assert (cv::norm(x2 - xpred) < 1e-10); |
||||
|
||||
//test on f:
|
||||
cv::Mat df(2, 1, CV_64FC1); |
||||
r.fill(df, cv::RNG::NORMAL, 0, 1); |
||||
df *= 1e-9*cv::norm(f); |
||||
cv::Matx33d K2 = K + cv::Matx33d(df.at<double>(0), df.at<double>(0) * alpha, 0, 0, df.at<double>(1), 0, 0, 0, 0); |
||||
cv::fisheye::projectPoints(X, x2, om, T, K2, k, alpha, cv::noArray()); |
||||
xpred = x1 + cv::Mat(jacobians.colRange(0,2) * df).reshape(2, 1); |
||||
CV_Assert (cv::norm(x2 - xpred) < 1e-10); |
||||
|
||||
//test on c:
|
||||
cv::Mat dc(2, 1, CV_64FC1); |
||||
r.fill(dc, cv::RNG::NORMAL, 0, 1); |
||||
dc *= 1e-9*cv::norm(c); |
||||
K2 = K + cv::Matx33d(0, 0, dc.at<double>(0), 0, 0, dc.at<double>(1), 0, 0, 0); |
||||
cv::fisheye::projectPoints(X, x2, om, T, K2, k, alpha, cv::noArray()); |
||||
xpred = x1 + cv::Mat(jacobians.colRange(2,4) * dc).reshape(2, 1); |
||||
CV_Assert (cv::norm(x2 - xpred) < 1e-10); |
||||
|
||||
//test on k:
|
||||
cv::Mat dk(4, 1, CV_64FC1); |
||||
r.fill(dk, cv::RNG::NORMAL, 0, 1); |
||||
dk *= 1e-9*cv::norm(k); |
||||
cv::Mat k2 = k + dk; |
||||
cv::fisheye::projectPoints(X, x2, om, T, K, k2, alpha, cv::noArray()); |
||||
xpred = x1 + cv::Mat(jacobians.colRange(4,8) * dk).reshape(2, 1); |
||||
CV_Assert (cv::norm(x2 - xpred) < 1e-10); |
||||
|
||||
//test on alpha:
|
||||
cv::Mat dalpha(1, 1, CV_64FC1); |
||||
r.fill(dalpha, cv::RNG::NORMAL, 0, 1); |
||||
dalpha *= 1e-9*cv::norm(f); |
||||
double alpha2 = alpha + dalpha.at<double>(0); |
||||
K2 = K + cv::Matx33d(0, f.at<double>(0) * dalpha.at<double>(0), 0, 0, 0, 0, 0, 0, 0); |
||||
cv::fisheye::projectPoints(X, x2, om, T, K, k, alpha2, cv::noArray()); |
||||
xpred = x1 + cv::Mat(jacobians.col(14) * dalpha).reshape(2, 1); |
||||
CV_Assert (cv::norm(x2 - xpred) < 1e-10); |
||||
} |
||||
|
||||
TEST_F(fisheyeTest, Calibration) |
||||
{ |
||||
const int n_images = 34; |
||||
|
||||
std::vector<std::vector<cv::Point2d> > imagePoints(n_images); |
||||
std::vector<std::vector<cv::Point3d> > objectPoints(n_images); |
||||
|
||||
const std::string folder =combine(datasets_repository_path, "calib-3_stereo_from_JY"); |
||||
cv::FileStorage fs_left(combine(folder, "left.xml"), cv::FileStorage::READ); |
||||
CV_Assert(fs_left.isOpened()); |
||||
for(int i = 0; i < n_images; ++i) |
||||
fs_left[cv::format("image_%d", i )] >> imagePoints[i]; |
||||
fs_left.release(); |
||||
|
||||
cv::FileStorage fs_object(combine(folder, "object.xml"), cv::FileStorage::READ); |
||||
CV_Assert(fs_object.isOpened()); |
||||
for(int i = 0; i < n_images; ++i) |
||||
fs_object[cv::format("image_%d", i )] >> objectPoints[i]; |
||||
fs_object.release(); |
||||
|
||||
int flag = 0; |
||||
flag |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC; |
||||
flag |= cv::fisheye::CALIB_CHECK_COND; |
||||
flag |= cv::fisheye::CALIB_FIX_SKEW; |
||||
|
||||
cv::Matx33d K; |
||||
cv::Vec4d D; |
||||
|
||||
cv::fisheye::calibrate(objectPoints, imagePoints, imageSize, K, D, |
||||
cv::noArray(), cv::noArray(), flag, cv::TermCriteria(3, 20, 1e-6)); |
||||
|
||||
EXPECT_MAT_NEAR(K, this->K, 1e-10); |
||||
EXPECT_MAT_NEAR(D, this->D, 1e-10); |
||||
} |
||||
|
||||
TEST_F(fisheyeTest, Homography) |
||||
{ |
||||
const int n_images = 1; |
||||
|
||||
std::vector<std::vector<cv::Point2d> > imagePoints(n_images); |
||||
std::vector<std::vector<cv::Point3d> > objectPoints(n_images); |
||||
|
||||
const std::string folder =combine(datasets_repository_path, "calib-3_stereo_from_JY"); |
||||
cv::FileStorage fs_left(combine(folder, "left.xml"), cv::FileStorage::READ); |
||||
CV_Assert(fs_left.isOpened()); |
||||
for(int i = 0; i < n_images; ++i) |
||||
fs_left[cv::format("image_%d", i )] >> imagePoints[i]; |
||||
fs_left.release(); |
||||
|
||||
cv::FileStorage fs_object(combine(folder, "object.xml"), cv::FileStorage::READ); |
||||
CV_Assert(fs_object.isOpened()); |
||||
for(int i = 0; i < n_images; ++i) |
||||
fs_object[cv::format("image_%d", i )] >> objectPoints[i]; |
||||
fs_object.release(); |
||||
|
||||
cv::internal::IntrinsicParams param; |
||||
param.Init(cv::Vec2d(cv::max(imageSize.width, imageSize.height) / CV_PI, cv::max(imageSize.width, imageSize.height) / CV_PI), |
||||
cv::Vec2d(imageSize.width / 2.0 - 0.5, imageSize.height / 2.0 - 0.5)); |
||||
|
||||
cv::Mat _imagePoints (imagePoints[0]); |
||||
cv::Mat _objectPoints(objectPoints[0]); |
||||
|
||||
cv::Mat imagePointsNormalized = NormalizePixels(_imagePoints, param).reshape(1).t(); |
||||
_objectPoints = _objectPoints.reshape(1).t(); |
||||
cv::Mat objectPointsMean, covObjectPoints; |
||||
|
||||
int Np = imagePointsNormalized.cols; |
||||
cv::calcCovarMatrix(_objectPoints, covObjectPoints, objectPointsMean, cv::COVAR_NORMAL | cv::COVAR_COLS); |
||||
cv::SVD svd(covObjectPoints); |
||||
cv::Mat R(svd.vt); |
||||
|
||||
if (cv::norm(R(cv::Rect(2, 0, 1, 2))) < 1e-6) |
||||
R = cv::Mat::eye(3,3, CV_64FC1); |
||||
if (cv::determinant(R) < 0) |
||||
R = -R; |
||||
|
||||
cv::Mat T = -R * objectPointsMean; |
||||
cv::Mat X_new = R * _objectPoints + T * cv::Mat::ones(1, Np, CV_64FC1); |
||||
cv::Mat H = cv::internal::ComputeHomography(imagePointsNormalized, X_new.rowRange(0, 2)); |
||||
|
||||
cv::Mat M = cv::Mat::ones(3, X_new.cols, CV_64FC1); |
||||
X_new.rowRange(0, 2).copyTo(M.rowRange(0, 2)); |
||||
cv::Mat mrep = H * M; |
||||
|
||||
cv::divide(mrep, cv::Mat::ones(3,1, CV_64FC1) * mrep.row(2).clone(), mrep); |
||||
|
||||
cv::Mat merr = (mrep.rowRange(0, 2) - imagePointsNormalized).t(); |
||||
|
||||
cv::Vec2d std_err; |
||||
cv::meanStdDev(merr.reshape(2), cv::noArray(), std_err); |
||||
std_err *= sqrt((double)merr.reshape(2).total() / (merr.reshape(2).total() - 1)); |
||||
|
||||
cv::Vec2d correct_std_err(0.00516740156010384, 0.00644205331553901); |
||||
EXPECT_MAT_NEAR(std_err, correct_std_err, 1e-12); |
||||
} |
||||
|
||||
TEST_F(fisheyeTest, EtimateUncertainties) |
||||
{ |
||||
const int n_images = 34; |
||||
|
||||
std::vector<std::vector<cv::Point2d> > imagePoints(n_images); |
||||
std::vector<std::vector<cv::Point3d> > objectPoints(n_images); |
||||
|
||||
const std::string folder =combine(datasets_repository_path, "calib-3_stereo_from_JY"); |
||||
cv::FileStorage fs_left(combine(folder, "left.xml"), cv::FileStorage::READ); |
||||
CV_Assert(fs_left.isOpened()); |
||||
for(int i = 0; i < n_images; ++i) |
||||
fs_left[cv::format("image_%d", i )] >> imagePoints[i]; |
||||
fs_left.release(); |
||||
|
||||
cv::FileStorage fs_object(combine(folder, "object.xml"), cv::FileStorage::READ); |
||||
CV_Assert(fs_object.isOpened()); |
||||
for(int i = 0; i < n_images; ++i) |
||||
fs_object[cv::format("image_%d", i )] >> objectPoints[i]; |
||||
fs_object.release(); |
||||
|
||||
int flag = 0; |
||||
flag |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC; |
||||
flag |= cv::fisheye::CALIB_CHECK_COND; |
||||
flag |= cv::fisheye::CALIB_FIX_SKEW; |
||||
|
||||
cv::Matx33d K; |
||||
cv::Vec4d D; |
||||
std::vector<cv::Vec3d> rvec; |
||||
std::vector<cv::Vec3d> tvec; |
||||
|
||||
cv::fisheye::calibrate(objectPoints, imagePoints, imageSize, K, D, |
||||
rvec, tvec, flag, cv::TermCriteria(3, 20, 1e-6)); |
||||
|
||||
cv::internal::IntrinsicParams param, errors; |
||||
cv::Vec2d err_std; |
||||
double thresh_cond = 1e6; |
||||
int check_cond = 1; |
||||
param.Init(cv::Vec2d(K(0,0), K(1,1)), cv::Vec2d(K(0,2), K(1, 2)), D); |
||||
param.isEstimate = std::vector<int>(9, 1); |
||||
param.isEstimate[4] = 0; |
||||
|
||||
errors.isEstimate = param.isEstimate; |
||||
|
||||
double rms; |
||||
|
||||
cv::internal::EstimateUncertainties(objectPoints, imagePoints, param, rvec, tvec, |
||||
errors, err_std, thresh_cond, check_cond, rms); |
||||
|
||||
EXPECT_MAT_NEAR(errors.f, cv::Vec2d(1.29837104202046, 1.31565641071524), 1e-10); |
||||
EXPECT_MAT_NEAR(errors.c, cv::Vec2d(0.890439368129246, 0.816096854937896), 1e-10); |
||||
EXPECT_MAT_NEAR(errors.k, cv::Vec4d(0.00516248605191506, 0.0168181467500934, 0.0213118690274604, 0.00916010877545648), 1e-10); |
||||
EXPECT_MAT_NEAR(err_std, cv::Vec2d(0.187475975266883, 0.185678953263995), 1e-10); |
||||
CV_Assert(abs(rms - 0.263782587133546) < 1e-10); |
||||
CV_Assert(errors.alpha == 0); |
||||
} |
||||
|
||||
TEST_F(fisheyeTest, rectify) |
||||
{ |
||||
const std::string folder =combine(datasets_repository_path, "calib-3_stereo_from_JY"); |
||||
|
||||
cv::Size calibration_size = this->imageSize, requested_size = calibration_size; |
||||
cv::Matx33d K1 = this->K, K2 = K1; |
||||
cv::Mat D1 = cv::Mat(this->D), D2 = D1; |
||||
|
||||
cv::Vec3d T = this->T; |
||||
cv::Matx33d R = this->R; |
||||
|
||||
double balance = 0.0, fov_scale = 1.1; |
||||
cv::Mat R1, R2, P1, P2, Q; |
||||
cv::fisheye::stereoRectify(K1, D1, K2, D2, calibration_size, R, T, R1, R2, P1, P2, Q, |
||||
cv::CALIB_ZERO_DISPARITY, requested_size, balance, fov_scale); |
||||
|
||||
cv::Mat lmapx, lmapy, rmapx, rmapy; |
||||
//rewrite for fisheye
|
||||
cv::fisheye::initUndistortRectifyMap(K1, D1, R1, P1, requested_size, CV_32F, lmapx, lmapy); |
||||
cv::fisheye::initUndistortRectifyMap(K2, D2, R2, P2, requested_size, CV_32F, rmapx, rmapy); |
||||
|
||||
cv::Mat l, r, lundist, rundist; |
||||
cv::VideoCapture lcap(combine(folder, "left/stereo_pair_%03d.jpg")), |
||||
rcap(combine(folder, "right/stereo_pair_%03d.jpg")); |
||||
|
||||
for(int i = 0;; ++i) |
||||
{ |
||||
lcap >> l; rcap >> r; |
||||
if (l.empty() || r.empty()) |
||||
break; |
||||
|
||||
int ndisp = 128; |
||||
cv::rectangle(l, cv::Rect(255, 0, 829, l.rows-1), cv::Scalar(0, 0, 255)); |
||||
cv::rectangle(r, cv::Rect(255, 0, 829, l.rows-1), cv::Scalar(0, 0, 255)); |
||||
cv::rectangle(r, cv::Rect(255-ndisp, 0, 829+ndisp ,l.rows-1), cv::Scalar(0, 0, 255)); |
||||
cv::remap(l, lundist, lmapx, lmapy, cv::INTER_LINEAR); |
||||
cv::remap(r, rundist, rmapx, rmapy, cv::INTER_LINEAR); |
||||
|
||||
cv::Mat rectification = mergeRectification(lundist, rundist); |
||||
|
||||
cv::Mat correct = cv::imread(combine(datasets_repository_path, cv::format("rectification_AB_%03d.png", i))); |
||||
|
||||
if (correct.empty()) |
||||
cv::imwrite(combine(datasets_repository_path, cv::format("rectification_AB_%03d.png", i)), rectification); |
||||
else |
||||
EXPECT_MAT_NEAR(correct, rectification, 1e-10); |
||||
} |
||||
} |
||||
|
||||
TEST_F(fisheyeTest, stereoCalibrate) |
||||
{ |
||||
const int n_images = 34; |
||||
|
||||
const std::string folder =combine(datasets_repository_path, "calib-3_stereo_from_JY"); |
||||
|
||||
std::vector<std::vector<cv::Point2d> > leftPoints(n_images); |
||||
std::vector<std::vector<cv::Point2d> > rightPoints(n_images); |
||||
std::vector<std::vector<cv::Point3d> > objectPoints(n_images); |
||||
|
||||
cv::FileStorage fs_left(combine(folder, "left.xml"), cv::FileStorage::READ); |
||||
CV_Assert(fs_left.isOpened()); |
||||
for(int i = 0; i < n_images; ++i) |
||||
fs_left[cv::format("image_%d", i )] >> leftPoints[i]; |
||||
fs_left.release(); |
||||
|
||||
cv::FileStorage fs_right(combine(folder, "right.xml"), cv::FileStorage::READ); |
||||
CV_Assert(fs_right.isOpened()); |
||||
for(int i = 0; i < n_images; ++i) |
||||
fs_right[cv::format("image_%d", i )] >> rightPoints[i]; |
||||
fs_right.release(); |
||||
|
||||
cv::FileStorage fs_object(combine(folder, "object.xml"), cv::FileStorage::READ); |
||||
CV_Assert(fs_object.isOpened()); |
||||
for(int i = 0; i < n_images; ++i) |
||||
fs_object[cv::format("image_%d", i )] >> objectPoints[i]; |
||||
fs_object.release(); |
||||
|
||||
cv::Matx33d K1, K2, R; |
||||
cv::Vec3d T; |
||||
cv::Vec4d D1, D2; |
||||
|
||||
int flag = 0; |
||||
flag |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC; |
||||
flag |= cv::fisheye::CALIB_CHECK_COND; |
||||
flag |= cv::fisheye::CALIB_FIX_SKEW; |
||||
// flag |= cv::fisheye::CALIB_FIX_INTRINSIC;
|
||||
|
||||
cv::fisheye::stereoCalibrate(objectPoints, leftPoints, rightPoints, |
||||
K1, D1, K2, D2, imageSize, R, T, flag, |
||||
cv::TermCriteria(3, 12, 0)); |
||||
|
||||
cv::Matx33d R_correct( 0.9975587205950972, 0.06953016383322372, 0.006492709911733523, |
||||
-0.06956823121068059, 0.9975601387249519, 0.005833595226966235, |
||||
-0.006071257768382089, -0.006271040135405457, 0.9999619062167968); |
||||
cv::Vec3d T_correct(-0.099402724724121, 0.00270812139265413, 0.00129330292472699); |
||||
cv::Matx33d K1_correct (561.195925927249, 0, 621.282400272412, |
||||
0, 562.849402029712, 380.555455380889, |
||||
0, 0, 1); |
||||
|
||||
cv::Matx33d K2_correct (560.395452535348, 0, 678.971652040359, |
||||
0, 561.90171021422, 380.401340535339, |
||||
0, 0, 1); |
||||
|
||||
cv::Vec4d D1_correct (-7.44253716539556e-05, -0.00702662033932424, 0.00737569823650885, -0.00342230256441771); |
||||
cv::Vec4d D2_correct (-0.0130785435677431, 0.0284434505383497, -0.0360333869900506, 0.0144724062347222); |
||||
|
||||
EXPECT_MAT_NEAR(R, R_correct, 1e-10); |
||||
EXPECT_MAT_NEAR(T, T_correct, 1e-10); |
||||
|
||||
EXPECT_MAT_NEAR(K1, K1_correct, 1e-10); |
||||
EXPECT_MAT_NEAR(K2, K2_correct, 1e-10); |
||||
|
||||
EXPECT_MAT_NEAR(D1, D1_correct, 1e-10); |
||||
EXPECT_MAT_NEAR(D2, D2_correct, 1e-10); |
||||
|
||||
} |
||||
|
||||
TEST_F(fisheyeTest, stereoCalibrateFixIntrinsic) |
||||
{ |
||||
const int n_images = 34; |
||||
|
||||
const std::string folder =combine(datasets_repository_path, "calib-3_stereo_from_JY"); |
||||
|
||||
std::vector<std::vector<cv::Point2d> > leftPoints(n_images); |
||||
std::vector<std::vector<cv::Point2d> > rightPoints(n_images); |
||||
std::vector<std::vector<cv::Point3d> > objectPoints(n_images); |
||||
|
||||
cv::FileStorage fs_left(combine(folder, "left.xml"), cv::FileStorage::READ); |
||||
CV_Assert(fs_left.isOpened()); |
||||
for(int i = 0; i < n_images; ++i) |
||||
fs_left[cv::format("image_%d", i )] >> leftPoints[i]; |
||||
fs_left.release(); |
||||
|
||||
cv::FileStorage fs_right(combine(folder, "right.xml"), cv::FileStorage::READ); |
||||
CV_Assert(fs_right.isOpened()); |
||||
for(int i = 0; i < n_images; ++i) |
||||
fs_right[cv::format("image_%d", i )] >> rightPoints[i]; |
||||
fs_right.release(); |
||||
|
||||
cv::FileStorage fs_object(combine(folder, "object.xml"), cv::FileStorage::READ); |
||||
CV_Assert(fs_object.isOpened()); |
||||
for(int i = 0; i < n_images; ++i) |
||||
fs_object[cv::format("image_%d", i )] >> objectPoints[i]; |
||||
fs_object.release(); |
||||
|
||||
cv::Matx33d R; |
||||
cv::Vec3d T; |
||||
|
||||
int flag = 0; |
||||
flag |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC; |
||||
flag |= cv::fisheye::CALIB_CHECK_COND; |
||||
flag |= cv::fisheye::CALIB_FIX_SKEW; |
||||
flag |= cv::fisheye::CALIB_FIX_INTRINSIC; |
||||
|
||||
cv::Matx33d K1 (561.195925927249, 0, 621.282400272412, |
||||
0, 562.849402029712, 380.555455380889, |
||||
0, 0, 1); |
||||
|
||||
cv::Matx33d K2 (560.395452535348, 0, 678.971652040359, |
||||
0, 561.90171021422, 380.401340535339, |
||||
0, 0, 1); |
||||
|
||||
cv::Vec4d D1 (-7.44253716539556e-05, -0.00702662033932424, 0.00737569823650885, -0.00342230256441771); |
||||
cv::Vec4d D2 (-0.0130785435677431, 0.0284434505383497, -0.0360333869900506, 0.0144724062347222); |
||||
|
||||
cv::fisheye::stereoCalibrate(objectPoints, leftPoints, rightPoints, |
||||
K1, D1, K2, D2, imageSize, R, T, flag, |
||||
cv::TermCriteria(3, 12, 0)); |
||||
|
||||
cv::Matx33d R_correct( 0.9975587205950972, 0.06953016383322372, 0.006492709911733523, |
||||
-0.06956823121068059, 0.9975601387249519, 0.005833595226966235, |
||||
-0.006071257768382089, -0.006271040135405457, 0.9999619062167968); |
||||
cv::Vec3d T_correct(-0.099402724724121, 0.00270812139265413, 0.00129330292472699); |
||||
|
||||
|
||||
EXPECT_MAT_NEAR(R, R_correct, 1e-10); |
||||
EXPECT_MAT_NEAR(T, T_correct, 1e-10); |
||||
} |
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// fisheyeTest::
|
||||
|
||||
const cv::Size fisheyeTest::imageSize(1280, 800); |
||||
|
||||
const cv::Matx33d fisheyeTest::K(558.478087865323, 0, 620.458515360843, |
||||
0, 560.506767351568, 381.939424848348, |
||||
0, 0, 1); |
||||
|
||||
const cv::Vec4d fisheyeTest::D(-0.0014613319981768, -0.00329861110580401, 0.00605760088590183, -0.00374209380722371); |
||||
|
||||
const cv::Matx33d fisheyeTest::R ( 9.9756700084424932e-01, 6.9698277640183867e-02, 1.4929569991321144e-03, |
||||
-6.9711825162322980e-02, 9.9748249845531767e-01, 1.2997180766418455e-02, |
||||
-5.8331736398316541e-04,-1.3069635393884985e-02, 9.9991441852366736e-01); |
||||
|
||||
const cv::Vec3d fisheyeTest::T(-9.9217369356044638e-02, 3.1741831972356663e-03, 1.8551007952921010e-04); |
||||
|
||||
std::string fisheyeTest::combine(const std::string& _item1, const std::string& _item2) |
||||
{ |
||||
std::string item1 = _item1, item2 = _item2; |
||||
std::replace(item1.begin(), item1.end(), '\\', '/'); |
||||
std::replace(item2.begin(), item2.end(), '\\', '/'); |
||||
|
||||
if (item1.empty()) |
||||
return item2; |
||||
|
||||
if (item2.empty()) |
||||
return item1; |
||||
|
||||
char last = item1[item1.size()-1]; |
||||
return item1 + (last != '/' ? "/" : "") + item2; |
||||
} |
||||
|
||||
cv::Mat fisheyeTest::mergeRectification(const cv::Mat& l, const cv::Mat& r) |
||||
{ |
||||
CV_Assert(l.type() == r.type() && l.size() == r.size()); |
||||
cv::Mat merged(l.rows, l.cols * 2, l.type()); |
||||
cv::Mat lpart = merged.colRange(0, l.cols); |
||||
cv::Mat rpart = merged.colRange(l.cols, merged.cols); |
||||
l.copyTo(lpart); |
||||
r.copyTo(rpart); |
||||
|
||||
for(int i = 0; i < l.rows; i+=20) |
||||
cv::line(merged, cv::Point(0, i), cv::Point(merged.cols, i), cv::Scalar(0, 255, 0)); |
||||
|
||||
return merged; |
||||
} |
@ -1,276 +0,0 @@ |
||||
Common Interfaces of Generic Descriptor Matchers |
||||
================================================ |
||||
|
||||
.. highlight:: cpp |
||||
|
||||
Matchers of keypoint descriptors in OpenCV have wrappers with a common interface that enables you to easily switch |
||||
between different algorithms solving the same problem. This section is devoted to matching descriptors |
||||
that cannot be represented as vectors in a multidimensional space. ``GenericDescriptorMatcher`` is a more generic interface for descriptors. It does not make any assumptions about descriptor representation. |
||||
Every descriptor with the |
||||
:ocv:class:`DescriptorExtractor` interface has a wrapper with the ``GenericDescriptorMatcher`` interface (see |
||||
:ocv:class:`VectorDescriptorMatcher` ). |
||||
There are descriptors such as the One-way descriptor and Ferns that have the ``GenericDescriptorMatcher`` interface implemented but do not support ``DescriptorExtractor``. |
||||
|
||||
.. note:: |
||||
|
||||
* An example explaining keypoint description can be found at opencv_source_code/samples/cpp/descriptor_extractor_matcher.cpp |
||||
* An example on descriptor matching evaluation can be found at opencv_source_code/samples/cpp/detector_descriptor_matcher_evaluation.cpp |
||||
* An example on one to many image matching can be found at opencv_source_code/samples/cpp/matching_to_many_images.cpp |
||||
|
||||
GenericDescriptorMatcher |
||||
------------------------ |
||||
.. ocv:class:: GenericDescriptorMatcher |
||||
|
||||
Abstract interface for extracting and matching a keypoint descriptor. There are also :ocv:class:`DescriptorExtractor` and :ocv:class:`DescriptorMatcher` for these purposes but their interfaces are intended for descriptors represented as vectors in a multidimensional space. ``GenericDescriptorMatcher`` is a more generic interface for descriptors. ``DescriptorMatcher`` and ``GenericDescriptorMatcher`` have two groups of match methods: for matching keypoints of an image with another image or with an image set. :: |
||||
|
||||
class GenericDescriptorMatcher |
||||
{ |
||||
public: |
||||
GenericDescriptorMatcher(); |
||||
virtual ~GenericDescriptorMatcher(); |
||||
|
||||
virtual void add( InputArrayOfArrays images, |
||||
vector<vector<KeyPoint> >& keypoints ); |
||||
|
||||
const vector<Mat>& getTrainImages() const; |
||||
const vector<vector<KeyPoint> >& getTrainKeypoints() const; |
||||
virtual void clear(); |
||||
|
||||
virtual void train() = 0; |
||||
|
||||
virtual bool isMaskSupported() = 0; |
||||
|
||||
void classify( InputArray queryImage, |
||||
vector<KeyPoint>& queryKeypoints, |
||||
InputArray trainImage, |
||||
vector<KeyPoint>& trainKeypoints ) const; |
||||
void classify( InputArray queryImage, |
||||
vector<KeyPoint>& queryKeypoints ); |
||||
|
||||
/* |
||||
* Group of methods to match keypoints from an image pair. |
||||
*/ |
||||
void match( InputArray queryImage, vector<KeyPoint>& queryKeypoints, |
||||
InputArray trainImage, vector<KeyPoint>& trainKeypoints, |
||||
vector<DMatch>& matches, InputArray mask=noArray() ) const; |
||||
void knnMatch( InputArray queryImage, vector<KeyPoint>& queryKeypoints, |
||||
InputArray trainImage, vector<KeyPoint>& trainKeypoints, |
||||
vector<vector<DMatch> >& matches, int k, |
||||
InputArray mask=noArray(), bool compactResult=false ) const; |
||||
void radiusMatch( InputArray queryImage, vector<KeyPoint>& queryKeypoints, |
||||
InputArray trainImage, vector<KeyPoint>& trainKeypoints, |
||||
vector<vector<DMatch> >& matches, float maxDistance, |
||||
InputArray mask=noArray(), bool compactResult=false ) const; |
||||
/* |
||||
* Group of methods to match keypoints from one image to an image set. |
||||
*/ |
||||
void match( InputArray queryImage, vector<KeyPoint>& queryKeypoints, |
||||
vector<DMatch>& matches, InputArrayOfArrays masks=noArray() ); |
||||
void knnMatch( InputArray queryImage, vector<KeyPoint>& queryKeypoints, |
||||
vector<vector<DMatch> >& matches, int k, |
||||
InputArrayOfArrays masks=noArray(), bool compactResult=false ); |
||||
void radiusMatch( InputArray queryImage, vector<KeyPoint>& queryKeypoints, |
||||
vector<vector<DMatch> >& matches, float maxDistance, |
||||
InputArrayOfArrays masks=noArray(), bool compactResult=false ); |
||||
|
||||
virtual void read( const FileNode& ); |
||||
virtual void write( FileStorage& ) const; |
||||
|
||||
virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const = 0; |
||||
|
||||
protected: |
||||
... |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
GenericDescriptorMatcher::add |
||||
--------------------------------- |
||||
Adds images and their keypoints to the training collection stored in the class instance. |
||||
|
||||
.. ocv:function:: void GenericDescriptorMatcher::add( InputArrayOfArrays images, vector<vector<KeyPoint> >& keypoints ) |
||||
|
||||
:param images: Image collection. |
||||
|
||||
:param keypoints: Point collection. It is assumed that ``keypoints[i]`` are keypoints detected in the image ``images[i]`` . |
||||
|
||||
|
||||
|
||||
GenericDescriptorMatcher::getTrainImages |
||||
-------------------------------------------- |
||||
Returns a train image collection. |
||||
|
||||
.. ocv:function:: const vector<Mat>& GenericDescriptorMatcher::getTrainImages() const |
||||
|
||||
|
||||
|
||||
GenericDescriptorMatcher::getTrainKeypoints |
||||
----------------------------------------------- |
||||
Returns a train keypoints collection. |
||||
|
||||
.. ocv:function:: const vector<vector<KeyPoint> >& GenericDescriptorMatcher::getTrainKeypoints() const |
||||
|
||||
|
||||
|
||||
GenericDescriptorMatcher::clear |
||||
----------------------------------- |
||||
Clears a train collection (images and keypoints). |
||||
|
||||
.. ocv:function:: void GenericDescriptorMatcher::clear() |
||||
|
||||
|
||||
|
||||
GenericDescriptorMatcher::train |
||||
----------------------------------- |
||||
Trains descriptor matcher |
||||
|
||||
.. ocv:function:: void GenericDescriptorMatcher::train() |
||||
|
||||
Prepares descriptor matcher, for example, creates a tree-based structure, to extract descriptors or to optimize descriptors matching. |
||||
|
||||
|
||||
GenericDescriptorMatcher::isMaskSupported |
||||
--------------------------------------------- |
||||
Returns ``true`` if a generic descriptor matcher supports masking permissible matches. |
||||
|
||||
.. ocv:function:: bool GenericDescriptorMatcher::isMaskSupported() |
||||
|
||||
|
||||
|
||||
GenericDescriptorMatcher::classify |
||||
-------------------------------------- |
||||
Classifies keypoints from a query set. |
||||
|
||||
.. ocv:function:: void GenericDescriptorMatcher::classify( InputArray queryImage, vector<KeyPoint>& queryKeypoints, InputArray trainImage, vector<KeyPoint>& trainKeypoints ) const |
||||
|
||||
.. ocv:function:: void GenericDescriptorMatcher::classify( InputArray queryImage, vector<KeyPoint>& queryKeypoints ) |
||||
|
||||
:param queryImage: Query image. |
||||
|
||||
:param queryKeypoints: Keypoints from a query image. |
||||
|
||||
:param trainImage: Train image. |
||||
|
||||
:param trainKeypoints: Keypoints from a train image. |
||||
|
||||
The method classifies each keypoint from a query set. The first variant of the method takes a train image and its keypoints as an input argument. The second variant uses the internally stored training collection that can be built using the ``GenericDescriptorMatcher::add`` method. |
||||
|
||||
The methods do the following: |
||||
|
||||
#. |
||||
Call the ``GenericDescriptorMatcher::match`` method to find correspondence between the query set and the training set. |
||||
|
||||
#. |
||||
Set the ``class_id`` field of each keypoint from the query set to ``class_id`` of the corresponding keypoint from the training set. |
||||
|
||||
|
||||
|
||||
GenericDescriptorMatcher::match |
||||
----------------------------------- |
||||
Finds the best match in the training set for each keypoint from the query set. |
||||
|
||||
.. ocv:function:: void GenericDescriptorMatcher::match(InputArray queryImage, vector<KeyPoint>& queryKeypoints, InputArray trainImage, vector<KeyPoint>& trainKeypoints, vector<DMatch>& matches, InputArray mask=noArray() ) const |
||||
|
||||
.. ocv:function:: void GenericDescriptorMatcher::match( InputArray queryImage, vector<KeyPoint>& queryKeypoints, vector<DMatch>& matches, InputArrayOfArrays masks=noArray() ) |
||||
|
||||
:param queryImage: Query image. |
||||
|
||||
:param queryKeypoints: Keypoints detected in ``queryImage`` . |
||||
|
||||
:param trainImage: Train image. It is not added to a train image collection stored in the class object. |
||||
|
||||
:param trainKeypoints: Keypoints detected in ``trainImage`` . They are not added to a train points collection stored in the class object. |
||||
|
||||
:param matches: Matches. If a query descriptor (keypoint) is masked out in ``mask`` , match is added for this descriptor. So, ``matches`` size may be smaller than the query keypoints count. |
||||
|
||||
:param mask: Mask specifying permissible matches between an input query and train keypoints. |
||||
|
||||
:param masks: Set of masks. Each ``masks[i]`` specifies permissible matches between input query keypoints and stored train keypoints from the i-th image. |
||||
|
||||
The methods find the best match for each query keypoint. In the first variant of the method, a train image and its keypoints are the input arguments. In the second variant, query keypoints are matched to the internally stored training collection that can be built using the ``GenericDescriptorMatcher::add`` method. Optional mask (or masks) can be passed to specify which query and training descriptors can be matched. Namely, ``queryKeypoints[i]`` can be matched with ``trainKeypoints[j]`` only if ``mask.at<uchar>(i,j)`` is non-zero. |
||||
|
||||
|
||||
|
||||
GenericDescriptorMatcher::knnMatch |
||||
-------------------------------------- |
||||
Finds the ``k`` best matches for each query keypoint. |
||||
|
||||
.. ocv:function:: void GenericDescriptorMatcher::knnMatch( InputArray queryImage, vector<KeyPoint>& queryKeypoints, InputArray trainImage, vector<KeyPoint>& trainKeypoints, vector<vector<DMatch> >& matches, int k, InputArray mask=noArray(), bool compactResult=false ) const |
||||
|
||||
.. ocv:function:: void GenericDescriptorMatcher::knnMatch( InputArray queryImage, vector<KeyPoint>& queryKeypoints, vector<vector<DMatch> >& matches, int k, InputArrayOfArrays masks=noArray(), bool compactResult=false ) |
||||
|
||||
The methods are extended variants of ``GenericDescriptorMatch::match``. The parameters are similar, and the semantics is similar to ``DescriptorMatcher::knnMatch``. But this class does not require explicitly computed keypoint descriptors. |
||||
|
||||
|
||||
|
||||
GenericDescriptorMatcher::radiusMatch |
||||
----------------------------------------- |
||||
For each query keypoint, finds the training keypoints not farther than the specified distance. |
||||
|
||||
.. ocv:function:: void GenericDescriptorMatcher::radiusMatch( InputArray queryImage, vector<KeyPoint>& queryKeypoints, InputArray trainImage, vector<KeyPoint>& trainKeypoints, vector<vector<DMatch> >& matches, float maxDistance, InputArray mask=noArray(), bool compactResult=false ) const |
||||
|
||||
.. ocv:function:: void GenericDescriptorMatcher::radiusMatch( InputArray queryImage, vector<KeyPoint>& queryKeypoints, vector<vector<DMatch> >& matches, float maxDistance, InputArrayOfArrays masks=noArray(), bool compactResult=false ) |
||||
|
||||
The methods are similar to ``DescriptorMatcher::radius``. But this class does not require explicitly computed keypoint descriptors. |
||||
|
||||
|
||||
|
||||
GenericDescriptorMatcher::read |
||||
---------------------------------- |
||||
Reads a matcher object from a file node. |
||||
|
||||
.. ocv:function:: void GenericDescriptorMatcher::read( const FileNode& fn ) |
||||
|
||||
|
||||
|
||||
GenericDescriptorMatcher::write |
||||
----------------------------------- |
||||
Writes a match object to a file storage. |
||||
|
||||
.. ocv:function:: void GenericDescriptorMatcher::write( FileStorage& fs ) const |
||||
|
||||
|
||||
GenericDescriptorMatcher::clone |
||||
----------------------------------- |
||||
Clones the matcher. |
||||
|
||||
.. ocv:function:: Ptr<GenericDescriptorMatcher> GenericDescriptorMatcher::clone( bool emptyTrainData=false ) const |
||||
|
||||
:param emptyTrainData: If ``emptyTrainData`` is false, the method creates a deep copy of the object, that is, copies |
||||
both parameters and train data. If ``emptyTrainData`` is true, the method creates an object copy with the current parameters |
||||
but with empty train data. |
||||
|
||||
|
||||
VectorDescriptorMatcher |
||||
----------------------- |
||||
.. ocv:class:: VectorDescriptorMatcher : public GenericDescriptorMatcher |
||||
|
||||
Class used for matching descriptors that can be described as vectors in a finite-dimensional space. :: |
||||
|
||||
class CV_EXPORTS VectorDescriptorMatcher : public GenericDescriptorMatcher |
||||
{ |
||||
public: |
||||
VectorDescriptorMatcher( const Ptr<DescriptorExtractor>& extractor, const Ptr<DescriptorMatcher>& matcher ); |
||||
virtual ~VectorDescriptorMatcher(); |
||||
|
||||
virtual void add( InputArrayOfArrays imgCollection, |
||||
vector<vector<KeyPoint> >& pointCollection ); |
||||
virtual void clear(); |
||||
virtual void train(); |
||||
virtual bool isMaskSupported(); |
||||
|
||||
virtual void read( const FileNode& fn ); |
||||
virtual void write( FileStorage& fs ) const; |
||||
|
||||
virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const; |
||||
|
||||
protected: |
||||
... |
||||
}; |
||||
|
||||
|
||||
Example: :: |
||||
|
||||
VectorDescriptorMatcher matcher( new SurfDescriptorExtractor, |
||||
new BruteForceMatcher<L2<float> > ); |
@ -1,184 +0,0 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp" |
||||
#include <algorithm> |
||||
#include <vector> |
||||
|
||||
#include <iostream> |
||||
#include <iomanip> |
||||
|
||||
using namespace cv; |
||||
|
||||
inline int smoothedSum(const Mat& sum, const KeyPoint& pt, int y, int x) |
||||
{ |
||||
static const int HALF_KERNEL = BriefDescriptorExtractor::KERNEL_SIZE / 2; |
||||
|
||||
int img_y = (int)(pt.pt.y + 0.5) + y; |
||||
int img_x = (int)(pt.pt.x + 0.5) + x; |
||||
return sum.at<int>(img_y + HALF_KERNEL + 1, img_x + HALF_KERNEL + 1) |
||||
- sum.at<int>(img_y + HALF_KERNEL + 1, img_x - HALF_KERNEL) |
||||
- sum.at<int>(img_y - HALF_KERNEL, img_x + HALF_KERNEL + 1) |
||||
+ sum.at<int>(img_y - HALF_KERNEL, img_x - HALF_KERNEL); |
||||
} |
||||
|
||||
static void pixelTests16(InputArray _sum, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors) |
||||
{ |
||||
Mat sum = _sum.getMat(), descriptors = _descriptors.getMat(); |
||||
for (int i = 0; i < (int)keypoints.size(); ++i) |
||||
{ |
||||
uchar* desc = descriptors.ptr(i); |
||||
const KeyPoint& pt = keypoints[i]; |
||||
#include "generated_16.i" |
||||
} |
||||
} |
||||
|
||||
static void pixelTests32(InputArray _sum, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors) |
||||
{ |
||||
Mat sum = _sum.getMat(), descriptors = _descriptors.getMat(); |
||||
for (int i = 0; i < (int)keypoints.size(); ++i) |
||||
{ |
||||
uchar* desc = descriptors.ptr(i); |
||||
const KeyPoint& pt = keypoints[i]; |
||||
|
||||
#include "generated_32.i" |
||||
} |
||||
} |
||||
|
||||
static void pixelTests64(InputArray _sum, const std::vector<KeyPoint>& keypoints, OutputArray _descriptors) |
||||
{ |
||||
Mat sum = _sum.getMat(), descriptors = _descriptors.getMat(); |
||||
for (int i = 0; i < (int)keypoints.size(); ++i) |
||||
{ |
||||
uchar* desc = descriptors.ptr(i); |
||||
const KeyPoint& pt = keypoints[i]; |
||||
|
||||
#include "generated_64.i" |
||||
} |
||||
} |
||||
|
||||
namespace cv |
||||
{ |
||||
|
||||
BriefDescriptorExtractor::BriefDescriptorExtractor(int bytes) : |
||||
bytes_(bytes), test_fn_(NULL) |
||||
{ |
||||
switch (bytes) |
||||
{ |
||||
case 16: |
||||
test_fn_ = pixelTests16; |
||||
break; |
||||
case 32: |
||||
test_fn_ = pixelTests32; |
||||
break; |
||||
case 64: |
||||
test_fn_ = pixelTests64; |
||||
break; |
||||
default: |
||||
CV_Error(Error::StsBadArg, "bytes must be 16, 32, or 64"); |
||||
} |
||||
} |
||||
|
||||
int BriefDescriptorExtractor::descriptorSize() const |
||||
{ |
||||
return bytes_; |
||||
} |
||||
|
||||
int BriefDescriptorExtractor::descriptorType() const |
||||
{ |
||||
return CV_8UC1; |
||||
} |
||||
|
||||
int BriefDescriptorExtractor::defaultNorm() const |
||||
{ |
||||
return NORM_HAMMING; |
||||
} |
||||
|
||||
void BriefDescriptorExtractor::read( const FileNode& fn) |
||||
{ |
||||
int dSize = fn["descriptorSize"]; |
||||
switch (dSize) |
||||
{ |
||||
case 16: |
||||
test_fn_ = pixelTests16; |
||||
break; |
||||
case 32: |
||||
test_fn_ = pixelTests32; |
||||
break; |
||||
case 64: |
||||
test_fn_ = pixelTests64; |
||||
break; |
||||
default: |
||||
CV_Error(Error::StsBadArg, "descriptorSize must be 16, 32, or 64"); |
||||
} |
||||
bytes_ = dSize; |
||||
} |
||||
|
||||
void BriefDescriptorExtractor::write( FileStorage& fs) const |
||||
{ |
||||
fs << "descriptorSize" << bytes_; |
||||
} |
||||
|
||||
void BriefDescriptorExtractor::computeImpl(InputArray image, std::vector<KeyPoint>& keypoints, OutputArray descriptors) const |
||||
{ |
||||
// Construct integral image for fast smoothing (box filter)
|
||||
Mat sum; |
||||
|
||||
Mat grayImage = image.getMat(); |
||||
if( image.type() != CV_8U ) cvtColor( image, grayImage, COLOR_BGR2GRAY ); |
||||
|
||||
///TODO allow the user to pass in a precomputed integral image
|
||||
//if(image.type() == CV_32S)
|
||||
// sum = image;
|
||||
//else
|
||||
|
||||
integral( grayImage, sum, CV_32S); |
||||
|
||||
//Remove keypoints very close to the border
|
||||
KeyPointsFilter::runByImageBorder(keypoints, image.size(), PATCH_SIZE/2 + KERNEL_SIZE/2); |
||||
|
||||
descriptors.create((int)keypoints.size(), bytes_, CV_8U); |
||||
descriptors.setTo(Scalar::all(0)); |
||||
test_fn_(sum, keypoints, descriptors); |
||||
} |
||||
|
||||
} // namespace cv
|
@ -1,734 +0,0 @@ |
||||
// freak.cpp
|
||||
//
|
||||
// Copyright (C) 2011-2012 Signal processing laboratory 2, EPFL,
|
||||
// Kirell Benzi (kirell.benzi@epfl.ch),
|
||||
// Raphael Ortiz (raphael.ortiz@a3.epfl.ch)
|
||||
// Alexandre Alahi (alexandre.alahi@epfl.ch)
|
||||
// and Pierre Vandergheynst (pierre.vandergheynst@epfl.ch)
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
|
||||
#include "precomp.hpp" |
||||
#include <fstream> |
||||
#include <stdlib.h> |
||||
#include <algorithm> |
||||
#include <iostream> |
||||
#include <bitset> |
||||
#include <sstream> |
||||
#include <algorithm> |
||||
#include <iomanip> |
||||
#include <string.h> |
||||
|
||||
namespace cv |
||||
{ |
||||
|
||||
static const double FREAK_SQRT2 = 1.4142135623731; |
||||
static const double FREAK_INV_SQRT2 = 1.0 / FREAK_SQRT2; |
||||
static const double FREAK_LOG2 = 0.693147180559945; |
||||
static const int FREAK_NB_ORIENTATION = 256; |
||||
static const int FREAK_NB_POINTS = 43; |
||||
static const int FREAK_SMALLEST_KP_SIZE = 7; // smallest size of keypoints
|
||||
static const int FREAK_NB_SCALES = FREAK::NB_SCALES; |
||||
static const int FREAK_NB_PAIRS = FREAK::NB_PAIRS; |
||||
static const int FREAK_NB_ORIENPAIRS = FREAK::NB_ORIENPAIRS; |
||||
|
||||
// default pairs
|
||||
static const int FREAK_DEF_PAIRS[FREAK::NB_PAIRS] = |
||||
{ |
||||
404,431,818,511,181,52,311,874,774,543,719,230,417,205,11, |
||||
560,149,265,39,306,165,857,250,8,61,15,55,717,44,412, |
||||
592,134,761,695,660,782,625,487,549,516,271,665,762,392,178, |
||||
796,773,31,672,845,548,794,677,654,241,831,225,238,849,83, |
||||
691,484,826,707,122,517,583,731,328,339,571,475,394,472,580, |
||||
381,137,93,380,327,619,729,808,218,213,459,141,806,341,95, |
||||
382,568,124,750,193,749,706,843,79,199,317,329,768,198,100, |
||||
466,613,78,562,783,689,136,838,94,142,164,679,219,419,366, |
||||
418,423,77,89,523,259,683,312,555,20,470,684,123,458,453,833, |
||||
72,113,253,108,313,25,153,648,411,607,618,128,305,232,301,84, |
||||
56,264,371,46,407,360,38,99,176,710,114,578,66,372,653, |
||||
129,359,424,159,821,10,323,393,5,340,891,9,790,47,0,175,346, |
||||
236,26,172,147,574,561,32,294,429,724,755,398,787,288,299, |
||||
769,565,767,722,757,224,465,723,498,467,235,127,802,446,233, |
||||
544,482,800,318,16,532,801,441,554,173,60,530,713,469,30, |
||||
212,630,899,170,266,799,88,49,512,399,23,500,107,524,90, |
||||
194,143,135,192,206,345,148,71,119,101,563,870,158,254,214, |
||||
276,464,332,725,188,385,24,476,40,231,620,171,258,67,109, |
||||
844,244,187,388,701,690,50,7,850,479,48,522,22,154,12,659, |
||||
736,655,577,737,830,811,174,21,237,335,353,234,53,270,62, |
||||
182,45,177,245,812,673,355,556,612,166,204,54,248,365,226, |
||||
242,452,700,685,573,14,842,481,468,781,564,416,179,405,35, |
||||
819,608,624,367,98,643,448,2,460,676,440,240,130,146,184, |
||||
185,430,65,807,377,82,121,708,239,310,138,596,730,575,477, |
||||
851,797,247,27,85,586,307,779,326,494,856,324,827,96,748, |
||||
13,397,125,688,702,92,293,716,277,140,112,4,80,855,839,1, |
||||
413,347,584,493,289,696,19,751,379,76,73,115,6,590,183,734, |
||||
197,483,217,344,330,400,186,243,587,220,780,200,793,246,824, |
||||
41,735,579,81,703,322,760,720,139,480,490,91,814,813,163, |
||||
152,488,763,263,425,410,576,120,319,668,150,160,302,491,515, |
||||
260,145,428,97,251,395,272,252,18,106,358,854,485,144,550, |
||||
131,133,378,68,102,104,58,361,275,209,697,582,338,742,589, |
||||
325,408,229,28,304,191,189,110,126,486,211,547,533,70,215, |
||||
670,249,36,581,389,605,331,518,442,822 |
||||
}; |
||||
|
||||
// used to sort pairs during pairs selection
|
||||
struct PairStat |
||||
{ |
||||
double mean; |
||||
int idx; |
||||
}; |
||||
|
||||
struct sortMean |
||||
{ |
||||
bool operator()( const PairStat& a, const PairStat& b ) const |
||||
{ |
||||
return a.mean < b.mean; |
||||
} |
||||
}; |
||||
|
||||
void FREAK::buildPattern() |
||||
{ |
||||
if( patternScale == patternScale0 && nOctaves == nOctaves0 && !patternLookup.empty() ) |
||||
return; |
||||
|
||||
nOctaves0 = nOctaves; |
||||
patternScale0 = patternScale; |
||||
|
||||
patternLookup.resize(FREAK_NB_SCALES*FREAK_NB_ORIENTATION*FREAK_NB_POINTS); |
||||
double scaleStep = std::pow(2.0, (double)(nOctaves)/FREAK_NB_SCALES ); // 2 ^ ( (nOctaves-1) /nbScales)
|
||||
double scalingFactor, alpha, beta, theta = 0; |
||||
|
||||
// pattern definition, radius normalized to 1.0 (outer point position+sigma=1.0)
|
||||
const int n[8] = {6,6,6,6,6,6,6,1}; // number of points on each concentric circle (from outer to inner)
|
||||
const double bigR(2.0/3.0); // bigger radius
|
||||
const double smallR(2.0/24.0); // smaller radius
|
||||
const double unitSpace( (bigR-smallR)/21.0 ); // define spaces between concentric circles (from center to outer: 1,2,3,4,5,6)
|
||||
// radii of the concentric cirles (from outer to inner)
|
||||
const double radius[8] = {bigR, bigR-6*unitSpace, bigR-11*unitSpace, bigR-15*unitSpace, bigR-18*unitSpace, bigR-20*unitSpace, smallR, 0.0}; |
||||
// sigma of pattern points (each group of 6 points on a concentric cirle has the same sigma)
|
||||
const double sigma[8] = {radius[0]/2.0, radius[1]/2.0, radius[2]/2.0, |
||||
radius[3]/2.0, radius[4]/2.0, radius[5]/2.0, |
||||
radius[6]/2.0, radius[6]/2.0 |
||||
}; |
||||
// fill the lookup table
|
||||
for( int scaleIdx=0; scaleIdx < FREAK_NB_SCALES; ++scaleIdx ) |
||||
{ |
||||
patternSizes[scaleIdx] = 0; // proper initialization
|
||||
scalingFactor = std::pow(scaleStep,scaleIdx); //scale of the pattern, scaleStep ^ scaleIdx
|
||||
|
||||
for( int orientationIdx = 0; orientationIdx < FREAK_NB_ORIENTATION; ++orientationIdx ) |
||||
{ |
||||
theta = double(orientationIdx)* 2*CV_PI/double(FREAK_NB_ORIENTATION); // orientation of the pattern
|
||||
int pointIdx = 0; |
||||
|
||||
PatternPoint* patternLookupPtr = &patternLookup[0]; |
||||
for( size_t i = 0; i < 8; ++i ) |
||||
{ |
||||
for( int k = 0 ; k < n[i]; ++k ) |
||||
{ |
||||
beta = CV_PI/n[i] * (i%2); // orientation offset so that groups of points on each circles are staggered
|
||||
alpha = double(k)* 2*CV_PI/double(n[i])+beta+theta; |
||||
|
||||
// add the point to the look-up table
|
||||
PatternPoint& point = patternLookupPtr[ scaleIdx*FREAK_NB_ORIENTATION*FREAK_NB_POINTS+orientationIdx*FREAK_NB_POINTS+pointIdx ]; |
||||
point.x = static_cast<float>(radius[i] * cos(alpha) * scalingFactor * patternScale); |
||||
point.y = static_cast<float>(radius[i] * sin(alpha) * scalingFactor * patternScale); |
||||
point.sigma = static_cast<float>(sigma[i] * scalingFactor * patternScale); |
||||
|
||||
// adapt the sizeList if necessary
|
||||
const int sizeMax = static_cast<int>(ceil((radius[i]+sigma[i])*scalingFactor*patternScale)) + 1; |
||||
if( patternSizes[scaleIdx] < sizeMax ) |
||||
patternSizes[scaleIdx] = sizeMax; |
||||
|
||||
++pointIdx; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
// build the list of orientation pairs
|
||||
orientationPairs[0].i=0; orientationPairs[0].j=3; orientationPairs[1].i=1; orientationPairs[1].j=4; orientationPairs[2].i=2; orientationPairs[2].j=5; |
||||
orientationPairs[3].i=0; orientationPairs[3].j=2; orientationPairs[4].i=1; orientationPairs[4].j=3; orientationPairs[5].i=2; orientationPairs[5].j=4; |
||||
orientationPairs[6].i=3; orientationPairs[6].j=5; orientationPairs[7].i=4; orientationPairs[7].j=0; orientationPairs[8].i=5; orientationPairs[8].j=1; |
||||
|
||||
orientationPairs[9].i=6; orientationPairs[9].j=9; orientationPairs[10].i=7; orientationPairs[10].j=10; orientationPairs[11].i=8; orientationPairs[11].j=11; |
||||
orientationPairs[12].i=6; orientationPairs[12].j=8; orientationPairs[13].i=7; orientationPairs[13].j=9; orientationPairs[14].i=8; orientationPairs[14].j=10; |
||||
orientationPairs[15].i=9; orientationPairs[15].j=11; orientationPairs[16].i=10; orientationPairs[16].j=6; orientationPairs[17].i=11; orientationPairs[17].j=7; |
||||
|
||||
orientationPairs[18].i=12; orientationPairs[18].j=15; orientationPairs[19].i=13; orientationPairs[19].j=16; orientationPairs[20].i=14; orientationPairs[20].j=17; |
||||
orientationPairs[21].i=12; orientationPairs[21].j=14; orientationPairs[22].i=13; orientationPairs[22].j=15; orientationPairs[23].i=14; orientationPairs[23].j=16; |
||||
orientationPairs[24].i=15; orientationPairs[24].j=17; orientationPairs[25].i=16; orientationPairs[25].j=12; orientationPairs[26].i=17; orientationPairs[26].j=13; |
||||
|
||||
orientationPairs[27].i=18; orientationPairs[27].j=21; orientationPairs[28].i=19; orientationPairs[28].j=22; orientationPairs[29].i=20; orientationPairs[29].j=23; |
||||
orientationPairs[30].i=18; orientationPairs[30].j=20; orientationPairs[31].i=19; orientationPairs[31].j=21; orientationPairs[32].i=20; orientationPairs[32].j=22; |
||||
orientationPairs[33].i=21; orientationPairs[33].j=23; orientationPairs[34].i=22; orientationPairs[34].j=18; orientationPairs[35].i=23; orientationPairs[35].j=19; |
||||
|
||||
orientationPairs[36].i=24; orientationPairs[36].j=27; orientationPairs[37].i=25; orientationPairs[37].j=28; orientationPairs[38].i=26; orientationPairs[38].j=29; |
||||
orientationPairs[39].i=30; orientationPairs[39].j=33; orientationPairs[40].i=31; orientationPairs[40].j=34; orientationPairs[41].i=32; orientationPairs[41].j=35; |
||||
orientationPairs[42].i=36; orientationPairs[42].j=39; orientationPairs[43].i=37; orientationPairs[43].j=40; orientationPairs[44].i=38; orientationPairs[44].j=41; |
||||
|
||||
for( unsigned m = FREAK_NB_ORIENPAIRS; m--; ) |
||||
{ |
||||
const float dx = patternLookup[orientationPairs[m].i].x-patternLookup[orientationPairs[m].j].x; |
||||
const float dy = patternLookup[orientationPairs[m].i].y-patternLookup[orientationPairs[m].j].y; |
||||
const float norm_sq = (dx*dx+dy*dy); |
||||
orientationPairs[m].weight_dx = int((dx/(norm_sq))*4096.0+0.5); |
||||
orientationPairs[m].weight_dy = int((dy/(norm_sq))*4096.0+0.5); |
||||
} |
||||
|
||||
// build the list of description pairs
|
||||
std::vector<DescriptionPair> allPairs; |
||||
for( unsigned int i = 1; i < (unsigned int)FREAK_NB_POINTS; ++i ) |
||||
{ |
||||
// (generate all the pairs)
|
||||
for( unsigned int j = 0; (unsigned int)j < i; ++j ) |
||||
{ |
||||
DescriptionPair pair = {(uchar)i,(uchar)j}; |
||||
allPairs.push_back(pair); |
||||
} |
||||
} |
||||
// Input vector provided
|
||||
if( !selectedPairs0.empty() ) |
||||
{ |
||||
if( (int)selectedPairs0.size() == FREAK_NB_PAIRS ) |
||||
{ |
||||
for( int i = 0; i < FREAK_NB_PAIRS; ++i ) |
||||
descriptionPairs[i] = allPairs[selectedPairs0.at(i)]; |
||||
} |
||||
else |
||||
{ |
||||
CV_Error(Error::StsVecLengthErr, "Input vector does not match the required size"); |
||||
} |
||||
} |
||||
else // default selected pairs
|
||||
{ |
||||
for( int i = 0; i < FREAK_NB_PAIRS; ++i ) |
||||
descriptionPairs[i] = allPairs[FREAK_DEF_PAIRS[i]]; |
||||
} |
||||
} |
||||
|
||||
void FREAK::computeImpl( InputArray _image, std::vector<KeyPoint>& keypoints, OutputArray _descriptors ) const |
||||
{ |
||||
Mat image = _image.getMat(); |
||||
if( image.empty() ) |
||||
return; |
||||
if( keypoints.empty() ) |
||||
return; |
||||
|
||||
((FREAK*)this)->buildPattern(); |
||||
|
||||
// Convert to gray if not already
|
||||
Mat grayImage = image; |
||||
// if( image.channels() > 1 )
|
||||
// cvtColor( image, grayImage, COLOR_BGR2GRAY );
|
||||
|
||||
// Use 32-bit integers if we won't overflow in the integral image
|
||||
if ((image.depth() == CV_8U || image.depth() == CV_8S) && |
||||
(image.rows * image.cols) < 8388608 ) // 8388608 = 2 ^ (32 - 8(bit depth) - 1(sign bit))
|
||||
{ |
||||
// Create the integral image appropriate for our type & usage
|
||||
if (image.depth() == CV_8U) |
||||
computeDescriptors<uchar, int>(grayImage, keypoints, _descriptors); |
||||
else if (image.depth() == CV_8S) |
||||
computeDescriptors<char, int>(grayImage, keypoints, _descriptors); |
||||
else |
||||
CV_Error( Error::StsUnsupportedFormat, "" ); |
||||
} else { |
||||
// Create the integral image appropriate for our type & usage
|
||||
if ( image.depth() == CV_8U ) |
||||
computeDescriptors<uchar, double>(grayImage, keypoints, _descriptors); |
||||
else if ( image.depth() == CV_8S ) |
||||
computeDescriptors<char, double>(grayImage, keypoints, _descriptors); |
||||
else if ( image.depth() == CV_16U ) |
||||
computeDescriptors<ushort, double>(grayImage, keypoints, _descriptors); |
||||
else if ( image.depth() == CV_16S ) |
||||
computeDescriptors<short, double>(grayImage, keypoints, _descriptors); |
||||
else |
||||
CV_Error( Error::StsUnsupportedFormat, "" ); |
||||
} |
||||
} |
||||
|
||||
template <typename srcMatType> |
||||
void FREAK::extractDescriptor(srcMatType *pointsValue, void ** ptr) const |
||||
{ |
||||
std::bitset<FREAK_NB_PAIRS>** ptrScalar = (std::bitset<FREAK_NB_PAIRS>**) ptr; |
||||
|
||||
// extracting descriptor preserving the order of SSE version
|
||||
int cnt = 0; |
||||
for( int n = 7; n < FREAK_NB_PAIRS; n += 128) |
||||
{ |
||||
for( int m = 8; m--; ) |
||||
{ |
||||
int nm = n-m; |
||||
for(int kk = nm+15*8; kk >= nm; kk-=8, ++cnt) |
||||
{ |
||||
(*ptrScalar)->set(kk, pointsValue[descriptionPairs[cnt].i] >= pointsValue[descriptionPairs[cnt].j]); |
||||
} |
||||
} |
||||
} |
||||
--(*ptrScalar); |
||||
} |
||||
|
||||
#if CV_SSE2 |
||||
template <> |
||||
void FREAK::extractDescriptor(uchar *pointsValue, void ** ptr) const |
||||
{ |
||||
__m128i** ptrSSE = (__m128i**) ptr; |
||||
|
||||
// note that comparisons order is modified in each block (but first 128 comparisons remain globally the same-->does not affect the 128,384 bits segmanted matching strategy)
|
||||
int cnt = 0; |
||||
for( int n = FREAK_NB_PAIRS/128; n-- ; ) |
||||
{ |
||||
__m128i result128 = _mm_setzero_si128(); |
||||
for( int m = 128/16; m--; cnt += 16 ) |
||||
{ |
||||
__m128i operand1 = _mm_set_epi8(pointsValue[descriptionPairs[cnt+0].i], |
||||
pointsValue[descriptionPairs[cnt+1].i], |
||||
pointsValue[descriptionPairs[cnt+2].i], |
||||
pointsValue[descriptionPairs[cnt+3].i], |
||||
pointsValue[descriptionPairs[cnt+4].i], |
||||
pointsValue[descriptionPairs[cnt+5].i], |
||||
pointsValue[descriptionPairs[cnt+6].i], |
||||
pointsValue[descriptionPairs[cnt+7].i], |
||||
pointsValue[descriptionPairs[cnt+8].i], |
||||
pointsValue[descriptionPairs[cnt+9].i], |
||||
pointsValue[descriptionPairs[cnt+10].i], |
||||
pointsValue[descriptionPairs[cnt+11].i], |
||||
pointsValue[descriptionPairs[cnt+12].i], |
||||
pointsValue[descriptionPairs[cnt+13].i], |
||||
pointsValue[descriptionPairs[cnt+14].i], |
||||
pointsValue[descriptionPairs[cnt+15].i]); |
||||
|
||||
__m128i operand2 = _mm_set_epi8(pointsValue[descriptionPairs[cnt+0].j], |
||||
pointsValue[descriptionPairs[cnt+1].j], |
||||
pointsValue[descriptionPairs[cnt+2].j], |
||||
pointsValue[descriptionPairs[cnt+3].j], |
||||
pointsValue[descriptionPairs[cnt+4].j], |
||||
pointsValue[descriptionPairs[cnt+5].j], |
||||
pointsValue[descriptionPairs[cnt+6].j], |
||||
pointsValue[descriptionPairs[cnt+7].j], |
||||
pointsValue[descriptionPairs[cnt+8].j], |
||||
pointsValue[descriptionPairs[cnt+9].j], |
||||
pointsValue[descriptionPairs[cnt+10].j], |
||||
pointsValue[descriptionPairs[cnt+11].j], |
||||
pointsValue[descriptionPairs[cnt+12].j], |
||||
pointsValue[descriptionPairs[cnt+13].j], |
||||
pointsValue[descriptionPairs[cnt+14].j], |
||||
pointsValue[descriptionPairs[cnt+15].j]); |
||||
|
||||
__m128i workReg = _mm_min_epu8(operand1, operand2); // emulated "not less than" for 8-bit UNSIGNED integers
|
||||
workReg = _mm_cmpeq_epi8(workReg, operand2); // emulated "not less than" for 8-bit UNSIGNED integers
|
||||
|
||||
workReg = _mm_and_si128(_mm_set1_epi16(short(0x8080 >> m)), workReg); // merge the last 16 bits with the 128bits std::vector until full
|
||||
result128 = _mm_or_si128(result128, workReg); |
||||
} |
||||
(**ptrSSE) = result128; |
||||
++(*ptrSSE); |
||||
} |
||||
(*ptrSSE) -= 8; |
||||
} |
||||
#endif |
||||
|
||||
template <typename srcMatType, typename iiMatType> |
||||
void FREAK::computeDescriptors( InputArray _image, std::vector<KeyPoint>& keypoints, OutputArray _descriptors ) const { |
||||
|
||||
Mat image = _image.getMat(); |
||||
Mat imgIntegral; |
||||
integral(image, imgIntegral, DataType<iiMatType>::type); |
||||
std::vector<int> kpScaleIdx(keypoints.size()); // used to save pattern scale index corresponding to each keypoints
|
||||
const std::vector<int>::iterator ScaleIdxBegin = kpScaleIdx.begin(); // used in std::vector erase function
|
||||
const std::vector<cv::KeyPoint>::iterator kpBegin = keypoints.begin(); // used in std::vector erase function
|
||||
const float sizeCst = static_cast<float>(FREAK_NB_SCALES/(FREAK_LOG2* nOctaves)); |
||||
srcMatType pointsValue[FREAK_NB_POINTS]; |
||||
int thetaIdx = 0; |
||||
int direction0; |
||||
int direction1; |
||||
|
||||
// compute the scale index corresponding to the keypoint size and remove keypoints close to the border
|
||||
if( scaleNormalized ) |
||||
{ |
||||
for( size_t k = keypoints.size(); k--; ) |
||||
{ |
||||
//Is k non-zero? If so, decrement it and continue"
|
||||
kpScaleIdx[k] = std::max( (int)(std::log(keypoints[k].size/FREAK_SMALLEST_KP_SIZE)*sizeCst+0.5) ,0); |
||||
if( kpScaleIdx[k] >= FREAK_NB_SCALES ) |
||||
kpScaleIdx[k] = FREAK_NB_SCALES-1; |
||||
|
||||
if( keypoints[k].pt.x <= patternSizes[kpScaleIdx[k]] || //check if the description at this specific position and scale fits inside the image
|
||||
keypoints[k].pt.y <= patternSizes[kpScaleIdx[k]] || |
||||
keypoints[k].pt.x >= image.cols-patternSizes[kpScaleIdx[k]] || |
||||
keypoints[k].pt.y >= image.rows-patternSizes[kpScaleIdx[k]] |
||||
) |
||||
{ |
||||
keypoints.erase(kpBegin+k); |
||||
kpScaleIdx.erase(ScaleIdxBegin+k); |
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
const int scIdx = std::max( (int)(1.0986122886681*sizeCst+0.5) ,0); |
||||
for( size_t k = keypoints.size(); k--; ) |
||||
{ |
||||
kpScaleIdx[k] = scIdx; // equivalent to the formule when the scale is normalized with a constant size of keypoints[k].size=3*SMALLEST_KP_SIZE
|
||||
if( kpScaleIdx[k] >= FREAK_NB_SCALES ) |
||||
{ |
||||
kpScaleIdx[k] = FREAK_NB_SCALES-1; |
||||
} |
||||
if( keypoints[k].pt.x <= patternSizes[kpScaleIdx[k]] || |
||||
keypoints[k].pt.y <= patternSizes[kpScaleIdx[k]] || |
||||
keypoints[k].pt.x >= image.cols-patternSizes[kpScaleIdx[k]] || |
||||
keypoints[k].pt.y >= image.rows-patternSizes[kpScaleIdx[k]] |
||||
) |
||||
{ |
||||
keypoints.erase(kpBegin+k); |
||||
kpScaleIdx.erase(ScaleIdxBegin+k); |
||||
} |
||||
} |
||||
} |
||||
|
||||
// allocate descriptor memory, estimate orientations, extract descriptors
|
||||
if( !extAll ) |
||||
{ |
||||
// extract the best comparisons only
|
||||
_descriptors.create((int)keypoints.size(), FREAK_NB_PAIRS/8, CV_8U); |
||||
_descriptors.setTo(Scalar::all(0)); |
||||
Mat descriptors = _descriptors.getMat(); |
||||
|
||||
void *ptr = descriptors.data+(keypoints.size()-1)*descriptors.step[0]; |
||||
|
||||
for( size_t k = keypoints.size(); k--; ) { |
||||
// estimate orientation (gradient)
|
||||
if( !orientationNormalized ) |
||||
{ |
||||
thetaIdx = 0; // assign 0° to all keypoints
|
||||
keypoints[k].angle = 0.0; |
||||
} |
||||
else |
||||
{ |
||||
// get the points intensity value in the un-rotated pattern
|
||||
for( int i = FREAK_NB_POINTS; i--; ) { |
||||
pointsValue[i] = meanIntensity<srcMatType, iiMatType>(image, imgIntegral, |
||||
keypoints[k].pt.x, keypoints[k].pt.y, |
||||
kpScaleIdx[k], 0, i); |
||||
} |
||||
direction0 = 0; |
||||
direction1 = 0; |
||||
for( int m = 45; m--; ) |
||||
{ |
||||
//iterate through the orientation pairs
|
||||
const int delta = (pointsValue[ orientationPairs[m].i ]-pointsValue[ orientationPairs[m].j ]); |
||||
direction0 += delta*(orientationPairs[m].weight_dx)/2048; |
||||
direction1 += delta*(orientationPairs[m].weight_dy)/2048; |
||||
} |
||||
|
||||
keypoints[k].angle = static_cast<float>(atan2((float)direction1,(float)direction0)*(180.0/CV_PI));//estimate orientation
|
||||
thetaIdx = int(FREAK_NB_ORIENTATION*keypoints[k].angle*(1/360.0)+0.5); |
||||
if( thetaIdx < 0 ) |
||||
thetaIdx += FREAK_NB_ORIENTATION; |
||||
|
||||
if( thetaIdx >= FREAK_NB_ORIENTATION ) |
||||
thetaIdx -= FREAK_NB_ORIENTATION; |
||||
} |
||||
// extract descriptor at the computed orientation
|
||||
for( int i = FREAK_NB_POINTS; i--; ) { |
||||
pointsValue[i] = meanIntensity<srcMatType, iiMatType>(image, imgIntegral, |
||||
keypoints[k].pt.x, keypoints[k].pt.y, |
||||
kpScaleIdx[k], thetaIdx, i); |
||||
} |
||||
|
||||
// Extract descriptor
|
||||
extractDescriptor<srcMatType>(pointsValue, &ptr); |
||||
} |
||||
} |
||||
else // extract all possible comparisons for selection
|
||||
{ |
||||
_descriptors.create((int)keypoints.size(), 128, CV_8U); |
||||
_descriptors.setTo(Scalar::all(0)); |
||||
Mat descriptors = _descriptors.getMat(); |
||||
std::bitset<1024>* ptr = (std::bitset<1024>*) (descriptors.data+(keypoints.size()-1)*descriptors.step[0]); |
||||
|
||||
for( size_t k = keypoints.size(); k--; ) |
||||
{ |
||||
//estimate orientation (gradient)
|
||||
if( !orientationNormalized ) |
||||
{ |
||||
thetaIdx = 0;//assign 0° to all keypoints
|
||||
keypoints[k].angle = 0.0; |
||||
} |
||||
else |
||||
{ |
||||
//get the points intensity value in the un-rotated pattern
|
||||
for( int i = FREAK_NB_POINTS;i--; ) |
||||
pointsValue[i] = meanIntensity<srcMatType, iiMatType>(image, imgIntegral, |
||||
keypoints[k].pt.x,keypoints[k].pt.y, |
||||
kpScaleIdx[k], 0, i); |
||||
|
||||
direction0 = 0; |
||||
direction1 = 0; |
||||
for( int m = 45; m--; ) |
||||
{ |
||||
//iterate through the orientation pairs
|
||||
const int delta = (pointsValue[ orientationPairs[m].i ]-pointsValue[ orientationPairs[m].j ]); |
||||
direction0 += delta*(orientationPairs[m].weight_dx)/2048; |
||||
direction1 += delta*(orientationPairs[m].weight_dy)/2048; |
||||
} |
||||
|
||||
keypoints[k].angle = static_cast<float>(atan2((float)direction1,(float)direction0)*(180.0/CV_PI)); //estimate orientation
|
||||
thetaIdx = int(FREAK_NB_ORIENTATION*keypoints[k].angle*(1/360.0)+0.5); |
||||
|
||||
if( thetaIdx < 0 ) |
||||
thetaIdx += FREAK_NB_ORIENTATION; |
||||
|
||||
if( thetaIdx >= FREAK_NB_ORIENTATION ) |
||||
thetaIdx -= FREAK_NB_ORIENTATION; |
||||
} |
||||
// get the points intensity value in the rotated pattern
|
||||
for( int i = FREAK_NB_POINTS; i--; ) { |
||||
pointsValue[i] = meanIntensity<srcMatType, iiMatType>(image, imgIntegral, |
||||
keypoints[k].pt.x, keypoints[k].pt.y, |
||||
kpScaleIdx[k], thetaIdx, i); |
||||
} |
||||
|
||||
int cnt(0); |
||||
for( int i = 1; i < FREAK_NB_POINTS; ++i ) |
||||
{ |
||||
//(generate all the pairs)
|
||||
for( int j = 0; j < i; ++j ) |
||||
{ |
||||
ptr->set(cnt, pointsValue[i] >= pointsValue[j] ); |
||||
++cnt; |
||||
} |
||||
} |
||||
--ptr; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// simply take average on a square patch, not even gaussian approx
|
||||
template <typename imgType, typename iiType> |
||||
imgType FREAK::meanIntensity( InputArray _image, InputArray _integral, |
||||
const float kp_x, |
||||
const float kp_y, |
||||
const unsigned int scale, |
||||
const unsigned int rot, |
||||
const unsigned int point) const { |
||||
Mat image = _image.getMat(), integral = _integral.getMat(); |
||||
// get point position in image
|
||||
const PatternPoint& FreakPoint = patternLookup[scale*FREAK_NB_ORIENTATION*FREAK_NB_POINTS + rot*FREAK_NB_POINTS + point]; |
||||
const float xf = FreakPoint.x+kp_x; |
||||
const float yf = FreakPoint.y+kp_y; |
||||
const int x = int(xf); |
||||
const int y = int(yf); |
||||
|
||||
// get the sigma:
|
||||
const float radius = FreakPoint.sigma; |
||||
|
||||
// calculate output:
|
||||
if( radius < 0.5 ) |
||||
{ |
||||
// interpolation multipliers:
|
||||
const int r_x = static_cast<int>((xf-x)*1024); |
||||
const int r_y = static_cast<int>((yf-y)*1024); |
||||
const int r_x_1 = (1024-r_x); |
||||
const int r_y_1 = (1024-r_y); |
||||
unsigned int ret_val; |
||||
// linear interpolation:
|
||||
ret_val = r_x_1*r_y_1*int(image.at<imgType>(y , x )) |
||||
+ r_x *r_y_1*int(image.at<imgType>(y , x+1)) |
||||
+ r_x_1*r_y *int(image.at<imgType>(y+1, x )) |
||||
+ r_x *r_y *int(image.at<imgType>(y+1, x+1)); |
||||
//return the rounded mean
|
||||
ret_val += 2 * 1024 * 1024; |
||||
return static_cast<imgType>(ret_val / (4 * 1024 * 1024)); |
||||
} |
||||
|
||||
// expected case:
|
||||
|
||||
// calculate borders
|
||||
const int x_left = int(xf-radius+0.5); |
||||
const int y_top = int(yf-radius+0.5); |
||||
const int x_right = int(xf+radius+1.5);//integral image is 1px wider
|
||||
const int y_bottom = int(yf+radius+1.5);//integral image is 1px higher
|
||||
iiType ret_val; |
||||
|
||||
ret_val = integral.at<iiType>(y_bottom,x_right);//bottom right corner
|
||||
ret_val -= integral.at<iiType>(y_bottom,x_left); |
||||
ret_val += integral.at<iiType>(y_top,x_left); |
||||
ret_val -= integral.at<iiType>(y_top,x_right); |
||||
ret_val = ret_val/( (x_right-x_left)* (y_bottom-y_top) ); |
||||
//~ std::cout<<integral.step[1]<<std::endl;
|
||||
return static_cast<imgType>(ret_val); |
||||
} |
||||
|
||||
// pair selection algorithm from a set of training images and corresponding keypoints
|
||||
std::vector<int> FREAK::selectPairs(const std::vector<Mat>& images |
||||
, std::vector<std::vector<KeyPoint> >& keypoints |
||||
, const double corrTresh |
||||
, bool verbose ) |
||||
{ |
||||
extAll = true; |
||||
// compute descriptors with all pairs
|
||||
Mat descriptors; |
||||
|
||||
if( verbose ) |
||||
std::cout << "Number of images: " << images.size() << std::endl; |
||||
|
||||
for( size_t i = 0;i < images.size(); ++i ) |
||||
{ |
||||
Mat descriptorsTmp; |
||||
computeImpl(images[i],keypoints[i],descriptorsTmp); |
||||
descriptors.push_back(descriptorsTmp); |
||||
} |
||||
|
||||
if( verbose ) |
||||
std::cout << "number of keypoints: " << descriptors.rows << std::endl; |
||||
|
||||
//descriptor in floating point format (each bit is a float)
|
||||
Mat descriptorsFloat = Mat::zeros(descriptors.rows, 903, CV_32F); |
||||
|
||||
std::bitset<1024>* ptr = (std::bitset<1024>*) (descriptors.data+(descriptors.rows-1)*descriptors.step[0]); |
||||
for( int m = descriptors.rows; m--; ) |
||||
{ |
||||
for( int n = 903; n--; ) |
||||
{ |
||||
if( ptr->test(n) == true ) |
||||
descriptorsFloat.at<float>(m,n)=1.0f; |
||||
} |
||||
--ptr; |
||||
} |
||||
|
||||
std::vector<PairStat> pairStat; |
||||
for( int n = 903; n--; ) |
||||
{ |
||||
// the higher the variance, the better --> mean = 0.5
|
||||
PairStat tmp = { fabs( mean(descriptorsFloat.col(n))[0]-0.5 ) ,n}; |
||||
pairStat.push_back(tmp); |
||||
} |
||||
|
||||
std::sort( pairStat.begin(),pairStat.end(), sortMean() ); |
||||
|
||||
std::vector<PairStat> bestPairs; |
||||
for( int m = 0; m < 903; ++m ) |
||||
{ |
||||
if( verbose ) |
||||
std::cout << m << ":" << bestPairs.size() << " " << std::flush; |
||||
double corrMax(0); |
||||
|
||||
for( size_t n = 0; n < bestPairs.size(); ++n ) |
||||
{ |
||||
int idxA = bestPairs[n].idx; |
||||
int idxB = pairStat[m].idx; |
||||
double corr(0); |
||||
// compute correlation between 2 pairs
|
||||
corr = fabs(compareHist(descriptorsFloat.col(idxA), descriptorsFloat.col(idxB), HISTCMP_CORREL)); |
||||
|
||||
if( corr > corrMax ) |
||||
{ |
||||
corrMax = corr; |
||||
if( corrMax >= corrTresh ) |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if( corrMax < corrTresh/*0.7*/ ) |
||||
bestPairs.push_back(pairStat[m]); |
||||
|
||||
if( bestPairs.size() >= 512 ) |
||||
{ |
||||
if( verbose ) |
||||
std::cout << m << std::endl; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
std::vector<int> idxBestPairs; |
||||
if( (int)bestPairs.size() >= FREAK_NB_PAIRS ) |
||||
{ |
||||
for( int i = 0; i < FREAK_NB_PAIRS; ++i ) |
||||
idxBestPairs.push_back(bestPairs[i].idx); |
||||
} |
||||
else |
||||
{ |
||||
if( verbose ) |
||||
std::cout << "correlation threshold too small (restrictive)" << std::endl; |
||||
CV_Error(Error::StsError, "correlation threshold too small (restrictive)"); |
||||
} |
||||
extAll = false; |
||||
return idxBestPairs; |
||||
} |
||||
|
||||
|
||||
/*
|
||||
// create an image showing the brisk pattern
|
||||
void FREAKImpl::drawPattern() |
||||
{ |
||||
Mat pattern = Mat::zeros(1000, 1000, CV_8UC3) + Scalar(255,255,255); |
||||
int sFac = 500 / patternScale; |
||||
for( int n = 0; n < kNB_POINTS; ++n ) |
||||
{ |
||||
PatternPoint& pt = patternLookup[n]; |
||||
circle(pattern, Point( pt.x*sFac,pt.y*sFac)+Point(500,500), pt.sigma*sFac, Scalar(0,0,255),2); |
||||
// rectangle(pattern, Point( (pt.x-pt.sigma)*sFac,(pt.y-pt.sigma)*sFac)+Point(500,500), Point( (pt.x+pt.sigma)*sFac,(pt.y+pt.sigma)*sFac)+Point(500,500), Scalar(0,0,255),2);
|
||||
|
||||
circle(pattern, Point( pt.x*sFac,pt.y*sFac)+Point(500,500), 1, Scalar(0,0,0),3); |
||||
std::ostringstream oss; |
||||
oss << n; |
||||
putText( pattern, oss.str(), Point( pt.x*sFac,pt.y*sFac)+Point(500,500), FONT_HERSHEY_SIMPLEX,0.5, Scalar(0,0,0), 1); |
||||
} |
||||
imshow( "FreakDescriptorExtractor pattern", pattern ); |
||||
waitKey(0); |
||||
} |
||||
*/ |
||||
|
||||
// -------------------------------------------------
|
||||
/* FREAK interface implementation */ |
||||
FREAK::FREAK( bool _orientationNormalized, bool _scaleNormalized |
||||
, float _patternScale, int _nOctaves, const std::vector<int>& _selectedPairs ) |
||||
: orientationNormalized(_orientationNormalized), scaleNormalized(_scaleNormalized), |
||||
patternScale(_patternScale), nOctaves(_nOctaves), extAll(false), nOctaves0(0), selectedPairs0(_selectedPairs) |
||||
{ |
||||
} |
||||
|
||||
FREAK::~FREAK() |
||||
{ |
||||
} |
||||
|
||||
int FREAK::descriptorSize() const |
||||
{ |
||||
return FREAK_NB_PAIRS / 8; // descriptor length in bytes
|
||||
} |
||||
|
||||
int FREAK::descriptorType() const |
||||
{ |
||||
return CV_8U; |
||||
} |
||||
|
||||
int FREAK::defaultNorm() const |
||||
{ |
||||
return NORM_HAMMING; |
||||
} |
||||
|
||||
} // END NAMESPACE CV
|
@ -1,19 +0,0 @@ |
||||
// Code generated with '$ scripts/generate_code.py src/test_pairs.txt 16' |
||||
#define SMOOTHED(y,x) smoothedSum(sum, pt, y, x) |
||||
desc[0] = (uchar)(((SMOOTHED(-2, -1) < SMOOTHED(7, -1)) << 7) + ((SMOOTHED(-14, -1) < SMOOTHED(-3, 3)) << 6) + ((SMOOTHED(1, -2) < SMOOTHED(11, 2)) << 5) + ((SMOOTHED(1, 6) < SMOOTHED(-10, -7)) << 4) + ((SMOOTHED(13, 2) < SMOOTHED(-1, 0)) << 3) + ((SMOOTHED(-14, 5) < SMOOTHED(5, -3)) << 2) + ((SMOOTHED(-2, 8) < SMOOTHED(2, 4)) << 1) + ((SMOOTHED(-11, 8) < SMOOTHED(-15, 5)) << 0)); |
||||
desc[1] = (uchar)(((SMOOTHED(-6, -23) < SMOOTHED(8, -9)) << 7) + ((SMOOTHED(-12, 6) < SMOOTHED(-10, 8)) << 6) + ((SMOOTHED(-3, -1) < SMOOTHED(8, 1)) << 5) + ((SMOOTHED(3, 6) < SMOOTHED(5, 6)) << 4) + ((SMOOTHED(-7, -6) < SMOOTHED(5, -5)) << 3) + ((SMOOTHED(22, -2) < SMOOTHED(-11, -8)) << 2) + ((SMOOTHED(14, 7) < SMOOTHED(8, 5)) << 1) + ((SMOOTHED(-1, 14) < SMOOTHED(-5, -14)) << 0)); |
||||
desc[2] = (uchar)(((SMOOTHED(-14, 9) < SMOOTHED(2, 0)) << 7) + ((SMOOTHED(7, -3) < SMOOTHED(22, 6)) << 6) + ((SMOOTHED(-6, 6) < SMOOTHED(-8, -5)) << 5) + ((SMOOTHED(-5, 9) < SMOOTHED(7, -1)) << 4) + ((SMOOTHED(-3, -7) < SMOOTHED(-10, -18)) << 3) + ((SMOOTHED(4, -5) < SMOOTHED(0, 11)) << 2) + ((SMOOTHED(2, 3) < SMOOTHED(9, 10)) << 1) + ((SMOOTHED(-10, 3) < SMOOTHED(4, 9)) << 0)); |
||||
desc[3] = (uchar)(((SMOOTHED(0, 12) < SMOOTHED(-3, 19)) << 7) + ((SMOOTHED(1, 15) < SMOOTHED(-11, -5)) << 6) + ((SMOOTHED(14, -1) < SMOOTHED(7, 8)) << 5) + ((SMOOTHED(7, -23) < SMOOTHED(-5, 5)) << 4) + ((SMOOTHED(0, -6) < SMOOTHED(-10, 17)) << 3) + ((SMOOTHED(13, -4) < SMOOTHED(-3, -4)) << 2) + ((SMOOTHED(-12, 1) < SMOOTHED(-12, 2)) << 1) + ((SMOOTHED(0, 8) < SMOOTHED(3, 22)) << 0)); |
||||
desc[4] = (uchar)(((SMOOTHED(-13, 13) < SMOOTHED(3, -1)) << 7) + ((SMOOTHED(-16, 17) < SMOOTHED(6, 10)) << 6) + ((SMOOTHED(7, 15) < SMOOTHED(-5, 0)) << 5) + ((SMOOTHED(2, -12) < SMOOTHED(19, -2)) << 4) + ((SMOOTHED(3, -6) < SMOOTHED(-4, -15)) << 3) + ((SMOOTHED(8, 3) < SMOOTHED(0, 14)) << 2) + ((SMOOTHED(4, -11) < SMOOTHED(5, 5)) << 1) + ((SMOOTHED(11, -7) < SMOOTHED(7, 1)) << 0)); |
||||
desc[5] = (uchar)(((SMOOTHED(6, 12) < SMOOTHED(21, 3)) << 7) + ((SMOOTHED(-3, 2) < SMOOTHED(14, 1)) << 6) + ((SMOOTHED(5, 1) < SMOOTHED(-5, 11)) << 5) + ((SMOOTHED(3, -17) < SMOOTHED(-6, 2)) << 4) + ((SMOOTHED(6, 8) < SMOOTHED(5, -10)) << 3) + ((SMOOTHED(-14, -2) < SMOOTHED(0, 4)) << 2) + ((SMOOTHED(5, -7) < SMOOTHED(-6, 5)) << 1) + ((SMOOTHED(10, 4) < SMOOTHED(4, -7)) << 0)); |
||||
desc[6] = (uchar)(((SMOOTHED(22, 0) < SMOOTHED(7, -18)) << 7) + ((SMOOTHED(-1, -3) < SMOOTHED(0, 18)) << 6) + ((SMOOTHED(-4, 22) < SMOOTHED(-5, 3)) << 5) + ((SMOOTHED(1, -7) < SMOOTHED(2, -3)) << 4) + ((SMOOTHED(19, -20) < SMOOTHED(17, -2)) << 3) + ((SMOOTHED(3, -10) < SMOOTHED(-8, 24)) << 2) + ((SMOOTHED(-5, -14) < SMOOTHED(7, 5)) << 1) + ((SMOOTHED(-2, 12) < SMOOTHED(-4, -15)) << 0)); |
||||
desc[7] = (uchar)(((SMOOTHED(4, 12) < SMOOTHED(0, -19)) << 7) + ((SMOOTHED(20, 13) < SMOOTHED(3, 5)) << 6) + ((SMOOTHED(-8, -12) < SMOOTHED(5, 0)) << 5) + ((SMOOTHED(-5, 6) < SMOOTHED(-7, -11)) << 4) + ((SMOOTHED(6, -11) < SMOOTHED(-3, -22)) << 3) + ((SMOOTHED(15, 4) < SMOOTHED(10, 1)) << 2) + ((SMOOTHED(-7, -4) < SMOOTHED(15, -6)) << 1) + ((SMOOTHED(5, 10) < SMOOTHED(0, 24)) << 0)); |
||||
desc[8] = (uchar)(((SMOOTHED(3, 6) < SMOOTHED(22, -2)) << 7) + ((SMOOTHED(-13, 14) < SMOOTHED(4, -4)) << 6) + ((SMOOTHED(-13, 8) < SMOOTHED(-18, -22)) << 5) + ((SMOOTHED(-1, -1) < SMOOTHED(-7, 3)) << 4) + ((SMOOTHED(-19, -12) < SMOOTHED(4, 3)) << 3) + ((SMOOTHED(8, 10) < SMOOTHED(13, -2)) << 2) + ((SMOOTHED(-6, -1) < SMOOTHED(-6, -5)) << 1) + ((SMOOTHED(2, -21) < SMOOTHED(-3, 2)) << 0)); |
||||
desc[9] = (uchar)(((SMOOTHED(4, -7) < SMOOTHED(0, 16)) << 7) + ((SMOOTHED(-6, -5) < SMOOTHED(-12, -1)) << 6) + ((SMOOTHED(1, -1) < SMOOTHED(9, 18)) << 5) + ((SMOOTHED(-7, 10) < SMOOTHED(-11, 6)) << 4) + ((SMOOTHED(4, 3) < SMOOTHED(19, -7)) << 3) + ((SMOOTHED(-18, 5) < SMOOTHED(-4, 5)) << 2) + ((SMOOTHED(4, 0) < SMOOTHED(-20, 4)) << 1) + ((SMOOTHED(7, -11) < SMOOTHED(18, 12)) << 0)); |
||||
desc[10] = (uchar)(((SMOOTHED(-20, 17) < SMOOTHED(-18, 7)) << 7) + ((SMOOTHED(2, 15) < SMOOTHED(19, -11)) << 6) + ((SMOOTHED(-18, 6) < SMOOTHED(-7, 3)) << 5) + ((SMOOTHED(-4, 1) < SMOOTHED(-14, 13)) << 4) + ((SMOOTHED(17, 3) < SMOOTHED(2, -8)) << 3) + ((SMOOTHED(-7, 2) < SMOOTHED(1, 6)) << 2) + ((SMOOTHED(17, -9) < SMOOTHED(-2, 8)) << 1) + ((SMOOTHED(-8, -6) < SMOOTHED(-1, 12)) << 0)); |
||||
desc[11] = (uchar)(((SMOOTHED(-2, 4) < SMOOTHED(-1, 6)) << 7) + ((SMOOTHED(-2, 7) < SMOOTHED(6, 8)) << 6) + ((SMOOTHED(-8, -1) < SMOOTHED(-7, -9)) << 5) + ((SMOOTHED(8, -9) < SMOOTHED(15, 0)) << 4) + ((SMOOTHED(0, 22) < SMOOTHED(-4, -15)) << 3) + ((SMOOTHED(-14, -1) < SMOOTHED(3, -2)) << 2) + ((SMOOTHED(-7, -4) < SMOOTHED(17, -7)) << 1) + ((SMOOTHED(-8, -2) < SMOOTHED(9, -4)) << 0)); |
||||
desc[12] = (uchar)(((SMOOTHED(5, -7) < SMOOTHED(7, 7)) << 7) + ((SMOOTHED(-5, 13) < SMOOTHED(-8, 11)) << 6) + ((SMOOTHED(11, -4) < SMOOTHED(0, 8)) << 5) + ((SMOOTHED(5, -11) < SMOOTHED(-9, -6)) << 4) + ((SMOOTHED(2, -6) < SMOOTHED(3, -20)) << 3) + ((SMOOTHED(-6, 2) < SMOOTHED(6, 10)) << 2) + ((SMOOTHED(-6, -6) < SMOOTHED(-15, 7)) << 1) + ((SMOOTHED(-6, -3) < SMOOTHED(2, 1)) << 0)); |
||||
desc[13] = (uchar)(((SMOOTHED(11, 0) < SMOOTHED(-3, 2)) << 7) + ((SMOOTHED(7, -12) < SMOOTHED(14, 5)) << 6) + ((SMOOTHED(0, -7) < SMOOTHED(-1, -1)) << 5) + ((SMOOTHED(-16, 0) < SMOOTHED(6, 8)) << 4) + ((SMOOTHED(22, 11) < SMOOTHED(0, -3)) << 3) + ((SMOOTHED(19, 0) < SMOOTHED(5, -17)) << 2) + ((SMOOTHED(-23, -14) < SMOOTHED(-13, -19)) << 1) + ((SMOOTHED(-8, 10) < SMOOTHED(-11, -2)) << 0)); |
||||
desc[14] = (uchar)(((SMOOTHED(-11, 6) < SMOOTHED(-10, 13)) << 7) + ((SMOOTHED(1, -7) < SMOOTHED(14, 0)) << 6) + ((SMOOTHED(-12, 1) < SMOOTHED(-5, -5)) << 5) + ((SMOOTHED(4, 7) < SMOOTHED(8, -1)) << 4) + ((SMOOTHED(-1, -5) < SMOOTHED(15, 2)) << 3) + ((SMOOTHED(-3, -1) < SMOOTHED(7, -10)) << 2) + ((SMOOTHED(3, -6) < SMOOTHED(10, -18)) << 1) + ((SMOOTHED(-7, -13) < SMOOTHED(-13, 10)) << 0)); |
||||
desc[15] = (uchar)(((SMOOTHED(1, -1) < SMOOTHED(13, -10)) << 7) + ((SMOOTHED(-19, 14) < SMOOTHED(8, -14)) << 6) + ((SMOOTHED(-4, -13) < SMOOTHED(7, 1)) << 5) + ((SMOOTHED(1, -2) < SMOOTHED(12, -7)) << 4) + ((SMOOTHED(3, -5) < SMOOTHED(1, -5)) << 3) + ((SMOOTHED(-2, -2) < SMOOTHED(8, -10)) << 2) + ((SMOOTHED(2, 14) < SMOOTHED(8, 7)) << 1) + ((SMOOTHED(3, 9) < SMOOTHED(8, 2)) << 0)); |
||||
#undef SMOOTHED |
@ -1,35 +0,0 @@ |
||||
// Code generated with '$ scripts/generate_code.py src/test_pairs.txt 32' |
||||
#define SMOOTHED(y,x) smoothedSum(sum, pt, y, x) |
||||
desc[0] = (uchar)(((SMOOTHED(-2, -1) < SMOOTHED(7, -1)) << 7) + ((SMOOTHED(-14, -1) < SMOOTHED(-3, 3)) << 6) + ((SMOOTHED(1, -2) < SMOOTHED(11, 2)) << 5) + ((SMOOTHED(1, 6) < SMOOTHED(-10, -7)) << 4) + ((SMOOTHED(13, 2) < SMOOTHED(-1, 0)) << 3) + ((SMOOTHED(-14, 5) < SMOOTHED(5, -3)) << 2) + ((SMOOTHED(-2, 8) < SMOOTHED(2, 4)) << 1) + ((SMOOTHED(-11, 8) < SMOOTHED(-15, 5)) << 0)); |
||||
desc[1] = (uchar)(((SMOOTHED(-6, -23) < SMOOTHED(8, -9)) << 7) + ((SMOOTHED(-12, 6) < SMOOTHED(-10, 8)) << 6) + ((SMOOTHED(-3, -1) < SMOOTHED(8, 1)) << 5) + ((SMOOTHED(3, 6) < SMOOTHED(5, 6)) << 4) + ((SMOOTHED(-7, -6) < SMOOTHED(5, -5)) << 3) + ((SMOOTHED(22, -2) < SMOOTHED(-11, -8)) << 2) + ((SMOOTHED(14, 7) < SMOOTHED(8, 5)) << 1) + ((SMOOTHED(-1, 14) < SMOOTHED(-5, -14)) << 0)); |
||||
desc[2] = (uchar)(((SMOOTHED(-14, 9) < SMOOTHED(2, 0)) << 7) + ((SMOOTHED(7, -3) < SMOOTHED(22, 6)) << 6) + ((SMOOTHED(-6, 6) < SMOOTHED(-8, -5)) << 5) + ((SMOOTHED(-5, 9) < SMOOTHED(7, -1)) << 4) + ((SMOOTHED(-3, -7) < SMOOTHED(-10, -18)) << 3) + ((SMOOTHED(4, -5) < SMOOTHED(0, 11)) << 2) + ((SMOOTHED(2, 3) < SMOOTHED(9, 10)) << 1) + ((SMOOTHED(-10, 3) < SMOOTHED(4, 9)) << 0)); |
||||
desc[3] = (uchar)(((SMOOTHED(0, 12) < SMOOTHED(-3, 19)) << 7) + ((SMOOTHED(1, 15) < SMOOTHED(-11, -5)) << 6) + ((SMOOTHED(14, -1) < SMOOTHED(7, 8)) << 5) + ((SMOOTHED(7, -23) < SMOOTHED(-5, 5)) << 4) + ((SMOOTHED(0, -6) < SMOOTHED(-10, 17)) << 3) + ((SMOOTHED(13, -4) < SMOOTHED(-3, -4)) << 2) + ((SMOOTHED(-12, 1) < SMOOTHED(-12, 2)) << 1) + ((SMOOTHED(0, 8) < SMOOTHED(3, 22)) << 0)); |
||||
desc[4] = (uchar)(((SMOOTHED(-13, 13) < SMOOTHED(3, -1)) << 7) + ((SMOOTHED(-16, 17) < SMOOTHED(6, 10)) << 6) + ((SMOOTHED(7, 15) < SMOOTHED(-5, 0)) << 5) + ((SMOOTHED(2, -12) < SMOOTHED(19, -2)) << 4) + ((SMOOTHED(3, -6) < SMOOTHED(-4, -15)) << 3) + ((SMOOTHED(8, 3) < SMOOTHED(0, 14)) << 2) + ((SMOOTHED(4, -11) < SMOOTHED(5, 5)) << 1) + ((SMOOTHED(11, -7) < SMOOTHED(7, 1)) << 0)); |
||||
desc[5] = (uchar)(((SMOOTHED(6, 12) < SMOOTHED(21, 3)) << 7) + ((SMOOTHED(-3, 2) < SMOOTHED(14, 1)) << 6) + ((SMOOTHED(5, 1) < SMOOTHED(-5, 11)) << 5) + ((SMOOTHED(3, -17) < SMOOTHED(-6, 2)) << 4) + ((SMOOTHED(6, 8) < SMOOTHED(5, -10)) << 3) + ((SMOOTHED(-14, -2) < SMOOTHED(0, 4)) << 2) + ((SMOOTHED(5, -7) < SMOOTHED(-6, 5)) << 1) + ((SMOOTHED(10, 4) < SMOOTHED(4, -7)) << 0)); |
||||
desc[6] = (uchar)(((SMOOTHED(22, 0) < SMOOTHED(7, -18)) << 7) + ((SMOOTHED(-1, -3) < SMOOTHED(0, 18)) << 6) + ((SMOOTHED(-4, 22) < SMOOTHED(-5, 3)) << 5) + ((SMOOTHED(1, -7) < SMOOTHED(2, -3)) << 4) + ((SMOOTHED(19, -20) < SMOOTHED(17, -2)) << 3) + ((SMOOTHED(3, -10) < SMOOTHED(-8, 24)) << 2) + ((SMOOTHED(-5, -14) < SMOOTHED(7, 5)) << 1) + ((SMOOTHED(-2, 12) < SMOOTHED(-4, -15)) << 0)); |
||||
desc[7] = (uchar)(((SMOOTHED(4, 12) < SMOOTHED(0, -19)) << 7) + ((SMOOTHED(20, 13) < SMOOTHED(3, 5)) << 6) + ((SMOOTHED(-8, -12) < SMOOTHED(5, 0)) << 5) + ((SMOOTHED(-5, 6) < SMOOTHED(-7, -11)) << 4) + ((SMOOTHED(6, -11) < SMOOTHED(-3, -22)) << 3) + ((SMOOTHED(15, 4) < SMOOTHED(10, 1)) << 2) + ((SMOOTHED(-7, -4) < SMOOTHED(15, -6)) << 1) + ((SMOOTHED(5, 10) < SMOOTHED(0, 24)) << 0)); |
||||
desc[8] = (uchar)(((SMOOTHED(3, 6) < SMOOTHED(22, -2)) << 7) + ((SMOOTHED(-13, 14) < SMOOTHED(4, -4)) << 6) + ((SMOOTHED(-13, 8) < SMOOTHED(-18, -22)) << 5) + ((SMOOTHED(-1, -1) < SMOOTHED(-7, 3)) << 4) + ((SMOOTHED(-19, -12) < SMOOTHED(4, 3)) << 3) + ((SMOOTHED(8, 10) < SMOOTHED(13, -2)) << 2) + ((SMOOTHED(-6, -1) < SMOOTHED(-6, -5)) << 1) + ((SMOOTHED(2, -21) < SMOOTHED(-3, 2)) << 0)); |
||||
desc[9] = (uchar)(((SMOOTHED(4, -7) < SMOOTHED(0, 16)) << 7) + ((SMOOTHED(-6, -5) < SMOOTHED(-12, -1)) << 6) + ((SMOOTHED(1, -1) < SMOOTHED(9, 18)) << 5) + ((SMOOTHED(-7, 10) < SMOOTHED(-11, 6)) << 4) + ((SMOOTHED(4, 3) < SMOOTHED(19, -7)) << 3) + ((SMOOTHED(-18, 5) < SMOOTHED(-4, 5)) << 2) + ((SMOOTHED(4, 0) < SMOOTHED(-20, 4)) << 1) + ((SMOOTHED(7, -11) < SMOOTHED(18, 12)) << 0)); |
||||
desc[10] = (uchar)(((SMOOTHED(-20, 17) < SMOOTHED(-18, 7)) << 7) + ((SMOOTHED(2, 15) < SMOOTHED(19, -11)) << 6) + ((SMOOTHED(-18, 6) < SMOOTHED(-7, 3)) << 5) + ((SMOOTHED(-4, 1) < SMOOTHED(-14, 13)) << 4) + ((SMOOTHED(17, 3) < SMOOTHED(2, -8)) << 3) + ((SMOOTHED(-7, 2) < SMOOTHED(1, 6)) << 2) + ((SMOOTHED(17, -9) < SMOOTHED(-2, 8)) << 1) + ((SMOOTHED(-8, -6) < SMOOTHED(-1, 12)) << 0)); |
||||
desc[11] = (uchar)(((SMOOTHED(-2, 4) < SMOOTHED(-1, 6)) << 7) + ((SMOOTHED(-2, 7) < SMOOTHED(6, 8)) << 6) + ((SMOOTHED(-8, -1) < SMOOTHED(-7, -9)) << 5) + ((SMOOTHED(8, -9) < SMOOTHED(15, 0)) << 4) + ((SMOOTHED(0, 22) < SMOOTHED(-4, -15)) << 3) + ((SMOOTHED(-14, -1) < SMOOTHED(3, -2)) << 2) + ((SMOOTHED(-7, -4) < SMOOTHED(17, -7)) << 1) + ((SMOOTHED(-8, -2) < SMOOTHED(9, -4)) << 0)); |
||||
desc[12] = (uchar)(((SMOOTHED(5, -7) < SMOOTHED(7, 7)) << 7) + ((SMOOTHED(-5, 13) < SMOOTHED(-8, 11)) << 6) + ((SMOOTHED(11, -4) < SMOOTHED(0, 8)) << 5) + ((SMOOTHED(5, -11) < SMOOTHED(-9, -6)) << 4) + ((SMOOTHED(2, -6) < SMOOTHED(3, -20)) << 3) + ((SMOOTHED(-6, 2) < SMOOTHED(6, 10)) << 2) + ((SMOOTHED(-6, -6) < SMOOTHED(-15, 7)) << 1) + ((SMOOTHED(-6, -3) < SMOOTHED(2, 1)) << 0)); |
||||
desc[13] = (uchar)(((SMOOTHED(11, 0) < SMOOTHED(-3, 2)) << 7) + ((SMOOTHED(7, -12) < SMOOTHED(14, 5)) << 6) + ((SMOOTHED(0, -7) < SMOOTHED(-1, -1)) << 5) + ((SMOOTHED(-16, 0) < SMOOTHED(6, 8)) << 4) + ((SMOOTHED(22, 11) < SMOOTHED(0, -3)) << 3) + ((SMOOTHED(19, 0) < SMOOTHED(5, -17)) << 2) + ((SMOOTHED(-23, -14) < SMOOTHED(-13, -19)) << 1) + ((SMOOTHED(-8, 10) < SMOOTHED(-11, -2)) << 0)); |
||||
desc[14] = (uchar)(((SMOOTHED(-11, 6) < SMOOTHED(-10, 13)) << 7) + ((SMOOTHED(1, -7) < SMOOTHED(14, 0)) << 6) + ((SMOOTHED(-12, 1) < SMOOTHED(-5, -5)) << 5) + ((SMOOTHED(4, 7) < SMOOTHED(8, -1)) << 4) + ((SMOOTHED(-1, -5) < SMOOTHED(15, 2)) << 3) + ((SMOOTHED(-3, -1) < SMOOTHED(7, -10)) << 2) + ((SMOOTHED(3, -6) < SMOOTHED(10, -18)) << 1) + ((SMOOTHED(-7, -13) < SMOOTHED(-13, 10)) << 0)); |
||||
desc[15] = (uchar)(((SMOOTHED(1, -1) < SMOOTHED(13, -10)) << 7) + ((SMOOTHED(-19, 14) < SMOOTHED(8, -14)) << 6) + ((SMOOTHED(-4, -13) < SMOOTHED(7, 1)) << 5) + ((SMOOTHED(1, -2) < SMOOTHED(12, -7)) << 4) + ((SMOOTHED(3, -5) < SMOOTHED(1, -5)) << 3) + ((SMOOTHED(-2, -2) < SMOOTHED(8, -10)) << 2) + ((SMOOTHED(2, 14) < SMOOTHED(8, 7)) << 1) + ((SMOOTHED(3, 9) < SMOOTHED(8, 2)) << 0)); |
||||
desc[16] = (uchar)(((SMOOTHED(-9, 1) < SMOOTHED(-18, 0)) << 7) + ((SMOOTHED(4, 0) < SMOOTHED(1, 12)) << 6) + ((SMOOTHED(0, 9) < SMOOTHED(-14, -10)) << 5) + ((SMOOTHED(-13, -9) < SMOOTHED(-2, 6)) << 4) + ((SMOOTHED(1, 5) < SMOOTHED(10, 10)) << 3) + ((SMOOTHED(-3, -6) < SMOOTHED(-16, -5)) << 2) + ((SMOOTHED(11, 6) < SMOOTHED(-5, 0)) << 1) + ((SMOOTHED(-23, 10) < SMOOTHED(1, 2)) << 0)); |
||||
desc[17] = (uchar)(((SMOOTHED(13, -5) < SMOOTHED(-3, 9)) << 7) + ((SMOOTHED(-4, -1) < SMOOTHED(-13, -5)) << 6) + ((SMOOTHED(10, 13) < SMOOTHED(-11, 8)) << 5) + ((SMOOTHED(19, 20) < SMOOTHED(-9, 2)) << 4) + ((SMOOTHED(4, -8) < SMOOTHED(0, -9)) << 3) + ((SMOOTHED(-14, 10) < SMOOTHED(15, 19)) << 2) + ((SMOOTHED(-14, -12) < SMOOTHED(-10, -3)) << 1) + ((SMOOTHED(-23, -3) < SMOOTHED(17, -2)) << 0)); |
||||
desc[18] = (uchar)(((SMOOTHED(-3, -11) < SMOOTHED(6, -14)) << 7) + ((SMOOTHED(19, -2) < SMOOTHED(-4, 2)) << 6) + ((SMOOTHED(-5, 5) < SMOOTHED(3, -13)) << 5) + ((SMOOTHED(2, -2) < SMOOTHED(-5, 4)) << 4) + ((SMOOTHED(17, 4) < SMOOTHED(17, -11)) << 3) + ((SMOOTHED(-7, -2) < SMOOTHED(1, 23)) << 2) + ((SMOOTHED(8, 13) < SMOOTHED(1, -16)) << 1) + ((SMOOTHED(-13, -5) < SMOOTHED(1, -17)) << 0)); |
||||
desc[19] = (uchar)(((SMOOTHED(4, 6) < SMOOTHED(-8, -3)) << 7) + ((SMOOTHED(-5, -9) < SMOOTHED(-2, -10)) << 6) + ((SMOOTHED(-9, 0) < SMOOTHED(-7, -2)) << 5) + ((SMOOTHED(5, 0) < SMOOTHED(5, 2)) << 4) + ((SMOOTHED(-4, -16) < SMOOTHED(6, 3)) << 3) + ((SMOOTHED(2, -15) < SMOOTHED(-2, 12)) << 2) + ((SMOOTHED(4, -1) < SMOOTHED(6, 2)) << 1) + ((SMOOTHED(1, 1) < SMOOTHED(-2, -8)) << 0)); |
||||
desc[20] = (uchar)(((SMOOTHED(-2, 12) < SMOOTHED(-5, -2)) << 7) + ((SMOOTHED(-8, 8) < SMOOTHED(-9, 9)) << 6) + ((SMOOTHED(2, -10) < SMOOTHED(3, 1)) << 5) + ((SMOOTHED(-4, 10) < SMOOTHED(-9, 4)) << 4) + ((SMOOTHED(6, 12) < SMOOTHED(2, 5)) << 3) + ((SMOOTHED(-3, -8) < SMOOTHED(0, 5)) << 2) + ((SMOOTHED(-13, 1) < SMOOTHED(-7, 2)) << 1) + ((SMOOTHED(-1, -10) < SMOOTHED(7, -18)) << 0)); |
||||
desc[21] = (uchar)(((SMOOTHED(-1, 8) < SMOOTHED(-9, -10)) << 7) + ((SMOOTHED(-23, -1) < SMOOTHED(6, 2)) << 6) + ((SMOOTHED(-5, -3) < SMOOTHED(3, 2)) << 5) + ((SMOOTHED(0, 11) < SMOOTHED(-4, -7)) << 4) + ((SMOOTHED(15, 2) < SMOOTHED(-10, -3)) << 3) + ((SMOOTHED(-20, -8) < SMOOTHED(-13, 3)) << 2) + ((SMOOTHED(-19, -12) < SMOOTHED(5, -11)) << 1) + ((SMOOTHED(-17, -13) < SMOOTHED(-3, 2)) << 0)); |
||||
desc[22] = (uchar)(((SMOOTHED(7, 4) < SMOOTHED(-12, 0)) << 7) + ((SMOOTHED(5, -1) < SMOOTHED(-14, -6)) << 6) + ((SMOOTHED(-4, 11) < SMOOTHED(0, -4)) << 5) + ((SMOOTHED(3, 10) < SMOOTHED(7, -3)) << 4) + ((SMOOTHED(13, 21) < SMOOTHED(-11, 6)) << 3) + ((SMOOTHED(-12, 24) < SMOOTHED(-7, -4)) << 2) + ((SMOOTHED(4, 16) < SMOOTHED(3, -14)) << 1) + ((SMOOTHED(-3, 5) < SMOOTHED(-7, -12)) << 0)); |
||||
desc[23] = (uchar)(((SMOOTHED(0, -4) < SMOOTHED(7, -5)) << 7) + ((SMOOTHED(-17, -9) < SMOOTHED(13, -7)) << 6) + ((SMOOTHED(22, -6) < SMOOTHED(-11, 5)) << 5) + ((SMOOTHED(2, -8) < SMOOTHED(23, -11)) << 4) + ((SMOOTHED(7, -10) < SMOOTHED(-1, 14)) << 3) + ((SMOOTHED(-3, -10) < SMOOTHED(8, 3)) << 2) + ((SMOOTHED(-13, 1) < SMOOTHED(-6, 0)) << 1) + ((SMOOTHED(-7, -21) < SMOOTHED(6, -14)) << 0)); |
||||
desc[24] = (uchar)(((SMOOTHED(18, 19) < SMOOTHED(-4, -6)) << 7) + ((SMOOTHED(10, 7) < SMOOTHED(-1, -4)) << 6) + ((SMOOTHED(-1, 21) < SMOOTHED(1, -5)) << 5) + ((SMOOTHED(-10, 6) < SMOOTHED(-11, -2)) << 4) + ((SMOOTHED(18, -3) < SMOOTHED(-1, 7)) << 3) + ((SMOOTHED(-3, -9) < SMOOTHED(-5, 10)) << 2) + ((SMOOTHED(-13, 14) < SMOOTHED(17, -3)) << 1) + ((SMOOTHED(11, -19) < SMOOTHED(-1, -18)) << 0)); |
||||
desc[25] = (uchar)(((SMOOTHED(8, -2) < SMOOTHED(-18, -23)) << 7) + ((SMOOTHED(0, -5) < SMOOTHED(-2, -9)) << 6) + ((SMOOTHED(-4, -11) < SMOOTHED(2, -8)) << 5) + ((SMOOTHED(14, 6) < SMOOTHED(-3, -6)) << 4) + ((SMOOTHED(-3, 0) < SMOOTHED(-15, 0)) << 3) + ((SMOOTHED(-9, 4) < SMOOTHED(-15, -9)) << 2) + ((SMOOTHED(-1, 11) < SMOOTHED(3, 11)) << 1) + ((SMOOTHED(-10, -16) < SMOOTHED(-7, 7)) << 0)); |
||||
desc[26] = (uchar)(((SMOOTHED(-2, -10) < SMOOTHED(-10, -2)) << 7) + ((SMOOTHED(-5, -3) < SMOOTHED(5, -23)) << 6) + ((SMOOTHED(13, -8) < SMOOTHED(-15, -11)) << 5) + ((SMOOTHED(-15, 11) < SMOOTHED(6, -6)) << 4) + ((SMOOTHED(-16, -3) < SMOOTHED(-2, 2)) << 3) + ((SMOOTHED(6, 12) < SMOOTHED(-16, 24)) << 2) + ((SMOOTHED(-10, 0) < SMOOTHED(8, 11)) << 1) + ((SMOOTHED(-7, 7) < SMOOTHED(-19, -7)) << 0)); |
||||
desc[27] = (uchar)(((SMOOTHED(5, 16) < SMOOTHED(9, -3)) << 7) + ((SMOOTHED(9, 7) < SMOOTHED(-7, -16)) << 6) + ((SMOOTHED(3, 2) < SMOOTHED(-10, 9)) << 5) + ((SMOOTHED(21, 1) < SMOOTHED(8, 7)) << 4) + ((SMOOTHED(7, 0) < SMOOTHED(1, 17)) << 3) + ((SMOOTHED(-8, 12) < SMOOTHED(9, 6)) << 2) + ((SMOOTHED(11, -7) < SMOOTHED(-8, -6)) << 1) + ((SMOOTHED(19, 0) < SMOOTHED(9, 3)) << 0)); |
||||
desc[28] = (uchar)(((SMOOTHED(1, -7) < SMOOTHED(-5, -11)) << 7) + ((SMOOTHED(0, 8) < SMOOTHED(-2, 14)) << 6) + ((SMOOTHED(12, -2) < SMOOTHED(-15, -6)) << 5) + ((SMOOTHED(4, 12) < SMOOTHED(0, -21)) << 4) + ((SMOOTHED(17, -4) < SMOOTHED(-6, -7)) << 3) + ((SMOOTHED(-10, -9) < SMOOTHED(-14, -7)) << 2) + ((SMOOTHED(-15, -10) < SMOOTHED(-15, -14)) << 1) + ((SMOOTHED(-7, -5) < SMOOTHED(5, -12)) << 0)); |
||||
desc[29] = (uchar)(((SMOOTHED(-4, 0) < SMOOTHED(15, -4)) << 7) + ((SMOOTHED(5, 2) < SMOOTHED(-6, -23)) << 6) + ((SMOOTHED(-4, -21) < SMOOTHED(-6, 4)) << 5) + ((SMOOTHED(-10, 5) < SMOOTHED(-15, 6)) << 4) + ((SMOOTHED(4, -3) < SMOOTHED(-1, 5)) << 3) + ((SMOOTHED(-4, 19) < SMOOTHED(-23, -4)) << 2) + ((SMOOTHED(-4, 17) < SMOOTHED(13, -11)) << 1) + ((SMOOTHED(1, 12) < SMOOTHED(4, -14)) << 0)); |
||||
desc[30] = (uchar)(((SMOOTHED(-11, -6) < SMOOTHED(-20, 10)) << 7) + ((SMOOTHED(4, 5) < SMOOTHED(3, 20)) << 6) + ((SMOOTHED(-8, -20) < SMOOTHED(3, 1)) << 5) + ((SMOOTHED(-19, 9) < SMOOTHED(9, -3)) << 4) + ((SMOOTHED(18, 15) < SMOOTHED(11, -4)) << 3) + ((SMOOTHED(12, 16) < SMOOTHED(8, 7)) << 2) + ((SMOOTHED(-14, -8) < SMOOTHED(-3, 9)) << 1) + ((SMOOTHED(-6, 0) < SMOOTHED(2, -4)) << 0)); |
||||
desc[31] = (uchar)(((SMOOTHED(1, -10) < SMOOTHED(-1, 2)) << 7) + ((SMOOTHED(8, -7) < SMOOTHED(-6, 18)) << 6) + ((SMOOTHED(9, 12) < SMOOTHED(-7, -23)) << 5) + ((SMOOTHED(8, -6) < SMOOTHED(5, 2)) << 4) + ((SMOOTHED(-9, 6) < SMOOTHED(-12, -7)) << 3) + ((SMOOTHED(-1, -2) < SMOOTHED(-7, 2)) << 2) + ((SMOOTHED(9, 9) < SMOOTHED(7, 15)) << 1) + ((SMOOTHED(6, 2) < SMOOTHED(-6, 6)) << 0)); |
||||
#undef SMOOTHED |
@ -1,67 +0,0 @@ |
||||
// Code generated with '$ scripts/generate_code.py src/test_pairs.txt 64' |
||||
#define SMOOTHED(y,x) smoothedSum(sum, pt, y, x) |
||||
desc[0] = (uchar)(((SMOOTHED(-2, -1) < SMOOTHED(7, -1)) << 7) + ((SMOOTHED(-14, -1) < SMOOTHED(-3, 3)) << 6) + ((SMOOTHED(1, -2) < SMOOTHED(11, 2)) << 5) + ((SMOOTHED(1, 6) < SMOOTHED(-10, -7)) << 4) + ((SMOOTHED(13, 2) < SMOOTHED(-1, 0)) << 3) + ((SMOOTHED(-14, 5) < SMOOTHED(5, -3)) << 2) + ((SMOOTHED(-2, 8) < SMOOTHED(2, 4)) << 1) + ((SMOOTHED(-11, 8) < SMOOTHED(-15, 5)) << 0)); |
||||
desc[1] = (uchar)(((SMOOTHED(-6, -23) < SMOOTHED(8, -9)) << 7) + ((SMOOTHED(-12, 6) < SMOOTHED(-10, 8)) << 6) + ((SMOOTHED(-3, -1) < SMOOTHED(8, 1)) << 5) + ((SMOOTHED(3, 6) < SMOOTHED(5, 6)) << 4) + ((SMOOTHED(-7, -6) < SMOOTHED(5, -5)) << 3) + ((SMOOTHED(22, -2) < SMOOTHED(-11, -8)) << 2) + ((SMOOTHED(14, 7) < SMOOTHED(8, 5)) << 1) + ((SMOOTHED(-1, 14) < SMOOTHED(-5, -14)) << 0)); |
||||
desc[2] = (uchar)(((SMOOTHED(-14, 9) < SMOOTHED(2, 0)) << 7) + ((SMOOTHED(7, -3) < SMOOTHED(22, 6)) << 6) + ((SMOOTHED(-6, 6) < SMOOTHED(-8, -5)) << 5) + ((SMOOTHED(-5, 9) < SMOOTHED(7, -1)) << 4) + ((SMOOTHED(-3, -7) < SMOOTHED(-10, -18)) << 3) + ((SMOOTHED(4, -5) < SMOOTHED(0, 11)) << 2) + ((SMOOTHED(2, 3) < SMOOTHED(9, 10)) << 1) + ((SMOOTHED(-10, 3) < SMOOTHED(4, 9)) << 0)); |
||||
desc[3] = (uchar)(((SMOOTHED(0, 12) < SMOOTHED(-3, 19)) << 7) + ((SMOOTHED(1, 15) < SMOOTHED(-11, -5)) << 6) + ((SMOOTHED(14, -1) < SMOOTHED(7, 8)) << 5) + ((SMOOTHED(7, -23) < SMOOTHED(-5, 5)) << 4) + ((SMOOTHED(0, -6) < SMOOTHED(-10, 17)) << 3) + ((SMOOTHED(13, -4) < SMOOTHED(-3, -4)) << 2) + ((SMOOTHED(-12, 1) < SMOOTHED(-12, 2)) << 1) + ((SMOOTHED(0, 8) < SMOOTHED(3, 22)) << 0)); |
||||
desc[4] = (uchar)(((SMOOTHED(-13, 13) < SMOOTHED(3, -1)) << 7) + ((SMOOTHED(-16, 17) < SMOOTHED(6, 10)) << 6) + ((SMOOTHED(7, 15) < SMOOTHED(-5, 0)) << 5) + ((SMOOTHED(2, -12) < SMOOTHED(19, -2)) << 4) + ((SMOOTHED(3, -6) < SMOOTHED(-4, -15)) << 3) + ((SMOOTHED(8, 3) < SMOOTHED(0, 14)) << 2) + ((SMOOTHED(4, -11) < SMOOTHED(5, 5)) << 1) + ((SMOOTHED(11, -7) < SMOOTHED(7, 1)) << 0)); |
||||
desc[5] = (uchar)(((SMOOTHED(6, 12) < SMOOTHED(21, 3)) << 7) + ((SMOOTHED(-3, 2) < SMOOTHED(14, 1)) << 6) + ((SMOOTHED(5, 1) < SMOOTHED(-5, 11)) << 5) + ((SMOOTHED(3, -17) < SMOOTHED(-6, 2)) << 4) + ((SMOOTHED(6, 8) < SMOOTHED(5, -10)) << 3) + ((SMOOTHED(-14, -2) < SMOOTHED(0, 4)) << 2) + ((SMOOTHED(5, -7) < SMOOTHED(-6, 5)) << 1) + ((SMOOTHED(10, 4) < SMOOTHED(4, -7)) << 0)); |
||||
desc[6] = (uchar)(((SMOOTHED(22, 0) < SMOOTHED(7, -18)) << 7) + ((SMOOTHED(-1, -3) < SMOOTHED(0, 18)) << 6) + ((SMOOTHED(-4, 22) < SMOOTHED(-5, 3)) << 5) + ((SMOOTHED(1, -7) < SMOOTHED(2, -3)) << 4) + ((SMOOTHED(19, -20) < SMOOTHED(17, -2)) << 3) + ((SMOOTHED(3, -10) < SMOOTHED(-8, 24)) << 2) + ((SMOOTHED(-5, -14) < SMOOTHED(7, 5)) << 1) + ((SMOOTHED(-2, 12) < SMOOTHED(-4, -15)) << 0)); |
||||
desc[7] = (uchar)(((SMOOTHED(4, 12) < SMOOTHED(0, -19)) << 7) + ((SMOOTHED(20, 13) < SMOOTHED(3, 5)) << 6) + ((SMOOTHED(-8, -12) < SMOOTHED(5, 0)) << 5) + ((SMOOTHED(-5, 6) < SMOOTHED(-7, -11)) << 4) + ((SMOOTHED(6, -11) < SMOOTHED(-3, -22)) << 3) + ((SMOOTHED(15, 4) < SMOOTHED(10, 1)) << 2) + ((SMOOTHED(-7, -4) < SMOOTHED(15, -6)) << 1) + ((SMOOTHED(5, 10) < SMOOTHED(0, 24)) << 0)); |
||||
desc[8] = (uchar)(((SMOOTHED(3, 6) < SMOOTHED(22, -2)) << 7) + ((SMOOTHED(-13, 14) < SMOOTHED(4, -4)) << 6) + ((SMOOTHED(-13, 8) < SMOOTHED(-18, -22)) << 5) + ((SMOOTHED(-1, -1) < SMOOTHED(-7, 3)) << 4) + ((SMOOTHED(-19, -12) < SMOOTHED(4, 3)) << 3) + ((SMOOTHED(8, 10) < SMOOTHED(13, -2)) << 2) + ((SMOOTHED(-6, -1) < SMOOTHED(-6, -5)) << 1) + ((SMOOTHED(2, -21) < SMOOTHED(-3, 2)) << 0)); |
||||
desc[9] = (uchar)(((SMOOTHED(4, -7) < SMOOTHED(0, 16)) << 7) + ((SMOOTHED(-6, -5) < SMOOTHED(-12, -1)) << 6) + ((SMOOTHED(1, -1) < SMOOTHED(9, 18)) << 5) + ((SMOOTHED(-7, 10) < SMOOTHED(-11, 6)) << 4) + ((SMOOTHED(4, 3) < SMOOTHED(19, -7)) << 3) + ((SMOOTHED(-18, 5) < SMOOTHED(-4, 5)) << 2) + ((SMOOTHED(4, 0) < SMOOTHED(-20, 4)) << 1) + ((SMOOTHED(7, -11) < SMOOTHED(18, 12)) << 0)); |
||||
desc[10] = (uchar)(((SMOOTHED(-20, 17) < SMOOTHED(-18, 7)) << 7) + ((SMOOTHED(2, 15) < SMOOTHED(19, -11)) << 6) + ((SMOOTHED(-18, 6) < SMOOTHED(-7, 3)) << 5) + ((SMOOTHED(-4, 1) < SMOOTHED(-14, 13)) << 4) + ((SMOOTHED(17, 3) < SMOOTHED(2, -8)) << 3) + ((SMOOTHED(-7, 2) < SMOOTHED(1, 6)) << 2) + ((SMOOTHED(17, -9) < SMOOTHED(-2, 8)) << 1) + ((SMOOTHED(-8, -6) < SMOOTHED(-1, 12)) << 0)); |
||||
desc[11] = (uchar)(((SMOOTHED(-2, 4) < SMOOTHED(-1, 6)) << 7) + ((SMOOTHED(-2, 7) < SMOOTHED(6, 8)) << 6) + ((SMOOTHED(-8, -1) < SMOOTHED(-7, -9)) << 5) + ((SMOOTHED(8, -9) < SMOOTHED(15, 0)) << 4) + ((SMOOTHED(0, 22) < SMOOTHED(-4, -15)) << 3) + ((SMOOTHED(-14, -1) < SMOOTHED(3, -2)) << 2) + ((SMOOTHED(-7, -4) < SMOOTHED(17, -7)) << 1) + ((SMOOTHED(-8, -2) < SMOOTHED(9, -4)) << 0)); |
||||
desc[12] = (uchar)(((SMOOTHED(5, -7) < SMOOTHED(7, 7)) << 7) + ((SMOOTHED(-5, 13) < SMOOTHED(-8, 11)) << 6) + ((SMOOTHED(11, -4) < SMOOTHED(0, 8)) << 5) + ((SMOOTHED(5, -11) < SMOOTHED(-9, -6)) << 4) + ((SMOOTHED(2, -6) < SMOOTHED(3, -20)) << 3) + ((SMOOTHED(-6, 2) < SMOOTHED(6, 10)) << 2) + ((SMOOTHED(-6, -6) < SMOOTHED(-15, 7)) << 1) + ((SMOOTHED(-6, -3) < SMOOTHED(2, 1)) << 0)); |
||||
desc[13] = (uchar)(((SMOOTHED(11, 0) < SMOOTHED(-3, 2)) << 7) + ((SMOOTHED(7, -12) < SMOOTHED(14, 5)) << 6) + ((SMOOTHED(0, -7) < SMOOTHED(-1, -1)) << 5) + ((SMOOTHED(-16, 0) < SMOOTHED(6, 8)) << 4) + ((SMOOTHED(22, 11) < SMOOTHED(0, -3)) << 3) + ((SMOOTHED(19, 0) < SMOOTHED(5, -17)) << 2) + ((SMOOTHED(-23, -14) < SMOOTHED(-13, -19)) << 1) + ((SMOOTHED(-8, 10) < SMOOTHED(-11, -2)) << 0)); |
||||
desc[14] = (uchar)(((SMOOTHED(-11, 6) < SMOOTHED(-10, 13)) << 7) + ((SMOOTHED(1, -7) < SMOOTHED(14, 0)) << 6) + ((SMOOTHED(-12, 1) < SMOOTHED(-5, -5)) << 5) + ((SMOOTHED(4, 7) < SMOOTHED(8, -1)) << 4) + ((SMOOTHED(-1, -5) < SMOOTHED(15, 2)) << 3) + ((SMOOTHED(-3, -1) < SMOOTHED(7, -10)) << 2) + ((SMOOTHED(3, -6) < SMOOTHED(10, -18)) << 1) + ((SMOOTHED(-7, -13) < SMOOTHED(-13, 10)) << 0)); |
||||
desc[15] = (uchar)(((SMOOTHED(1, -1) < SMOOTHED(13, -10)) << 7) + ((SMOOTHED(-19, 14) < SMOOTHED(8, -14)) << 6) + ((SMOOTHED(-4, -13) < SMOOTHED(7, 1)) << 5) + ((SMOOTHED(1, -2) < SMOOTHED(12, -7)) << 4) + ((SMOOTHED(3, -5) < SMOOTHED(1, -5)) << 3) + ((SMOOTHED(-2, -2) < SMOOTHED(8, -10)) << 2) + ((SMOOTHED(2, 14) < SMOOTHED(8, 7)) << 1) + ((SMOOTHED(3, 9) < SMOOTHED(8, 2)) << 0)); |
||||
desc[16] = (uchar)(((SMOOTHED(-9, 1) < SMOOTHED(-18, 0)) << 7) + ((SMOOTHED(4, 0) < SMOOTHED(1, 12)) << 6) + ((SMOOTHED(0, 9) < SMOOTHED(-14, -10)) << 5) + ((SMOOTHED(-13, -9) < SMOOTHED(-2, 6)) << 4) + ((SMOOTHED(1, 5) < SMOOTHED(10, 10)) << 3) + ((SMOOTHED(-3, -6) < SMOOTHED(-16, -5)) << 2) + ((SMOOTHED(11, 6) < SMOOTHED(-5, 0)) << 1) + ((SMOOTHED(-23, 10) < SMOOTHED(1, 2)) << 0)); |
||||
desc[17] = (uchar)(((SMOOTHED(13, -5) < SMOOTHED(-3, 9)) << 7) + ((SMOOTHED(-4, -1) < SMOOTHED(-13, -5)) << 6) + ((SMOOTHED(10, 13) < SMOOTHED(-11, 8)) << 5) + ((SMOOTHED(19, 20) < SMOOTHED(-9, 2)) << 4) + ((SMOOTHED(4, -8) < SMOOTHED(0, -9)) << 3) + ((SMOOTHED(-14, 10) < SMOOTHED(15, 19)) << 2) + ((SMOOTHED(-14, -12) < SMOOTHED(-10, -3)) << 1) + ((SMOOTHED(-23, -3) < SMOOTHED(17, -2)) << 0)); |
||||
desc[18] = (uchar)(((SMOOTHED(-3, -11) < SMOOTHED(6, -14)) << 7) + ((SMOOTHED(19, -2) < SMOOTHED(-4, 2)) << 6) + ((SMOOTHED(-5, 5) < SMOOTHED(3, -13)) << 5) + ((SMOOTHED(2, -2) < SMOOTHED(-5, 4)) << 4) + ((SMOOTHED(17, 4) < SMOOTHED(17, -11)) << 3) + ((SMOOTHED(-7, -2) < SMOOTHED(1, 23)) << 2) + ((SMOOTHED(8, 13) < SMOOTHED(1, -16)) << 1) + ((SMOOTHED(-13, -5) < SMOOTHED(1, -17)) << 0)); |
||||
desc[19] = (uchar)(((SMOOTHED(4, 6) < SMOOTHED(-8, -3)) << 7) + ((SMOOTHED(-5, -9) < SMOOTHED(-2, -10)) << 6) + ((SMOOTHED(-9, 0) < SMOOTHED(-7, -2)) << 5) + ((SMOOTHED(5, 0) < SMOOTHED(5, 2)) << 4) + ((SMOOTHED(-4, -16) < SMOOTHED(6, 3)) << 3) + ((SMOOTHED(2, -15) < SMOOTHED(-2, 12)) << 2) + ((SMOOTHED(4, -1) < SMOOTHED(6, 2)) << 1) + ((SMOOTHED(1, 1) < SMOOTHED(-2, -8)) << 0)); |
||||
desc[20] = (uchar)(((SMOOTHED(-2, 12) < SMOOTHED(-5, -2)) << 7) + ((SMOOTHED(-8, 8) < SMOOTHED(-9, 9)) << 6) + ((SMOOTHED(2, -10) < SMOOTHED(3, 1)) << 5) + ((SMOOTHED(-4, 10) < SMOOTHED(-9, 4)) << 4) + ((SMOOTHED(6, 12) < SMOOTHED(2, 5)) << 3) + ((SMOOTHED(-3, -8) < SMOOTHED(0, 5)) << 2) + ((SMOOTHED(-13, 1) < SMOOTHED(-7, 2)) << 1) + ((SMOOTHED(-1, -10) < SMOOTHED(7, -18)) << 0)); |
||||
desc[21] = (uchar)(((SMOOTHED(-1, 8) < SMOOTHED(-9, -10)) << 7) + ((SMOOTHED(-23, -1) < SMOOTHED(6, 2)) << 6) + ((SMOOTHED(-5, -3) < SMOOTHED(3, 2)) << 5) + ((SMOOTHED(0, 11) < SMOOTHED(-4, -7)) << 4) + ((SMOOTHED(15, 2) < SMOOTHED(-10, -3)) << 3) + ((SMOOTHED(-20, -8) < SMOOTHED(-13, 3)) << 2) + ((SMOOTHED(-19, -12) < SMOOTHED(5, -11)) << 1) + ((SMOOTHED(-17, -13) < SMOOTHED(-3, 2)) << 0)); |
||||
desc[22] = (uchar)(((SMOOTHED(7, 4) < SMOOTHED(-12, 0)) << 7) + ((SMOOTHED(5, -1) < SMOOTHED(-14, -6)) << 6) + ((SMOOTHED(-4, 11) < SMOOTHED(0, -4)) << 5) + ((SMOOTHED(3, 10) < SMOOTHED(7, -3)) << 4) + ((SMOOTHED(13, 21) < SMOOTHED(-11, 6)) << 3) + ((SMOOTHED(-12, 24) < SMOOTHED(-7, -4)) << 2) + ((SMOOTHED(4, 16) < SMOOTHED(3, -14)) << 1) + ((SMOOTHED(-3, 5) < SMOOTHED(-7, -12)) << 0)); |
||||
desc[23] = (uchar)(((SMOOTHED(0, -4) < SMOOTHED(7, -5)) << 7) + ((SMOOTHED(-17, -9) < SMOOTHED(13, -7)) << 6) + ((SMOOTHED(22, -6) < SMOOTHED(-11, 5)) << 5) + ((SMOOTHED(2, -8) < SMOOTHED(23, -11)) << 4) + ((SMOOTHED(7, -10) < SMOOTHED(-1, 14)) << 3) + ((SMOOTHED(-3, -10) < SMOOTHED(8, 3)) << 2) + ((SMOOTHED(-13, 1) < SMOOTHED(-6, 0)) << 1) + ((SMOOTHED(-7, -21) < SMOOTHED(6, -14)) << 0)); |
||||
desc[24] = (uchar)(((SMOOTHED(18, 19) < SMOOTHED(-4, -6)) << 7) + ((SMOOTHED(10, 7) < SMOOTHED(-1, -4)) << 6) + ((SMOOTHED(-1, 21) < SMOOTHED(1, -5)) << 5) + ((SMOOTHED(-10, 6) < SMOOTHED(-11, -2)) << 4) + ((SMOOTHED(18, -3) < SMOOTHED(-1, 7)) << 3) + ((SMOOTHED(-3, -9) < SMOOTHED(-5, 10)) << 2) + ((SMOOTHED(-13, 14) < SMOOTHED(17, -3)) << 1) + ((SMOOTHED(11, -19) < SMOOTHED(-1, -18)) << 0)); |
||||
desc[25] = (uchar)(((SMOOTHED(8, -2) < SMOOTHED(-18, -23)) << 7) + ((SMOOTHED(0, -5) < SMOOTHED(-2, -9)) << 6) + ((SMOOTHED(-4, -11) < SMOOTHED(2, -8)) << 5) + ((SMOOTHED(14, 6) < SMOOTHED(-3, -6)) << 4) + ((SMOOTHED(-3, 0) < SMOOTHED(-15, 0)) << 3) + ((SMOOTHED(-9, 4) < SMOOTHED(-15, -9)) << 2) + ((SMOOTHED(-1, 11) < SMOOTHED(3, 11)) << 1) + ((SMOOTHED(-10, -16) < SMOOTHED(-7, 7)) << 0)); |
||||
desc[26] = (uchar)(((SMOOTHED(-2, -10) < SMOOTHED(-10, -2)) << 7) + ((SMOOTHED(-5, -3) < SMOOTHED(5, -23)) << 6) + ((SMOOTHED(13, -8) < SMOOTHED(-15, -11)) << 5) + ((SMOOTHED(-15, 11) < SMOOTHED(6, -6)) << 4) + ((SMOOTHED(-16, -3) < SMOOTHED(-2, 2)) << 3) + ((SMOOTHED(6, 12) < SMOOTHED(-16, 24)) << 2) + ((SMOOTHED(-10, 0) < SMOOTHED(8, 11)) << 1) + ((SMOOTHED(-7, 7) < SMOOTHED(-19, -7)) << 0)); |
||||
desc[27] = (uchar)(((SMOOTHED(5, 16) < SMOOTHED(9, -3)) << 7) + ((SMOOTHED(9, 7) < SMOOTHED(-7, -16)) << 6) + ((SMOOTHED(3, 2) < SMOOTHED(-10, 9)) << 5) + ((SMOOTHED(21, 1) < SMOOTHED(8, 7)) << 4) + ((SMOOTHED(7, 0) < SMOOTHED(1, 17)) << 3) + ((SMOOTHED(-8, 12) < SMOOTHED(9, 6)) << 2) + ((SMOOTHED(11, -7) < SMOOTHED(-8, -6)) << 1) + ((SMOOTHED(19, 0) < SMOOTHED(9, 3)) << 0)); |
||||
desc[28] = (uchar)(((SMOOTHED(1, -7) < SMOOTHED(-5, -11)) << 7) + ((SMOOTHED(0, 8) < SMOOTHED(-2, 14)) << 6) + ((SMOOTHED(12, -2) < SMOOTHED(-15, -6)) << 5) + ((SMOOTHED(4, 12) < SMOOTHED(0, -21)) << 4) + ((SMOOTHED(17, -4) < SMOOTHED(-6, -7)) << 3) + ((SMOOTHED(-10, -9) < SMOOTHED(-14, -7)) << 2) + ((SMOOTHED(-15, -10) < SMOOTHED(-15, -14)) << 1) + ((SMOOTHED(-7, -5) < SMOOTHED(5, -12)) << 0)); |
||||
desc[29] = (uchar)(((SMOOTHED(-4, 0) < SMOOTHED(15, -4)) << 7) + ((SMOOTHED(5, 2) < SMOOTHED(-6, -23)) << 6) + ((SMOOTHED(-4, -21) < SMOOTHED(-6, 4)) << 5) + ((SMOOTHED(-10, 5) < SMOOTHED(-15, 6)) << 4) + ((SMOOTHED(4, -3) < SMOOTHED(-1, 5)) << 3) + ((SMOOTHED(-4, 19) < SMOOTHED(-23, -4)) << 2) + ((SMOOTHED(-4, 17) < SMOOTHED(13, -11)) << 1) + ((SMOOTHED(1, 12) < SMOOTHED(4, -14)) << 0)); |
||||
desc[30] = (uchar)(((SMOOTHED(-11, -6) < SMOOTHED(-20, 10)) << 7) + ((SMOOTHED(4, 5) < SMOOTHED(3, 20)) << 6) + ((SMOOTHED(-8, -20) < SMOOTHED(3, 1)) << 5) + ((SMOOTHED(-19, 9) < SMOOTHED(9, -3)) << 4) + ((SMOOTHED(18, 15) < SMOOTHED(11, -4)) << 3) + ((SMOOTHED(12, 16) < SMOOTHED(8, 7)) << 2) + ((SMOOTHED(-14, -8) < SMOOTHED(-3, 9)) << 1) + ((SMOOTHED(-6, 0) < SMOOTHED(2, -4)) << 0)); |
||||
desc[31] = (uchar)(((SMOOTHED(1, -10) < SMOOTHED(-1, 2)) << 7) + ((SMOOTHED(8, -7) < SMOOTHED(-6, 18)) << 6) + ((SMOOTHED(9, 12) < SMOOTHED(-7, -23)) << 5) + ((SMOOTHED(8, -6) < SMOOTHED(5, 2)) << 4) + ((SMOOTHED(-9, 6) < SMOOTHED(-12, -7)) << 3) + ((SMOOTHED(-1, -2) < SMOOTHED(-7, 2)) << 2) + ((SMOOTHED(9, 9) < SMOOTHED(7, 15)) << 1) + ((SMOOTHED(6, 2) < SMOOTHED(-6, 6)) << 0)); |
||||
desc[32] = (uchar)(((SMOOTHED(16, 12) < SMOOTHED(0, 19)) << 7) + ((SMOOTHED(4, 3) < SMOOTHED(6, 0)) << 6) + ((SMOOTHED(-2, -1) < SMOOTHED(2, 17)) << 5) + ((SMOOTHED(8, 1) < SMOOTHED(3, 1)) << 4) + ((SMOOTHED(-12, -1) < SMOOTHED(-11, 0)) << 3) + ((SMOOTHED(-11, 2) < SMOOTHED(7, 9)) << 2) + ((SMOOTHED(-1, 3) < SMOOTHED(-19, 4)) << 1) + ((SMOOTHED(-1, -11) < SMOOTHED(-1, 3)) << 0)); |
||||
desc[33] = (uchar)(((SMOOTHED(1, -10) < SMOOTHED(-10, -4)) << 7) + ((SMOOTHED(-2, 3) < SMOOTHED(6, 11)) << 6) + ((SMOOTHED(3, 7) < SMOOTHED(-9, -8)) << 5) + ((SMOOTHED(24, -14) < SMOOTHED(-2, -10)) << 4) + ((SMOOTHED(-3, -3) < SMOOTHED(-18, -6)) << 3) + ((SMOOTHED(-13, -10) < SMOOTHED(-7, -1)) << 2) + ((SMOOTHED(2, -7) < SMOOTHED(9, -6)) << 1) + ((SMOOTHED(2, -4) < SMOOTHED(6, -13)) << 0)); |
||||
desc[34] = (uchar)(((SMOOTHED(4, -4) < SMOOTHED(-2, 3)) << 7) + ((SMOOTHED(-4, 2) < SMOOTHED(9, 13)) << 6) + ((SMOOTHED(-11, 5) < SMOOTHED(-6, -11)) << 5) + ((SMOOTHED(4, -2) < SMOOTHED(11, -9)) << 4) + ((SMOOTHED(-19, 0) < SMOOTHED(-23, -5)) << 3) + ((SMOOTHED(-5, -7) < SMOOTHED(-3, -6)) << 2) + ((SMOOTHED(-6, -4) < SMOOTHED(12, 14)) << 1) + ((SMOOTHED(12, -11) < SMOOTHED(-8, -16)) << 0)); |
||||
desc[35] = (uchar)(((SMOOTHED(-21, 15) < SMOOTHED(-12, 6)) << 7) + ((SMOOTHED(-2, -1) < SMOOTHED(-8, 16)) << 6) + ((SMOOTHED(6, -1) < SMOOTHED(-8, -2)) << 5) + ((SMOOTHED(1, -1) < SMOOTHED(-9, 8)) << 4) + ((SMOOTHED(3, -4) < SMOOTHED(-2, -2)) << 3) + ((SMOOTHED(-7, 0) < SMOOTHED(4, -8)) << 2) + ((SMOOTHED(11, -11) < SMOOTHED(-12, 2)) << 1) + ((SMOOTHED(2, 3) < SMOOTHED(11, 7)) << 0)); |
||||
desc[36] = (uchar)(((SMOOTHED(-7, -4) < SMOOTHED(-9, -6)) << 7) + ((SMOOTHED(3, -7) < SMOOTHED(-5, 0)) << 6) + ((SMOOTHED(3, -7) < SMOOTHED(-10, -5)) << 5) + ((SMOOTHED(-3, -1) < SMOOTHED(8, -10)) << 4) + ((SMOOTHED(0, 8) < SMOOTHED(5, 1)) << 3) + ((SMOOTHED(9, 0) < SMOOTHED(1, 16)) << 2) + ((SMOOTHED(8, 4) < SMOOTHED(-11, -3)) << 1) + ((SMOOTHED(-15, 9) < SMOOTHED(8, 17)) << 0)); |
||||
desc[37] = (uchar)(((SMOOTHED(0, 2) < SMOOTHED(-9, 17)) << 7) + ((SMOOTHED(-6, -11) < SMOOTHED(-10, -3)) << 6) + ((SMOOTHED(1, 1) < SMOOTHED(15, -8)) << 5) + ((SMOOTHED(-12, -13) < SMOOTHED(-2, 4)) << 4) + ((SMOOTHED(-6, 4) < SMOOTHED(-6, -10)) << 3) + ((SMOOTHED(5, -7) < SMOOTHED(7, -5)) << 2) + ((SMOOTHED(10, 6) < SMOOTHED(8, 9)) << 1) + ((SMOOTHED(-5, 7) < SMOOTHED(-18, -3)) << 0)); |
||||
desc[38] = (uchar)(((SMOOTHED(-6, 3) < SMOOTHED(5, 4)) << 7) + ((SMOOTHED(-10, -13) < SMOOTHED(-5, -3)) << 6) + ((SMOOTHED(-11, 2) < SMOOTHED(-16, 0)) << 5) + ((SMOOTHED(7, -21) < SMOOTHED(-5, -13)) << 4) + ((SMOOTHED(-14, -14) < SMOOTHED(-4, -4)) << 3) + ((SMOOTHED(4, 9) < SMOOTHED(7, -3)) << 2) + ((SMOOTHED(4, 11) < SMOOTHED(10, -4)) << 1) + ((SMOOTHED(6, 17) < SMOOTHED(9, 17)) << 0)); |
||||
desc[39] = (uchar)(((SMOOTHED(-10, 8) < SMOOTHED(0, -11)) << 7) + ((SMOOTHED(-6, -16) < SMOOTHED(-6, 8)) << 6) + ((SMOOTHED(-13, 5) < SMOOTHED(10, -5)) << 5) + ((SMOOTHED(3, 2) < SMOOTHED(12, 16)) << 4) + ((SMOOTHED(13, -8) < SMOOTHED(0, -6)) << 3) + ((SMOOTHED(10, 0) < SMOOTHED(4, -11)) << 2) + ((SMOOTHED(8, 5) < SMOOTHED(10, -2)) << 1) + ((SMOOTHED(11, -7) < SMOOTHED(-13, 3)) << 0)); |
||||
desc[40] = (uchar)(((SMOOTHED(2, 4) < SMOOTHED(-7, -3)) << 7) + ((SMOOTHED(-14, -2) < SMOOTHED(-11, 16)) << 6) + ((SMOOTHED(11, -6) < SMOOTHED(7, 6)) << 5) + ((SMOOTHED(-3, 15) < SMOOTHED(8, -10)) << 4) + ((SMOOTHED(-3, 8) < SMOOTHED(12, -12)) << 3) + ((SMOOTHED(-13, 6) < SMOOTHED(-14, 7)) << 2) + ((SMOOTHED(-11, -5) < SMOOTHED(-8, -6)) << 1) + ((SMOOTHED(7, -6) < SMOOTHED(6, 3)) << 0)); |
||||
desc[41] = (uchar)(((SMOOTHED(-4, 10) < SMOOTHED(5, 1)) << 7) + ((SMOOTHED(9, 16) < SMOOTHED(10, 13)) << 6) + ((SMOOTHED(-17, 10) < SMOOTHED(2, 8)) << 5) + ((SMOOTHED(-5, 1) < SMOOTHED(4, -4)) << 4) + ((SMOOTHED(-14, 8) < SMOOTHED(-5, 2)) << 3) + ((SMOOTHED(4, -9) < SMOOTHED(-6, -3)) << 2) + ((SMOOTHED(3, -7) < SMOOTHED(-10, 0)) << 1) + ((SMOOTHED(-2, -8) < SMOOTHED(-10, 4)) << 0)); |
||||
desc[42] = (uchar)(((SMOOTHED(-8, 5) < SMOOTHED(-9, 24)) << 7) + ((SMOOTHED(2, -8) < SMOOTHED(8, -9)) << 6) + ((SMOOTHED(-4, 17) < SMOOTHED(-5, 2)) << 5) + ((SMOOTHED(14, 0) < SMOOTHED(-9, 9)) << 4) + ((SMOOTHED(11, 15) < SMOOTHED(-6, 5)) << 3) + ((SMOOTHED(-8, 1) < SMOOTHED(-3, 4)) << 2) + ((SMOOTHED(9, -21) < SMOOTHED(10, 2)) << 1) + ((SMOOTHED(2, -1) < SMOOTHED(4, 11)) << 0)); |
||||
desc[43] = (uchar)(((SMOOTHED(24, 3) < SMOOTHED(2, -2)) << 7) + ((SMOOTHED(-8, 17) < SMOOTHED(-14, -10)) << 6) + ((SMOOTHED(6, 5) < SMOOTHED(-13, 7)) << 5) + ((SMOOTHED(11, 10) < SMOOTHED(0, -1)) << 4) + ((SMOOTHED(4, 6) < SMOOTHED(-10, 6)) << 3) + ((SMOOTHED(-12, -2) < SMOOTHED(5, 6)) << 2) + ((SMOOTHED(3, -1) < SMOOTHED(8, -15)) << 1) + ((SMOOTHED(1, -4) < SMOOTHED(-7, 11)) << 0)); |
||||
desc[44] = (uchar)(((SMOOTHED(1, 11) < SMOOTHED(5, 0)) << 7) + ((SMOOTHED(6, -12) < SMOOTHED(10, 1)) << 6) + ((SMOOTHED(-3, -2) < SMOOTHED(-1, 4)) << 5) + ((SMOOTHED(-2, -11) < SMOOTHED(-1, 12)) << 4) + ((SMOOTHED(7, -8) < SMOOTHED(-20, -18)) << 3) + ((SMOOTHED(2, 0) < SMOOTHED(-9, 2)) << 2) + ((SMOOTHED(-13, -1) < SMOOTHED(-16, 2)) << 1) + ((SMOOTHED(3, -1) < SMOOTHED(-5, -17)) << 0)); |
||||
desc[45] = (uchar)(((SMOOTHED(15, 8) < SMOOTHED(3, -14)) << 7) + ((SMOOTHED(-13, -12) < SMOOTHED(6, 15)) << 6) + ((SMOOTHED(2, -8) < SMOOTHED(2, 6)) << 5) + ((SMOOTHED(6, 22) < SMOOTHED(-3, -23)) << 4) + ((SMOOTHED(-2, -7) < SMOOTHED(-6, 0)) << 3) + ((SMOOTHED(13, -10) < SMOOTHED(-6, 6)) << 2) + ((SMOOTHED(6, 7) < SMOOTHED(-10, 12)) << 1) + ((SMOOTHED(-6, 7) < SMOOTHED(-2, 11)) << 0)); |
||||
desc[46] = (uchar)(((SMOOTHED(0, -22) < SMOOTHED(-2, -17)) << 7) + ((SMOOTHED(-4, -1) < SMOOTHED(-11, -14)) << 6) + ((SMOOTHED(-2, -8) < SMOOTHED(7, 12)) << 5) + ((SMOOTHED(12, -5) < SMOOTHED(7, -13)) << 4) + ((SMOOTHED(2, -2) < SMOOTHED(-7, 6)) << 3) + ((SMOOTHED(0, 8) < SMOOTHED(-3, 23)) << 2) + ((SMOOTHED(6, 12) < SMOOTHED(13, -11)) << 1) + ((SMOOTHED(-21, -10) < SMOOTHED(10, 8)) << 0)); |
||||
desc[47] = (uchar)(((SMOOTHED(-3, 0) < SMOOTHED(7, 15)) << 7) + ((SMOOTHED(7, -6) < SMOOTHED(-5, -12)) << 6) + ((SMOOTHED(-21, -10) < SMOOTHED(12, -11)) << 5) + ((SMOOTHED(-5, -11) < SMOOTHED(8, -11)) << 4) + ((SMOOTHED(5, 0) < SMOOTHED(-11, -1)) << 3) + ((SMOOTHED(8, -9) < SMOOTHED(7, -1)) << 2) + ((SMOOTHED(11, -23) < SMOOTHED(21, -5)) << 1) + ((SMOOTHED(0, -5) < SMOOTHED(-8, 6)) << 0)); |
||||
desc[48] = (uchar)(((SMOOTHED(-6, 8) < SMOOTHED(8, 12)) << 7) + ((SMOOTHED(-7, 5) < SMOOTHED(3, -2)) << 6) + ((SMOOTHED(-5, -20) < SMOOTHED(-12, 9)) << 5) + ((SMOOTHED(-6, 12) < SMOOTHED(-11, 3)) << 4) + ((SMOOTHED(4, 5) < SMOOTHED(13, 11)) << 3) + ((SMOOTHED(2, 12) < SMOOTHED(13, -12)) << 2) + ((SMOOTHED(-4, -13) < SMOOTHED(4, 7)) << 1) + ((SMOOTHED(0, 15) < SMOOTHED(-3, -16)) << 0)); |
||||
desc[49] = (uchar)(((SMOOTHED(-3, 2) < SMOOTHED(-2, 14)) << 7) + ((SMOOTHED(4, -14) < SMOOTHED(16, -11)) << 6) + ((SMOOTHED(-13, 3) < SMOOTHED(23, 10)) << 5) + ((SMOOTHED(9, -19) < SMOOTHED(2, 5)) << 4) + ((SMOOTHED(5, 3) < SMOOTHED(14, -7)) << 3) + ((SMOOTHED(19, -13) < SMOOTHED(-11, 15)) << 2) + ((SMOOTHED(14, 0) < SMOOTHED(-2, -5)) << 1) + ((SMOOTHED(11, -4) < SMOOTHED(0, -6)) << 0)); |
||||
desc[50] = (uchar)(((SMOOTHED(-2, 5) < SMOOTHED(-13, -8)) << 7) + ((SMOOTHED(-11, -15) < SMOOTHED(-7, -17)) << 6) + ((SMOOTHED(1, 3) < SMOOTHED(-10, -8)) << 5) + ((SMOOTHED(-13, -10) < SMOOTHED(7, -12)) << 4) + ((SMOOTHED(0, -13) < SMOOTHED(23, -6)) << 3) + ((SMOOTHED(2, -17) < SMOOTHED(-7, -3)) << 2) + ((SMOOTHED(1, 3) < SMOOTHED(4, -10)) << 1) + ((SMOOTHED(13, 4) < SMOOTHED(14, -6)) << 0)); |
||||
desc[51] = (uchar)(((SMOOTHED(-19, -2) < SMOOTHED(-1, 5)) << 7) + ((SMOOTHED(9, -8) < SMOOTHED(10, -5)) << 6) + ((SMOOTHED(7, -1) < SMOOTHED(5, 7)) << 5) + ((SMOOTHED(9, -10) < SMOOTHED(19, 0)) << 4) + ((SMOOTHED(7, 5) < SMOOTHED(-4, -7)) << 3) + ((SMOOTHED(-11, 1) < SMOOTHED(-1, -11)) << 2) + ((SMOOTHED(2, -1) < SMOOTHED(-4, 11)) << 1) + ((SMOOTHED(-1, 7) < SMOOTHED(2, -2)) << 0)); |
||||
desc[52] = (uchar)(((SMOOTHED(1, -20) < SMOOTHED(-9, -6)) << 7) + ((SMOOTHED(-4, -18) < SMOOTHED(8, -18)) << 6) + ((SMOOTHED(-16, -2) < SMOOTHED(7, -6)) << 5) + ((SMOOTHED(-3, -6) < SMOOTHED(-1, -4)) << 4) + ((SMOOTHED(0, -16) < SMOOTHED(24, -5)) << 3) + ((SMOOTHED(-4, -2) < SMOOTHED(-1, 9)) << 2) + ((SMOOTHED(-8, 2) < SMOOTHED(-6, 15)) << 1) + ((SMOOTHED(11, 4) < SMOOTHED(0, -3)) << 0)); |
||||
desc[53] = (uchar)(((SMOOTHED(7, 6) < SMOOTHED(2, -10)) << 7) + ((SMOOTHED(-7, -9) < SMOOTHED(12, -6)) << 6) + ((SMOOTHED(24, 15) < SMOOTHED(-8, -1)) << 5) + ((SMOOTHED(15, -9) < SMOOTHED(-3, -15)) << 4) + ((SMOOTHED(17, -5) < SMOOTHED(11, -10)) << 3) + ((SMOOTHED(-2, 13) < SMOOTHED(-15, 4)) << 2) + ((SMOOTHED(-2, -1) < SMOOTHED(4, -23)) << 1) + ((SMOOTHED(-16, 3) < SMOOTHED(-7, -14)) << 0)); |
||||
desc[54] = (uchar)(((SMOOTHED(-3, -5) < SMOOTHED(-10, -9)) << 7) + ((SMOOTHED(-5, 3) < SMOOTHED(-2, -1)) << 6) + ((SMOOTHED(-1, 4) < SMOOTHED(1, 8)) << 5) + ((SMOOTHED(12, 9) < SMOOTHED(9, -14)) << 4) + ((SMOOTHED(-9, 17) < SMOOTHED(-3, 0)) << 3) + ((SMOOTHED(5, 4) < SMOOTHED(13, -6)) << 2) + ((SMOOTHED(-1, -8) < SMOOTHED(19, 10)) << 1) + ((SMOOTHED(8, -5) < SMOOTHED(-15, 2)) << 0)); |
||||
desc[55] = (uchar)(((SMOOTHED(-12, -9) < SMOOTHED(-4, -5)) << 7) + ((SMOOTHED(12, 0) < SMOOTHED(24, 4)) << 6) + ((SMOOTHED(8, -2) < SMOOTHED(14, 4)) << 5) + ((SMOOTHED(8, -4) < SMOOTHED(-7, 16)) << 4) + ((SMOOTHED(5, -1) < SMOOTHED(-8, -4)) << 3) + ((SMOOTHED(-2, 18) < SMOOTHED(-5, 17)) << 2) + ((SMOOTHED(8, -2) < SMOOTHED(-9, -2)) << 1) + ((SMOOTHED(3, -7) < SMOOTHED(1, -6)) << 0)); |
||||
desc[56] = (uchar)(((SMOOTHED(-5, -22) < SMOOTHED(-5, -2)) << 7) + ((SMOOTHED(-8, -10) < SMOOTHED(14, 1)) << 6) + ((SMOOTHED(-3, -13) < SMOOTHED(3, 9)) << 5) + ((SMOOTHED(-4, -1) < SMOOTHED(-1, 0)) << 4) + ((SMOOTHED(-7, -21) < SMOOTHED(12, -19)) << 3) + ((SMOOTHED(-8, 8) < SMOOTHED(24, 8)) << 2) + ((SMOOTHED(12, -6) < SMOOTHED(-2, 3)) << 1) + ((SMOOTHED(-5, -11) < SMOOTHED(-22, -4)) << 0)); |
||||
desc[57] = (uchar)(((SMOOTHED(-3, 5) < SMOOTHED(-4, 4)) << 7) + ((SMOOTHED(-16, 24) < SMOOTHED(7, -9)) << 6) + ((SMOOTHED(-10, 23) < SMOOTHED(-9, 18)) << 5) + ((SMOOTHED(1, 12) < SMOOTHED(17, 21)) << 4) + ((SMOOTHED(24, -6) < SMOOTHED(-3, -11)) << 3) + ((SMOOTHED(-7, 17) < SMOOTHED(1, -6)) << 2) + ((SMOOTHED(4, 4) < SMOOTHED(2, -7)) << 1) + ((SMOOTHED(14, 6) < SMOOTHED(-12, 3)) << 0)); |
||||
desc[58] = (uchar)(((SMOOTHED(-6, 0) < SMOOTHED(-16, 13)) << 7) + ((SMOOTHED(-10, 5) < SMOOTHED(7, 12)) << 6) + ((SMOOTHED(5, 2) < SMOOTHED(6, -3)) << 5) + ((SMOOTHED(7, 0) < SMOOTHED(-23, 1)) << 4) + ((SMOOTHED(15, -5) < SMOOTHED(1, 14)) << 3) + ((SMOOTHED(-3, -1) < SMOOTHED(6, 6)) << 2) + ((SMOOTHED(6, -9) < SMOOTHED(-9, 12)) << 1) + ((SMOOTHED(4, -2) < SMOOTHED(-4, 7)) << 0)); |
||||
desc[59] = (uchar)(((SMOOTHED(-4, -5) < SMOOTHED(4, 4)) << 7) + ((SMOOTHED(-13, 0) < SMOOTHED(6, -10)) << 6) + ((SMOOTHED(2, -12) < SMOOTHED(-6, -3)) << 5) + ((SMOOTHED(16, 0) < SMOOTHED(-3, 3)) << 4) + ((SMOOTHED(5, -14) < SMOOTHED(6, 11)) << 3) + ((SMOOTHED(5, 11) < SMOOTHED(0, -13)) << 2) + ((SMOOTHED(7, 5) < SMOOTHED(-1, -5)) << 1) + ((SMOOTHED(12, 4) < SMOOTHED(6, 10)) << 0)); |
||||
desc[60] = (uchar)(((SMOOTHED(-10, 4) < SMOOTHED(-1, -11)) << 7) + ((SMOOTHED(4, 10) < SMOOTHED(-14, 5)) << 6) + ((SMOOTHED(11, -14) < SMOOTHED(-13, 0)) << 5) + ((SMOOTHED(2, 8) < SMOOTHED(12, 24)) << 4) + ((SMOOTHED(-1, 3) < SMOOTHED(-1, 2)) << 3) + ((SMOOTHED(9, -14) < SMOOTHED(-23, 3)) << 2) + ((SMOOTHED(-8, -6) < SMOOTHED(0, 9)) << 1) + ((SMOOTHED(-15, 14) < SMOOTHED(10, -10)) << 0)); |
||||
desc[61] = (uchar)(((SMOOTHED(-10, -6) < SMOOTHED(-7, -5)) << 7) + ((SMOOTHED(11, 5) < SMOOTHED(-3, -15)) << 6) + ((SMOOTHED(1, 0) < SMOOTHED(1, 8)) << 5) + ((SMOOTHED(-11, -6) < SMOOTHED(-4, -18)) << 4) + ((SMOOTHED(9, 0) < SMOOTHED(22, -4)) << 3) + ((SMOOTHED(-5, -1) < SMOOTHED(-9, 4)) << 2) + ((SMOOTHED(-20, 2) < SMOOTHED(1, 6)) << 1) + ((SMOOTHED(1, 2) < SMOOTHED(-9, -12)) << 0)); |
||||
desc[62] = (uchar)(((SMOOTHED(5, 15) < SMOOTHED(4, -6)) << 7) + ((SMOOTHED(19, 4) < SMOOTHED(4, 11)) << 6) + ((SMOOTHED(17, -4) < SMOOTHED(-8, -1)) << 5) + ((SMOOTHED(-8, -12) < SMOOTHED(7, -3)) << 4) + ((SMOOTHED(11, 9) < SMOOTHED(8, 1)) << 3) + ((SMOOTHED(9, 22) < SMOOTHED(-15, 15)) << 2) + ((SMOOTHED(-7, -7) < SMOOTHED(1, -23)) << 1) + ((SMOOTHED(-5, 13) < SMOOTHED(-8, 2)) << 0)); |
||||
desc[63] = (uchar)(((SMOOTHED(3, -5) < SMOOTHED(11, -11)) << 7) + ((SMOOTHED(3, -18) < SMOOTHED(14, -5)) << 6) + ((SMOOTHED(-20, 7) < SMOOTHED(-10, -23)) << 5) + ((SMOOTHED(-2, -5) < SMOOTHED(6, 0)) << 4) + ((SMOOTHED(-17, -13) < SMOOTHED(-3, 2)) << 3) + ((SMOOTHED(-6, -1) < SMOOTHED(14, -2)) << 2) + ((SMOOTHED(-12, -16) < SMOOTHED(15, 6)) << 1) + ((SMOOTHED(-12, -2) < SMOOTHED(3, -19)) << 0)); |
||||
#undef SMOOTHED |
@ -1,472 +0,0 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2008-2012, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
namespace cv |
||||
{ |
||||
|
||||
template <typename inMatType, typename outMatType> static void |
||||
computeIntegralImages( const Mat& matI, Mat& matS, Mat& matT, Mat& _FT, |
||||
int iiType ) |
||||
{ |
||||
int x, y, rows = matI.rows, cols = matI.cols; |
||||
|
||||
matS.create(rows + 1, cols + 1, iiType ); |
||||
matT.create(rows + 1, cols + 1, iiType ); |
||||
_FT.create(rows + 1, cols + 1, iiType ); |
||||
|
||||
const inMatType* I = matI.ptr<inMatType>(); |
||||
|
||||
outMatType *S = matS.ptr<outMatType>(); |
||||
outMatType *T = matT.ptr<outMatType>(); |
||||
outMatType *FT = _FT.ptr<outMatType>(); |
||||
|
||||
int istep = (int)(matI.step/matI.elemSize()); |
||||
int step = (int)(matS.step/matS.elemSize()); |
||||
|
||||
for( x = 0; x <= cols; x++ ) |
||||
S[x] = T[x] = FT[x] = 0; |
||||
|
||||
S += step; T += step; FT += step; |
||||
S[0] = T[0] = 0; |
||||
FT[0] = I[0]; |
||||
for( x = 1; x < cols; x++ ) |
||||
{ |
||||
S[x] = S[x-1] + I[x-1]; |
||||
T[x] = I[x-1]; |
||||
FT[x] = I[x] + I[x-1]; |
||||
} |
||||
S[cols] = S[cols-1] + I[cols-1]; |
||||
T[cols] = FT[cols] = I[cols-1]; |
||||
|
||||
for( y = 2; y <= rows; y++ ) |
||||
{ |
||||
I += istep, S += step, T += step, FT += step; |
||||
|
||||
S[0] = S[-step]; S[1] = S[-step+1] + I[0]; |
||||
T[0] = T[-step + 1]; |
||||
T[1] = FT[0] = T[-step + 2] + I[-istep] + I[0]; |
||||
FT[1] = FT[-step + 2] + I[-istep] + I[1] + I[0]; |
||||
|
||||
for( x = 2; x < cols; x++ ) |
||||
{ |
||||
S[x] = S[x - 1] + S[-step + x] - S[-step + x - 1] + I[x - 1]; |
||||
T[x] = T[-step + x - 1] + T[-step + x + 1] - T[-step*2 + x] + I[-istep + x - 1] + I[x - 1]; |
||||
FT[x] = FT[-step + x - 1] + FT[-step + x + 1] - FT[-step*2 + x] + I[x] + I[x-1]; |
||||
} |
||||
|
||||
S[cols] = S[cols - 1] + S[-step + cols] - S[-step + cols - 1] + I[cols - 1]; |
||||
T[cols] = FT[cols] = T[-step + cols - 1] + I[-istep + cols - 1] + I[cols - 1]; |
||||
} |
||||
} |
||||
|
||||
template <typename iiMatType> static int |
||||
StarDetectorComputeResponses( const Mat& img, Mat& responses, Mat& sizes, |
||||
int maxSize, int iiType ) |
||||
{ |
||||
const int MAX_PATTERN = 17; |
||||
static const int sizes0[] = {1, 2, 3, 4, 6, 8, 11, 12, 16, 22, 23, 32, 45, 46, 64, 90, 128, -1}; |
||||
static const int pairs[][2] = {{1, 0}, {3, 1}, {4, 2}, {5, 3}, {7, 4}, {8, 5}, {9, 6}, |
||||
{11, 8}, {13, 10}, {14, 11}, {15, 12}, {16, 14}, {-1, -1}}; |
||||
float invSizes[MAX_PATTERN][2]; |
||||
int sizes1[MAX_PATTERN]; |
||||
|
||||
#if CV_SSE2 |
||||
__m128 invSizes4[MAX_PATTERN][2]; |
||||
__m128 sizes1_4[MAX_PATTERN]; |
||||
union { int i; float f; } absmask; |
||||
absmask.i = 0x7fffffff; |
||||
volatile bool useSIMD = cv::checkHardwareSupport(CV_CPU_SSE2) && iiType == CV_32S; |
||||
#endif |
||||
|
||||
struct StarFeature |
||||
{ |
||||
int area; |
||||
iiMatType* p[8]; |
||||
}; |
||||
|
||||
StarFeature f[MAX_PATTERN]; |
||||
|
||||
Mat sum, tilted, flatTilted; |
||||
int y, rows = img.rows, cols = img.cols; |
||||
int border, npatterns=0, maxIdx=0; |
||||
|
||||
responses.create( img.size(), CV_32F ); |
||||
sizes.create( img.size(), CV_16S ); |
||||
|
||||
while( pairs[npatterns][0] >= 0 && ! |
||||
( sizes0[pairs[npatterns][0]] >= maxSize |
||||
|| sizes0[pairs[npatterns+1][0]] + sizes0[pairs[npatterns+1][0]]/2 >= std::min(rows, cols) ) ) |
||||
{ |
||||
++npatterns; |
||||
} |
||||
|
||||
npatterns += (pairs[npatterns-1][0] >= 0); |
||||
maxIdx = pairs[npatterns-1][0]; |
||||
|
||||
// Create the integral image appropriate for our type & usage
|
||||
if ( img.type() == CV_8U ) |
||||
computeIntegralImages<uchar, iiMatType>( img, sum, tilted, flatTilted, iiType ); |
||||
else if ( img.type() == CV_8S ) |
||||
computeIntegralImages<char, iiMatType>( img, sum, tilted, flatTilted, iiType ); |
||||
else if ( img.type() == CV_16U ) |
||||
computeIntegralImages<ushort, iiMatType>( img, sum, tilted, flatTilted, iiType ); |
||||
else if ( img.type() == CV_16S ) |
||||
computeIntegralImages<short, iiMatType>( img, sum, tilted, flatTilted, iiType ); |
||||
else |
||||
CV_Error( Error::StsUnsupportedFormat, "" ); |
||||
|
||||
int step = (int)(sum.step/sum.elemSize()); |
||||
|
||||
for(int i = 0; i <= maxIdx; i++ ) |
||||
{ |
||||
int ur_size = sizes0[i], t_size = sizes0[i] + sizes0[i]/2; |
||||
int ur_area = (2*ur_size + 1)*(2*ur_size + 1); |
||||
int t_area = t_size*t_size + (t_size + 1)*(t_size + 1); |
||||
|
||||
f[i].p[0] = sum.ptr<iiMatType>() + (ur_size + 1)*step + ur_size + 1; |
||||
f[i].p[1] = sum.ptr<iiMatType>() - ur_size*step + ur_size + 1; |
||||
f[i].p[2] = sum.ptr<iiMatType>() + (ur_size + 1)*step - ur_size; |
||||
f[i].p[3] = sum.ptr<iiMatType>() - ur_size*step - ur_size; |
||||
|
||||
f[i].p[4] = tilted.ptr<iiMatType>() + (t_size + 1)*step + 1; |
||||
f[i].p[5] = flatTilted.ptr<iiMatType>() - t_size; |
||||
f[i].p[6] = flatTilted.ptr<iiMatType>() + t_size + 1; |
||||
f[i].p[7] = tilted.ptr<iiMatType>() - t_size*step + 1; |
||||
|
||||
f[i].area = ur_area + t_area; |
||||
sizes1[i] = sizes0[i]; |
||||
} |
||||
// negate end points of the size range
|
||||
// for a faster rejection of very small or very large features in non-maxima suppression.
|
||||
sizes1[0] = -sizes1[0]; |
||||
sizes1[1] = -sizes1[1]; |
||||
sizes1[maxIdx] = -sizes1[maxIdx]; |
||||
border = sizes0[maxIdx] + sizes0[maxIdx]/2; |
||||
|
||||
for(int i = 0; i < npatterns; i++ ) |
||||
{ |
||||
int innerArea = f[pairs[i][1]].area; |
||||
int outerArea = f[pairs[i][0]].area - innerArea; |
||||
invSizes[i][0] = 1.f/outerArea; |
||||
invSizes[i][1] = 1.f/innerArea; |
||||
} |
||||
|
||||
#if CV_SSE2 |
||||
if( useSIMD ) |
||||
{ |
||||
for(int i = 0; i < npatterns; i++ ) |
||||
{ |
||||
_mm_store_ps((float*)&invSizes4[i][0], _mm_set1_ps(invSizes[i][0])); |
||||
_mm_store_ps((float*)&invSizes4[i][1], _mm_set1_ps(invSizes[i][1])); |
||||
} |
||||
|
||||
for(int i = 0; i <= maxIdx; i++ ) |
||||
_mm_store_ps((float*)&sizes1_4[i], _mm_set1_ps((float)sizes1[i])); |
||||
} |
||||
#endif |
||||
|
||||
for( y = 0; y < border; y++ ) |
||||
{ |
||||
float* r_ptr = responses.ptr<float>(y); |
||||
float* r_ptr2 = responses.ptr<float>(rows - 1 - y); |
||||
short* s_ptr = sizes.ptr<short>(y); |
||||
short* s_ptr2 = sizes.ptr<short>(rows - 1 - y); |
||||
|
||||
memset( r_ptr, 0, cols*sizeof(r_ptr[0])); |
||||
memset( r_ptr2, 0, cols*sizeof(r_ptr2[0])); |
||||
memset( s_ptr, 0, cols*sizeof(s_ptr[0])); |
||||
memset( s_ptr2, 0, cols*sizeof(s_ptr2[0])); |
||||
} |
||||
|
||||
for( y = border; y < rows - border; y++ ) |
||||
{ |
||||
int x = border; |
||||
float* r_ptr = responses.ptr<float>(y); |
||||
short* s_ptr = sizes.ptr<short>(y); |
||||
|
||||
memset( r_ptr, 0, border*sizeof(r_ptr[0])); |
||||
memset( s_ptr, 0, border*sizeof(s_ptr[0])); |
||||
memset( r_ptr + cols - border, 0, border*sizeof(r_ptr[0])); |
||||
memset( s_ptr + cols - border, 0, border*sizeof(s_ptr[0])); |
||||
|
||||
#if CV_SSE2 |
||||
if( useSIMD ) |
||||
{ |
||||
__m128 absmask4 = _mm_set1_ps(absmask.f); |
||||
for( ; x <= cols - border - 4; x += 4 ) |
||||
{ |
||||
int ofs = y*step + x; |
||||
__m128 vals[MAX_PATTERN]; |
||||
__m128 bestResponse = _mm_setzero_ps(); |
||||
__m128 bestSize = _mm_setzero_ps(); |
||||
|
||||
for(int i = 0; i <= maxIdx; i++ ) |
||||
{ |
||||
const iiMatType** p = (const iiMatType**)&f[i].p[0]; |
||||
__m128i r0 = _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(p[0]+ofs)), |
||||
_mm_loadu_si128((const __m128i*)(p[1]+ofs))); |
||||
__m128i r1 = _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(p[3]+ofs)), |
||||
_mm_loadu_si128((const __m128i*)(p[2]+ofs))); |
||||
__m128i r2 = _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(p[4]+ofs)), |
||||
_mm_loadu_si128((const __m128i*)(p[5]+ofs))); |
||||
__m128i r3 = _mm_sub_epi32(_mm_loadu_si128((const __m128i*)(p[7]+ofs)), |
||||
_mm_loadu_si128((const __m128i*)(p[6]+ofs))); |
||||
r0 = _mm_add_epi32(_mm_add_epi32(r0,r1), _mm_add_epi32(r2,r3)); |
||||
_mm_store_ps((float*)&vals[i], _mm_cvtepi32_ps(r0)); |
||||
} |
||||
|
||||
for(int i = 0; i < npatterns; i++ ) |
||||
{ |
||||
__m128 inner_sum = vals[pairs[i][1]]; |
||||
__m128 outer_sum = _mm_sub_ps(vals[pairs[i][0]], inner_sum); |
||||
__m128 response = _mm_sub_ps(_mm_mul_ps(inner_sum, invSizes4[i][1]), |
||||
_mm_mul_ps(outer_sum, invSizes4[i][0])); |
||||
__m128 swapmask = _mm_cmpgt_ps(_mm_and_ps(response,absmask4), |
||||
_mm_and_ps(bestResponse,absmask4)); |
||||
bestResponse = _mm_xor_ps(bestResponse, |
||||
_mm_and_ps(_mm_xor_ps(response,bestResponse), swapmask)); |
||||
bestSize = _mm_xor_ps(bestSize, |
||||
_mm_and_ps(_mm_xor_ps(sizes1_4[pairs[i][0]], bestSize), swapmask)); |
||||
} |
||||
|
||||
_mm_storeu_ps(r_ptr + x, bestResponse); |
||||
_mm_storel_epi64((__m128i*)(s_ptr + x), |
||||
_mm_packs_epi32(_mm_cvtps_epi32(bestSize),_mm_setzero_si128())); |
||||
} |
||||
} |
||||
#endif |
||||
for( ; x < cols - border; x++ ) |
||||
{ |
||||
int ofs = y*step + x; |
||||
int vals[MAX_PATTERN]; |
||||
float bestResponse = 0; |
||||
int bestSize = 0; |
||||
|
||||
for(int i = 0; i <= maxIdx; i++ ) |
||||
{ |
||||
const iiMatType** p = (const iiMatType**)&f[i].p[0]; |
||||
vals[i] = (int)(p[0][ofs] - p[1][ofs] - p[2][ofs] + p[3][ofs] + |
||||
p[4][ofs] - p[5][ofs] - p[6][ofs] + p[7][ofs]); |
||||
} |
||||
for(int i = 0; i < npatterns; i++ ) |
||||
{ |
||||
int inner_sum = vals[pairs[i][1]]; |
||||
int outer_sum = vals[pairs[i][0]] - inner_sum; |
||||
float response = inner_sum*invSizes[i][1] - outer_sum*invSizes[i][0]; |
||||
if( fabs(response) > fabs(bestResponse) ) |
||||
{ |
||||
bestResponse = response; |
||||
bestSize = sizes1[pairs[i][0]]; |
||||
} |
||||
} |
||||
|
||||
r_ptr[x] = bestResponse; |
||||
s_ptr[x] = (short)bestSize; |
||||
} |
||||
} |
||||
|
||||
return border; |
||||
} |
||||
|
||||
|
||||
static bool StarDetectorSuppressLines( const Mat& responses, const Mat& sizes, Point pt, |
||||
int lineThresholdProjected, int lineThresholdBinarized ) |
||||
{ |
||||
const float* r_ptr = responses.ptr<float>(); |
||||
int rstep = (int)(responses.step/sizeof(r_ptr[0])); |
||||
const short* s_ptr = sizes.ptr<short>(); |
||||
int sstep = (int)(sizes.step/sizeof(s_ptr[0])); |
||||
int sz = s_ptr[pt.y*sstep + pt.x]; |
||||
int x, y, delta = sz/4, radius = delta*4; |
||||
float Lxx = 0, Lyy = 0, Lxy = 0; |
||||
int Lxxb = 0, Lyyb = 0, Lxyb = 0; |
||||
|
||||
for( y = pt.y - radius; y <= pt.y + radius; y += delta ) |
||||
for( x = pt.x - radius; x <= pt.x + radius; x += delta ) |
||||
{ |
||||
float Lx = r_ptr[y*rstep + x + 1] - r_ptr[y*rstep + x - 1]; |
||||
float Ly = r_ptr[(y+1)*rstep + x] - r_ptr[(y-1)*rstep + x]; |
||||
Lxx += Lx*Lx; Lyy += Ly*Ly; Lxy += Lx*Ly; |
||||
} |
||||
|
||||
if( (Lxx + Lyy)*(Lxx + Lyy) >= lineThresholdProjected*(Lxx*Lyy - Lxy*Lxy) ) |
||||
return true; |
||||
|
||||
for( y = pt.y - radius; y <= pt.y + radius; y += delta ) |
||||
for( x = pt.x - radius; x <= pt.x + radius; x += delta ) |
||||
{ |
||||
int Lxb = (s_ptr[y*sstep + x + 1] == sz) - (s_ptr[y*sstep + x - 1] == sz); |
||||
int Lyb = (s_ptr[(y+1)*sstep + x] == sz) - (s_ptr[(y-1)*sstep + x] == sz); |
||||
Lxxb += Lxb * Lxb; Lyyb += Lyb * Lyb; Lxyb += Lxb * Lyb; |
||||
} |
||||
|
||||
if( (Lxxb + Lyyb)*(Lxxb + Lyyb) >= lineThresholdBinarized*(Lxxb*Lyyb - Lxyb*Lxyb) ) |
||||
return true; |
||||
|
||||
return false; |
||||
} |
||||
|
||||
|
||||
static void |
||||
StarDetectorSuppressNonmax( const Mat& responses, const Mat& sizes, |
||||
std::vector<KeyPoint>& keypoints, int border, |
||||
int responseThreshold, |
||||
int lineThresholdProjected, |
||||
int lineThresholdBinarized, |
||||
int suppressNonmaxSize ) |
||||
{ |
||||
int x, y, x1, y1, delta = suppressNonmaxSize/2; |
||||
int rows = responses.rows, cols = responses.cols; |
||||
const float* r_ptr = responses.ptr<float>(); |
||||
int rstep = (int)(responses.step/sizeof(r_ptr[0])); |
||||
const short* s_ptr = sizes.ptr<short>(); |
||||
int sstep = (int)(sizes.step/sizeof(s_ptr[0])); |
||||
short featureSize = 0; |
||||
|
||||
for( y = border; y < rows - border; y += delta+1 ) |
||||
for( x = border; x < cols - border; x += delta+1 ) |
||||
{ |
||||
float maxResponse = (float)responseThreshold; |
||||
float minResponse = (float)-responseThreshold; |
||||
Point maxPt(-1, -1), minPt(-1, -1); |
||||
int tileEndY = MIN(y + delta, rows - border - 1); |
||||
int tileEndX = MIN(x + delta, cols - border - 1); |
||||
|
||||
for( y1 = y; y1 <= tileEndY; y1++ ) |
||||
for( x1 = x; x1 <= tileEndX; x1++ ) |
||||
{ |
||||
float val = r_ptr[y1*rstep + x1]; |
||||
if( maxResponse < val ) |
||||
{ |
||||
maxResponse = val; |
||||
maxPt = Point(x1, y1); |
||||
} |
||||
else if( minResponse > val ) |
||||
{ |
||||
minResponse = val; |
||||
minPt = Point(x1, y1); |
||||
} |
||||
} |
||||
|
||||
if( maxPt.x >= 0 ) |
||||
{ |
||||
for( y1 = maxPt.y - delta; y1 <= maxPt.y + delta; y1++ ) |
||||
for( x1 = maxPt.x - delta; x1 <= maxPt.x + delta; x1++ ) |
||||
{ |
||||
float val = r_ptr[y1*rstep + x1]; |
||||
if( val >= maxResponse && (y1 != maxPt.y || x1 != maxPt.x)) |
||||
goto skip_max; |
||||
} |
||||
|
||||
if( (featureSize = s_ptr[maxPt.y*sstep + maxPt.x]) >= 4 && |
||||
!StarDetectorSuppressLines( responses, sizes, maxPt, lineThresholdProjected, |
||||
lineThresholdBinarized )) |
||||
{ |
||||
KeyPoint kpt((float)maxPt.x, (float)maxPt.y, featureSize, -1, maxResponse); |
||||
keypoints.push_back(kpt); |
||||
} |
||||
} |
||||
skip_max: |
||||
if( minPt.x >= 0 ) |
||||
{ |
||||
for( y1 = minPt.y - delta; y1 <= minPt.y + delta; y1++ ) |
||||
for( x1 = minPt.x - delta; x1 <= minPt.x + delta; x1++ ) |
||||
{ |
||||
float val = r_ptr[y1*rstep + x1]; |
||||
if( val <= minResponse && (y1 != minPt.y || x1 != minPt.x)) |
||||
goto skip_min; |
||||
} |
||||
|
||||
if( (featureSize = s_ptr[minPt.y*sstep + minPt.x]) >= 4 && |
||||
!StarDetectorSuppressLines( responses, sizes, minPt, |
||||
lineThresholdProjected, lineThresholdBinarized)) |
||||
{ |
||||
KeyPoint kpt((float)minPt.x, (float)minPt.y, featureSize, -1, maxResponse); |
||||
keypoints.push_back(kpt); |
||||
} |
||||
} |
||||
skip_min: |
||||
; |
||||
} |
||||
} |
||||
|
||||
StarDetector::StarDetector(int _maxSize, int _responseThreshold, |
||||
int _lineThresholdProjected, |
||||
int _lineThresholdBinarized, |
||||
int _suppressNonmaxSize) |
||||
: maxSize(_maxSize), responseThreshold(_responseThreshold), |
||||
lineThresholdProjected(_lineThresholdProjected), |
||||
lineThresholdBinarized(_lineThresholdBinarized), |
||||
suppressNonmaxSize(_suppressNonmaxSize) |
||||
{} |
||||
|
||||
|
||||
void StarDetector::detectImpl( InputArray _image, std::vector<KeyPoint>& keypoints, InputArray _mask ) const |
||||
{ |
||||
Mat image = _image.getMat(), mask = _mask.getMat(), grayImage = image; |
||||
if( image.channels() > 1 ) cvtColor( image, grayImage, COLOR_BGR2GRAY ); |
||||
|
||||
(*this)(grayImage, keypoints); |
||||
KeyPointsFilter::runByPixelsMask( keypoints, mask ); |
||||
} |
||||
|
||||
void StarDetector::operator()(const Mat& img, std::vector<KeyPoint>& keypoints) const |
||||
{ |
||||
Mat responses, sizes; |
||||
int border; |
||||
|
||||
// Use 32-bit integers if we won't overflow in the integral image
|
||||
if ((img.depth() == CV_8U || img.depth() == CV_8S) && |
||||
(img.rows * img.cols) < 8388608 ) // 8388608 = 2 ^ (32 - 8(bit depth) - 1(sign bit))
|
||||
border = StarDetectorComputeResponses<int>( img, responses, sizes, maxSize, CV_32S ); |
||||
else |
||||
border = StarDetectorComputeResponses<double>( img, responses, sizes, maxSize, CV_64F ); |
||||
|
||||
keypoints.clear(); |
||||
if( border >= 0 ) |
||||
StarDetectorSuppressNonmax( responses, sizes, keypoints, border, |
||||
responseThreshold, lineThresholdProjected, |
||||
lineThresholdBinarized, suppressNonmaxSize ); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,107 @@ |
||||
ColorMaps in OpenCV |
||||
=================== |
||||
|
||||
applyColorMap |
||||
--------------------- |
||||
|
||||
Applies a GNU Octave/MATLAB equivalent colormap on a given image. |
||||
|
||||
.. ocv:function:: void applyColorMap(InputArray src, OutputArray dst, int colormap) |
||||
|
||||
:param src: The source image, grayscale or colored does not matter. |
||||
:param dst: The result is the colormapped source image. Note: :ocv:func:`Mat::create` is called on dst. |
||||
:param colormap: The colormap to apply, see the list of available colormaps below. |
||||
|
||||
Currently the following GNU Octave/MATLAB equivalent colormaps are implemented: |
||||
|
||||
.. code-block:: cpp |
||||
|
||||
enum |
||||
{ |
||||
COLORMAP_AUTUMN = 0, |
||||
COLORMAP_BONE = 1, |
||||
COLORMAP_JET = 2, |
||||
COLORMAP_WINTER = 3, |
||||
COLORMAP_RAINBOW = 4, |
||||
COLORMAP_OCEAN = 5, |
||||
COLORMAP_SUMMER = 6, |
||||
COLORMAP_SPRING = 7, |
||||
COLORMAP_COOL = 8, |
||||
COLORMAP_HSV = 9, |
||||
COLORMAP_PINK = 10, |
||||
COLORMAP_HOT = 11 |
||||
} |
||||
|
||||
|
||||
Description |
||||
----------- |
||||
|
||||
The human perception isn't built for observing fine changes in grayscale images. Human eyes are more sensitive to observing changes between colors, so you often need to recolor your grayscale images to get a clue about them. OpenCV now comes with various colormaps to enhance the visualization in your computer vision application. |
||||
|
||||
In OpenCV 2.4 you only need :ocv:func:`applyColorMap` to apply a colormap on a given image. The following sample code reads the path to an image from command line, applies a Jet colormap on it and shows the result: |
||||
|
||||
.. code-block:: cpp |
||||
|
||||
#include <opencv2/contrib.hpp> |
||||
#include <opencv2/core.hpp> |
||||
#include <opencv2/highgui.hpp> |
||||
|
||||
using namespace cv; |
||||
|
||||
int main(int argc, const char *argv[]) { |
||||
// Get the path to the image, if it was given |
||||
// if no arguments were given. |
||||
String filename; |
||||
if (argc > 1) { |
||||
filename = String(argv[1]); |
||||
} |
||||
// The following lines show how to apply a colormap on a given image |
||||
// and show it with cv::imshow example with an image. An exception is |
||||
// thrown if the path to the image is invalid. |
||||
if(!filename.empty()) { |
||||
Mat img0 = imread(filename); |
||||
// Throw an exception, if the image can't be read: |
||||
if(img0.empty()) { |
||||
CV_Error(CV_StsBadArg, "Sample image is empty. Please adjust your path, so it points to a valid input image!"); |
||||
} |
||||
// Holds the colormap version of the image: |
||||
Mat cm_img0; |
||||
// Apply the colormap: |
||||
applyColorMap(img0, cm_img0, COLORMAP_JET); |
||||
// Show the result: |
||||
imshow("cm_img0", cm_img0); |
||||
waitKey(0); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
And here are the color scales for each of the available colormaps: |
||||
|
||||
+-----------------------+---------------------------------------------------+ |
||||
| Class | Scale | |
||||
+=======================+===================================================+ |
||||
| COLORMAP_AUTUMN | .. image:: pics/colormaps/colorscale_autumn.jpg | |
||||
+-----------------------+---------------------------------------------------+ |
||||
| COLORMAP_BONE | .. image:: pics/colormaps/colorscale_bone.jpg | |
||||
+-----------------------+---------------------------------------------------+ |
||||
| COLORMAP_COOL | .. image:: pics/colormaps/colorscale_cool.jpg | |
||||
+-----------------------+---------------------------------------------------+ |
||||
| COLORMAP_HOT | .. image:: pics/colormaps/colorscale_hot.jpg | |
||||
+-----------------------+---------------------------------------------------+ |
||||
| COLORMAP_HSV | .. image:: pics/colormaps/colorscale_hsv.jpg | |
||||
+-----------------------+---------------------------------------------------+ |
||||
| COLORMAP_JET | .. image:: pics/colormaps/colorscale_jet.jpg | |
||||
+-----------------------+---------------------------------------------------+ |
||||
| COLORMAP_OCEAN | .. image:: pics/colormaps/colorscale_ocean.jpg | |
||||
+-----------------------+---------------------------------------------------+ |
||||
| COLORMAP_PINK | .. image:: pics/colormaps/colorscale_pink.jpg | |
||||
+-----------------------+---------------------------------------------------+ |
||||
| COLORMAP_RAINBOW | .. image:: pics/colormaps/colorscale_rainbow.jpg | |
||||
+-----------------------+---------------------------------------------------+ |
||||
| COLORMAP_SPRING | .. image:: pics/colormaps/colorscale_spring.jpg | |
||||
+-----------------------+---------------------------------------------------+ |
||||
| COLORMAP_SUMMER | .. image:: pics/colormaps/colorscale_summer.jpg | |
||||
+-----------------------+---------------------------------------------------+ |
||||
| COLORMAP_WINTER | .. image:: pics/colormaps/colorscale_winter.jpg | |
||||
+-----------------------+---------------------------------------------------+ |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,530 @@ |
||||
/*
|
||||
* Copyright (c) 2011. Philipp Wagner <bytefish[at]gmx[dot]de>. |
||||
* Released to public domain under terms of the BSD Simplified license. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of the organization nor the names of its contributors |
||||
* may be used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* See <http://www.opensource.org/licenses/bsd-license>
|
||||
*/ |
||||
#include "precomp.hpp" |
||||
#include <iostream> |
||||
|
||||
#ifdef _MSC_VER |
||||
#pragma warning( disable: 4305 ) |
||||
#endif |
||||
|
||||
namespace cv |
||||
{ |
||||
|
||||
static Mat linspace(float x0, float x1, int n) |
||||
{ |
||||
Mat pts(n, 1, CV_32FC1); |
||||
float step = (x1-x0)/(n-1); |
||||
for(int i = 0; i < n; i++) |
||||
pts.at<float>(i,0) = x0+i*step; |
||||
return pts; |
||||
} |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// cv::sortMatrixRowsByIndices
|
||||
//------------------------------------------------------------------------------
|
||||
static void sortMatrixRowsByIndices(InputArray _src, InputArray _indices, OutputArray _dst) |
||||
{ |
||||
if(_indices.getMat().type() != CV_32SC1) |
||||
CV_Error(Error::StsUnsupportedFormat, "cv::sortRowsByIndices only works on integer indices!"); |
||||
Mat src = _src.getMat(); |
||||
std::vector<int> indices = _indices.getMat(); |
||||
_dst.create(src.rows, src.cols, src.type()); |
||||
Mat dst = _dst.getMat(); |
||||
for(size_t idx = 0; idx < indices.size(); idx++) { |
||||
Mat originalRow = src.row(indices[idx]); |
||||
Mat sortedRow = dst.row((int)idx); |
||||
originalRow.copyTo(sortedRow); |
||||
} |
||||
} |
||||
|
||||
static Mat sortMatrixRowsByIndices(InputArray src, InputArray indices) |
||||
{ |
||||
Mat dst; |
||||
sortMatrixRowsByIndices(src, indices, dst); |
||||
return dst; |
||||
} |
||||
|
||||
|
||||
static Mat argsort(InputArray _src, bool ascending=true) |
||||
{ |
||||
Mat src = _src.getMat(); |
||||
if (src.rows != 1 && src.cols != 1) |
||||
CV_Error(Error::StsBadArg, "cv::argsort only sorts 1D matrices."); |
||||
int flags = SORT_EVERY_ROW | (ascending ? SORT_ASCENDING : SORT_DESCENDING); |
||||
Mat sorted_indices; |
||||
sortIdx(src.reshape(1,1),sorted_indices,flags); |
||||
return sorted_indices; |
||||
} |
||||
|
||||
template <typename _Tp> static |
||||
Mat interp1_(const Mat& X_, const Mat& Y_, const Mat& XI) |
||||
{ |
||||
int n = XI.rows; |
||||
// sort input table
|
||||
std::vector<int> sort_indices = argsort(X_); |
||||
|
||||
Mat X = sortMatrixRowsByIndices(X_,sort_indices); |
||||
Mat Y = sortMatrixRowsByIndices(Y_,sort_indices); |
||||
// interpolated values
|
||||
Mat yi = Mat::zeros(XI.size(), XI.type()); |
||||
for(int i = 0; i < n; i++) { |
||||
int c = 0; |
||||
int low = 0; |
||||
int high = X.rows - 1; |
||||
// set bounds
|
||||
if(XI.at<_Tp>(i,0) < X.at<_Tp>(low, 0)) |
||||
high = 1; |
||||
if(XI.at<_Tp>(i,0) > X.at<_Tp>(high, 0)) |
||||
low = high - 1; |
||||
// binary search
|
||||
while((high-low)>1) { |
||||
c = low + ((high - low) >> 1); |
||||
if(XI.at<_Tp>(i,0) > X.at<_Tp>(c,0)) { |
||||
low = c; |
||||
} else { |
||||
high = c; |
||||
} |
||||
} |
||||
// linear interpolation
|
||||
yi.at<_Tp>(i,0) += Y.at<_Tp>(low,0) |
||||
+ (XI.at<_Tp>(i,0) - X.at<_Tp>(low,0)) |
||||
* (Y.at<_Tp>(high,0) - Y.at<_Tp>(low,0)) |
||||
/ (X.at<_Tp>(high,0) - X.at<_Tp>(low,0)); |
||||
} |
||||
return yi; |
||||
} |
||||
|
||||
static Mat interp1(InputArray _x, InputArray _Y, InputArray _xi) |
||||
{ |
||||
// get matrices
|
||||
Mat x = _x.getMat(); |
||||
Mat Y = _Y.getMat(); |
||||
Mat xi = _xi.getMat(); |
||||
// check types & alignment
|
||||
CV_Assert((x.type() == Y.type()) && (Y.type() == xi.type())); |
||||
CV_Assert((x.cols == 1) && (x.rows == Y.rows) && (x.cols == Y.cols)); |
||||
// call templated interp1
|
||||
switch(x.type()) { |
||||
case CV_8SC1: return interp1_<char>(x,Y,xi); break; |
||||
case CV_8UC1: return interp1_<unsigned char>(x,Y,xi); break; |
||||
case CV_16SC1: return interp1_<short>(x,Y,xi); break; |
||||
case CV_16UC1: return interp1_<unsigned short>(x,Y,xi); break; |
||||
case CV_32SC1: return interp1_<int>(x,Y,xi); break; |
||||
case CV_32FC1: return interp1_<float>(x,Y,xi); break; |
||||
case CV_64FC1: return interp1_<double>(x,Y,xi); break; |
||||
default: CV_Error(Error::StsUnsupportedFormat, ""); break; |
||||
} |
||||
return Mat(); |
||||
} |
||||
|
||||
namespace colormap |
||||
{ |
||||
|
||||
class ColorMap { |
||||
|
||||
protected: |
||||
Mat _lut; |
||||
|
||||
public: |
||||
virtual ~ColorMap() {} |
||||
|
||||
// Applies the colormap on a given image.
|
||||
//
|
||||
// This function expects BGR-aligned data of type CV_8UC1 or
|
||||
// CV_8UC3. If the wrong image type is given, the original image
|
||||
// will be returned.
|
||||
//
|
||||
// Throws an error for wrong-aligned lookup table, which must be
|
||||
// of size 256 in the latest OpenCV release (2.3.1).
|
||||
void operator()(InputArray src, OutputArray dst) const; |
||||
|
||||
// Setup base map to interpolate from.
|
||||
virtual void init(int n) = 0; |
||||
|
||||
// Interpolates from a base colormap.
|
||||
static Mat linear_colormap(InputArray X, |
||||
InputArray r, InputArray g, InputArray b, |
||||
int n) { |
||||
return linear_colormap(X,r,g,b,linspace(0,1,n)); |
||||
} |
||||
|
||||
// Interpolates from a base colormap.
|
||||
static Mat linear_colormap(InputArray X, |
||||
InputArray r, InputArray g, InputArray b, |
||||
float begin, float end, float n) { |
||||
return linear_colormap(X,r,g,b,linspace(begin,end, cvRound(n))); |
||||
} |
||||
|
||||
// Interpolates from a base colormap.
|
||||
static Mat linear_colormap(InputArray X, |
||||
InputArray r, InputArray g, InputArray b, |
||||
InputArray xi); |
||||
}; |
||||
|
||||
// Equals the GNU Octave colormap "autumn".
|
||||
class Autumn : public ColorMap { |
||||
public: |
||||
Autumn() : ColorMap() { |
||||
init(256); |
||||
} |
||||
|
||||
Autumn(int n) : ColorMap() { |
||||
init(n); |
||||
} |
||||
|
||||
void init(int n) { |
||||
float r[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; |
||||
float g[] = { 0, 0.01587301587301587, 0.03174603174603174, 0.04761904761904762, 0.06349206349206349, 0.07936507936507936, 0.09523809523809523, 0.1111111111111111, 0.126984126984127, 0.1428571428571428, 0.1587301587301587, 0.1746031746031746, 0.1904761904761905, 0.2063492063492063, 0.2222222222222222, 0.2380952380952381, 0.253968253968254, 0.2698412698412698, 0.2857142857142857, 0.3015873015873016, 0.3174603174603174, 0.3333333333333333, 0.3492063492063492, 0.3650793650793651, 0.3809523809523809, 0.3968253968253968, 0.4126984126984127, 0.4285714285714285, 0.4444444444444444, 0.4603174603174603, 0.4761904761904762, 0.492063492063492, 0.5079365079365079, 0.5238095238095238, 0.5396825396825397, 0.5555555555555556, 0.5714285714285714, 0.5873015873015873, 0.6031746031746031, 0.6190476190476191, 0.6349206349206349, 0.6507936507936508, 0.6666666666666666, 0.6825396825396826, 0.6984126984126984, 0.7142857142857143, 0.7301587301587301, 0.746031746031746, 0.7619047619047619, 0.7777777777777778, 0.7936507936507936, 0.8095238095238095, 0.8253968253968254, 0.8412698412698413, 0.8571428571428571, 0.873015873015873, 0.8888888888888888, 0.9047619047619048, 0.9206349206349206, 0.9365079365079365, 0.9523809523809523, 0.9682539682539683, 0.9841269841269841, 1}; |
||||
float b[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
||||
Mat X = linspace(0,1,64); |
||||
this->_lut = ColorMap::linear_colormap(X, |
||||
Mat(64,1, CV_32FC1, r).clone(), // red
|
||||
Mat(64,1, CV_32FC1, g).clone(), // green
|
||||
Mat(64,1, CV_32FC1, b).clone(), // blue
|
||||
n); // number of sample points
|
||||
} |
||||
}; |
||||
|
||||
// Equals the GNU Octave colormap "bone".
|
||||
class Bone : public ColorMap { |
||||
public: |
||||
Bone() : ColorMap() { |
||||
init(256); |
||||
} |
||||
|
||||
Bone(int n) : ColorMap() { |
||||
init(n); |
||||
} |
||||
|
||||
void init(int n) { |
||||
float r[] = { 0, 0.01388888888888889, 0.02777777777777778, 0.04166666666666666, 0.05555555555555555, 0.06944444444444445, 0.08333333333333333, 0.09722222222222221, 0.1111111111111111, 0.125, 0.1388888888888889, 0.1527777777777778, 0.1666666666666667, 0.1805555555555556, 0.1944444444444444, 0.2083333333333333, 0.2222222222222222, 0.2361111111111111, 0.25, 0.2638888888888889, 0.2777777777777778, 0.2916666666666666, 0.3055555555555555, 0.3194444444444444, 0.3333333333333333, 0.3472222222222222, 0.3611111111111111, 0.375, 0.3888888888888888, 0.4027777777777777, 0.4166666666666666, 0.4305555555555555, 0.4444444444444444, 0.4583333333333333, 0.4722222222222222, 0.4861111111111112, 0.5, 0.5138888888888888, 0.5277777777777778, 0.5416666666666667, 0.5555555555555556, 0.5694444444444444, 0.5833333333333333, 0.5972222222222222, 0.611111111111111, 0.6249999999999999, 0.6388888888888888, 0.6527777777777778, 0.6726190476190474, 0.6944444444444442, 0.7162698412698412, 0.7380952380952381, 0.7599206349206349, 0.7817460317460316, 0.8035714285714286, 0.8253968253968254, 0.8472222222222221, 0.8690476190476188, 0.8908730158730158, 0.9126984126984128, 0.9345238095238095, 0.9563492063492063, 0.978174603174603, 1}; |
||||
float g[] = { 0, 0.01388888888888889, 0.02777777777777778, 0.04166666666666666, 0.05555555555555555, 0.06944444444444445, 0.08333333333333333, 0.09722222222222221, 0.1111111111111111, 0.125, 0.1388888888888889, 0.1527777777777778, 0.1666666666666667, 0.1805555555555556, 0.1944444444444444, 0.2083333333333333, 0.2222222222222222, 0.2361111111111111, 0.25, 0.2638888888888889, 0.2777777777777778, 0.2916666666666666, 0.3055555555555555, 0.3194444444444444, 0.3353174603174602, 0.3544973544973544, 0.3736772486772486, 0.3928571428571428, 0.412037037037037, 0.4312169312169312, 0.4503968253968254, 0.4695767195767195, 0.4887566137566137, 0.5079365079365078, 0.5271164021164021, 0.5462962962962963, 0.5654761904761904, 0.5846560846560845, 0.6038359788359787, 0.623015873015873, 0.6421957671957671, 0.6613756613756612, 0.6805555555555555, 0.6997354497354497, 0.7189153439153438, 0.7380952380952379, 0.7572751322751322, 0.7764550264550264, 0.7916666666666666, 0.8055555555555555, 0.8194444444444444, 0.8333333333333334, 0.8472222222222222, 0.861111111111111, 0.875, 0.8888888888888888, 0.9027777777777777, 0.9166666666666665, 0.9305555555555555, 0.9444444444444444, 0.9583333333333333, 0.9722222222222221, 0.986111111111111, 1}; |
||||
float b[] = { 0, 0.01917989417989418, 0.03835978835978836, 0.05753968253968253, 0.07671957671957672, 0.09589947089947089, 0.1150793650793651, 0.1342592592592592, 0.1534391534391534, 0.1726190476190476, 0.1917989417989418, 0.210978835978836, 0.2301587301587301, 0.2493386243386243, 0.2685185185185185, 0.2876984126984127, 0.3068783068783069, 0.326058201058201, 0.3452380952380952, 0.3644179894179894, 0.3835978835978835, 0.4027777777777777, 0.4219576719576719, 0.4411375661375661, 0.4583333333333333, 0.4722222222222222, 0.4861111111111111, 0.5, 0.5138888888888888, 0.5277777777777777, 0.5416666666666666, 0.5555555555555556, 0.5694444444444444, 0.5833333333333333, 0.5972222222222222, 0.6111111111111112, 0.625, 0.6388888888888888, 0.6527777777777778, 0.6666666666666667, 0.6805555555555556, 0.6944444444444444, 0.7083333333333333, 0.7222222222222222, 0.736111111111111, 0.7499999999999999, 0.7638888888888888, 0.7777777777777778, 0.7916666666666666, 0.8055555555555555, 0.8194444444444444, 0.8333333333333334, 0.8472222222222222, 0.861111111111111, 0.875, 0.8888888888888888, 0.9027777777777777, 0.9166666666666665, 0.9305555555555555, 0.9444444444444444, 0.9583333333333333, 0.9722222222222221, 0.986111111111111, 1}; |
||||
Mat X = linspace(0,1,64); |
||||
this->_lut = ColorMap::linear_colormap(X, |
||||
Mat(64,1, CV_32FC1, r).clone(), // red
|
||||
Mat(64,1, CV_32FC1, g).clone(), // green
|
||||
Mat(64,1, CV_32FC1, b).clone(), // blue
|
||||
n); // number of sample points
|
||||
} |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
// Equals the GNU Octave colormap "jet".
|
||||
class Jet : public ColorMap { |
||||
|
||||
public: |
||||
Jet() { |
||||
init(256); |
||||
} |
||||
Jet(int n) : ColorMap() { |
||||
init(n); |
||||
} |
||||
|
||||
void init(int n) { |
||||
// breakpoints
|
||||
Mat X = linspace(0,1,256); |
||||
// define the basemap
|
||||
float r[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.00588235294117645,0.02156862745098032,0.03725490196078418,0.05294117647058827,0.06862745098039214,0.084313725490196,0.1000000000000001,0.115686274509804,0.1313725490196078,0.1470588235294117,0.1627450980392156,0.1784313725490196,0.1941176470588235,0.2098039215686274,0.2254901960784315,0.2411764705882353,0.2568627450980392,0.2725490196078431,0.2882352941176469,0.303921568627451,0.3196078431372549,0.3352941176470587,0.3509803921568628,0.3666666666666667,0.3823529411764706,0.3980392156862744,0.4137254901960783,0.4294117647058824,0.4450980392156862,0.4607843137254901,0.4764705882352942,0.4921568627450981,0.5078431372549019,0.5235294117647058,0.5392156862745097,0.5549019607843135,0.5705882352941174,0.5862745098039217,0.6019607843137256,0.6176470588235294,0.6333333333333333,0.6490196078431372,0.664705882352941,0.6803921568627449,0.6960784313725492,0.7117647058823531,0.7274509803921569,0.7431372549019608,0.7588235294117647,0.7745098039215685,0.7901960784313724,0.8058823529411763,0.8215686274509801,0.8372549019607844,0.8529411764705883,0.8686274509803922,0.884313725490196,0.8999999999999999,0.9156862745098038,0.9313725490196076,0.947058823529412,0.9627450980392158,0.9784313725490197,0.9941176470588236,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.9862745098039216,0.9705882352941178,0.9549019607843139,0.93921568627451,0.9235294117647062,0.9078431372549018,0.892156862745098,0.8764705882352941,0.8607843137254902,0.8450980392156864,0.8294117647058825,0.8137254901960786,0.7980392156862743,0.7823529411764705,0.7666666666666666,0.7509803921568627,0.7352941176470589,0.719607843137255,0.7039215686274511,0.6882352941176473,0.6725490196078434,0.6568627450980391,0.6411764705882352,0.6254901960784314,0.6098039215686275,0.5941176470588236,0.5784313725490198,0.5627450980392159,0.5470588235294116,0.5313725490196077,0.5156862745098039,0.5}; |
||||
float g[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.001960784313725483,0.01764705882352935,0.03333333333333333,0.0490196078431373,0.06470588235294117,0.08039215686274503,0.09607843137254901,0.111764705882353,0.1274509803921569,0.1431372549019607,0.1588235294117647,0.1745098039215687,0.1901960784313725,0.2058823529411764,0.2215686274509804,0.2372549019607844,0.2529411764705882,0.2686274509803921,0.2843137254901961,0.3,0.3156862745098039,0.3313725490196078,0.3470588235294118,0.3627450980392157,0.3784313725490196,0.3941176470588235,0.4098039215686274,0.4254901960784314,0.4411764705882353,0.4568627450980391,0.4725490196078431,0.4882352941176471,0.503921568627451,0.5196078431372548,0.5352941176470587,0.5509803921568628,0.5666666666666667,0.5823529411764705,0.5980392156862746,0.6137254901960785,0.6294117647058823,0.6450980392156862,0.6607843137254901,0.6764705882352942,0.692156862745098,0.7078431372549019,0.723529411764706,0.7392156862745098,0.7549019607843137,0.7705882352941176,0.7862745098039214,0.8019607843137255,0.8176470588235294,0.8333333333333333,0.8490196078431373,0.8647058823529412,0.8803921568627451,0.8960784313725489,0.9117647058823528,0.9274509803921569,0.9431372549019608,0.9588235294117646,0.9745098039215687,0.9901960784313726,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.9901960784313726,0.9745098039215687,0.9588235294117649,0.943137254901961,0.9274509803921571,0.9117647058823528,0.8960784313725489,0.8803921568627451,0.8647058823529412,0.8490196078431373,0.8333333333333335,0.8176470588235296,0.8019607843137253,0.7862745098039214,0.7705882352941176,0.7549019607843137,0.7392156862745098,0.723529411764706,0.7078431372549021,0.6921568627450982,0.6764705882352944,0.6607843137254901,0.6450980392156862,0.6294117647058823,0.6137254901960785,0.5980392156862746,0.5823529411764707,0.5666666666666669,0.5509803921568626,0.5352941176470587,0.5196078431372548,0.503921568627451,0.4882352941176471,0.4725490196078432,0.4568627450980394,0.4411764705882355,0.4254901960784316,0.4098039215686273,0.3941176470588235,0.3784313725490196,0.3627450980392157,0.3470588235294119,0.331372549019608,0.3156862745098041,0.2999999999999998,0.284313725490196,0.2686274509803921,0.2529411764705882,0.2372549019607844,0.2215686274509805,0.2058823529411766,0.1901960784313728,0.1745098039215689,0.1588235294117646,0.1431372549019607,0.1274509803921569,0.111764705882353,0.09607843137254912,0.08039215686274526,0.06470588235294139,0.04901960784313708,0.03333333333333321,0.01764705882352935,0.001960784313725483,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; |
||||
float b[] = {0.5,0.5156862745098039,0.5313725490196078,0.5470588235294118,0.5627450980392157,0.5784313725490196,0.5941176470588235,0.6098039215686275,0.6254901960784314,0.6411764705882352,0.6568627450980392,0.6725490196078432,0.6882352941176471,0.7039215686274509,0.7196078431372549,0.7352941176470589,0.7509803921568627,0.7666666666666666,0.7823529411764706,0.7980392156862746,0.8137254901960784,0.8294117647058823,0.8450980392156863,0.8607843137254902,0.8764705882352941,0.892156862745098,0.907843137254902,0.9235294117647059,0.9392156862745098,0.9549019607843137,0.9705882352941176,0.9862745098039216,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.9941176470588236,0.9784313725490197,0.9627450980392158,0.9470588235294117,0.9313725490196079,0.915686274509804,0.8999999999999999,0.884313725490196,0.8686274509803922,0.8529411764705883,0.8372549019607844,0.8215686274509804,0.8058823529411765,0.7901960784313726,0.7745098039215685,0.7588235294117647,0.7431372549019608,0.7274509803921569,0.7117647058823531,0.696078431372549,0.6803921568627451,0.6647058823529413,0.6490196078431372,0.6333333333333333,0.6176470588235294,0.6019607843137256,0.5862745098039217,0.5705882352941176,0.5549019607843138,0.5392156862745099,0.5235294117647058,0.5078431372549019,0.4921568627450981,0.4764705882352942,0.4607843137254903,0.4450980392156865,0.4294117647058826,0.4137254901960783,0.3980392156862744,0.3823529411764706,0.3666666666666667,0.3509803921568628,0.335294117647059,0.3196078431372551,0.3039215686274508,0.2882352941176469,0.2725490196078431,0.2568627450980392,0.2411764705882353,0.2254901960784315,0.2098039215686276,0.1941176470588237,0.1784313725490199,0.1627450980392156,0.1470588235294117,0.1313725490196078,0.115686274509804,0.1000000000000001,0.08431372549019622,0.06862745098039236,0.05294117647058805,0.03725490196078418,0.02156862745098032,0.00588235294117645,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; |
||||
// now build lookup table
|
||||
this->_lut = ColorMap::linear_colormap(X, |
||||
Mat(256,1, CV_32FC1, r).clone(), // red
|
||||
Mat(256,1, CV_32FC1, g).clone(), // green
|
||||
Mat(256,1, CV_32FC1, b).clone(), // blue
|
||||
n); |
||||
} |
||||
}; |
||||
|
||||
// Equals the GNU Octave colormap "winter".
|
||||
class Winter : public ColorMap { |
||||
public: |
||||
Winter() : ColorMap() { |
||||
init(256); |
||||
} |
||||
|
||||
Winter(int n) : ColorMap() { |
||||
init(n); |
||||
} |
||||
|
||||
void init(int n) { |
||||
float r[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; |
||||
float g[] = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}; |
||||
float b[] = {1.0, 0.95, 0.9, 0.85, 0.8, 0.75, 0.7, 0.65, 0.6, 0.55, 0.5}; |
||||
Mat X = linspace(0,1,11); |
||||
this->_lut = ColorMap::linear_colormap(X, |
||||
Mat(11,1, CV_32FC1, r).clone(), // red
|
||||
Mat(11,1, CV_32FC1, g).clone(), // green
|
||||
Mat(11,1, CV_32FC1, b).clone(), // blue
|
||||
n); // number of sample points
|
||||
} |
||||
}; |
||||
|
||||
// Equals the GNU Octave colormap "rainbow".
|
||||
class Rainbow : public ColorMap { |
||||
public: |
||||
Rainbow() : ColorMap() { |
||||
init(256); |
||||
} |
||||
|
||||
Rainbow(int n) : ColorMap() { |
||||
init(n); |
||||
} |
||||
|
||||
void init(int n) { |
||||
float r[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9365079365079367, 0.8571428571428572, 0.7777777777777777, 0.6984126984126986, 0.6190476190476191, 0.53968253968254, 0.4603174603174605, 0.3809523809523814, 0.3015873015873018, 0.2222222222222223, 0.1428571428571432, 0.06349206349206415, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.03174603174603208, 0.08465608465608465, 0.1375661375661377, 0.1904761904761907, 0.2433862433862437, 0.2962962962962963, 0.3492063492063493, 0.4021164021164023, 0.4550264550264553, 0.5079365079365079, 0.5608465608465609, 0.6137566137566139, 0.666666666666667}; |
||||
float g[] = { 0, 0.03968253968253968, 0.07936507936507936, 0.119047619047619, 0.1587301587301587, 0.1984126984126984, 0.2380952380952381, 0.2777777777777778, 0.3174603174603174, 0.3571428571428571, 0.3968253968253968, 0.4365079365079365, 0.4761904761904762, 0.5158730158730158, 0.5555555555555556, 0.5952380952380952, 0.6349206349206349, 0.6746031746031745, 0.7142857142857142, 0.753968253968254, 0.7936507936507936, 0.8333333333333333, 0.873015873015873, 0.9126984126984127, 0.9523809523809523, 0.992063492063492, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9841269841269842, 0.9047619047619047, 0.8253968253968256, 0.7460317460317465, 0.666666666666667, 0.587301587301587, 0.5079365079365079, 0.4285714285714288, 0.3492063492063493, 0.2698412698412698, 0.1904761904761907, 0.1111111111111116, 0.03174603174603208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
||||
float b[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.01587301587301582, 0.09523809523809534, 0.1746031746031744, 0.2539682539682535, 0.333333333333333, 0.412698412698413, 0.4920634920634921, 0.5714285714285712, 0.6507936507936507, 0.7301587301587302, 0.8095238095238093, 0.8888888888888884, 0.9682539682539679, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; |
||||
Mat X = linspace(0,1,64); |
||||
this->_lut = ColorMap::linear_colormap(X, |
||||
Mat(64,1, CV_32FC1, r).clone(), // red
|
||||
Mat(64,1, CV_32FC1, g).clone(), // green
|
||||
Mat(64,1, CV_32FC1, b).clone(), // blue
|
||||
n); // number of sample points
|
||||
} |
||||
}; |
||||
|
||||
// Equals the GNU Octave colormap "ocean".
|
||||
class Ocean : public ColorMap { |
||||
public: |
||||
Ocean() : ColorMap() { |
||||
init(256); |
||||
} |
||||
|
||||
Ocean(int n) : ColorMap() { |
||||
init(n); |
||||
} |
||||
|
||||
void init(int n) { |
||||
float r[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.04761904761904762, 0.09523809523809523, 0.1428571428571428, 0.1904761904761905, 0.2380952380952381, 0.2857142857142857, 0.3333333333333333, 0.3809523809523809, 0.4285714285714285, 0.4761904761904762, 0.5238095238095238, 0.5714285714285714, 0.6190476190476191, 0.6666666666666666, 0.7142857142857143, 0.7619047619047619, 0.8095238095238095, 0.8571428571428571, 0.9047619047619048, 0.9523809523809523, 1}; |
||||
float g[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.02380952380952381, 0.04761904761904762, 0.07142857142857142, 0.09523809523809523, 0.119047619047619, 0.1428571428571428, 0.1666666666666667, 0.1904761904761905, 0.2142857142857143, 0.2380952380952381, 0.2619047619047619, 0.2857142857142857, 0.3095238095238095, 0.3333333333333333, 0.3571428571428572, 0.3809523809523809, 0.4047619047619048, 0.4285714285714285, 0.4523809523809524, 0.4761904761904762, 0.5, 0.5238095238095238, 0.5476190476190477, 0.5714285714285714, 0.5952380952380952, 0.6190476190476191, 0.6428571428571429, 0.6666666666666666, 0.6904761904761905, 0.7142857142857143, 0.7380952380952381, 0.7619047619047619, 0.7857142857142857, 0.8095238095238095, 0.8333333333333334, 0.8571428571428571, 0.8809523809523809, 0.9047619047619048, 0.9285714285714286, 0.9523809523809523, 0.9761904761904762, 1}; |
||||
float b[] = { 0, 0.01587301587301587, 0.03174603174603174, 0.04761904761904762, 0.06349206349206349, 0.07936507936507936, 0.09523809523809523, 0.1111111111111111, 0.126984126984127, 0.1428571428571428, 0.1587301587301587, 0.1746031746031746, 0.1904761904761905, 0.2063492063492063, 0.2222222222222222, 0.2380952380952381, 0.253968253968254, 0.2698412698412698, 0.2857142857142857, 0.3015873015873016, 0.3174603174603174, 0.3333333333333333, 0.3492063492063492, 0.3650793650793651, 0.3809523809523809, 0.3968253968253968, 0.4126984126984127, 0.4285714285714285, 0.4444444444444444, 0.4603174603174603, 0.4761904761904762, 0.492063492063492, 0.5079365079365079, 0.5238095238095238, 0.5396825396825397, 0.5555555555555556, 0.5714285714285714, 0.5873015873015873, 0.6031746031746031, 0.6190476190476191, 0.6349206349206349, 0.6507936507936508, 0.6666666666666666, 0.6825396825396826, 0.6984126984126984, 0.7142857142857143, 0.7301587301587301, 0.746031746031746, 0.7619047619047619, 0.7777777777777778, 0.7936507936507936, 0.8095238095238095, 0.8253968253968254, 0.8412698412698413, 0.8571428571428571, 0.873015873015873, 0.8888888888888888, 0.9047619047619048, 0.9206349206349206, 0.9365079365079365, 0.9523809523809523, 0.9682539682539683, 0.9841269841269841, 1}; |
||||
Mat X = linspace(0,1,64); |
||||
this->_lut = ColorMap::linear_colormap(X, |
||||
Mat(64,1, CV_32FC1, r).clone(), // red
|
||||
Mat(64,1, CV_32FC1, g).clone(), // green
|
||||
Mat(64,1, CV_32FC1, b).clone(), // blue
|
||||
n); // number of sample points
|
||||
} |
||||
}; |
||||
|
||||
// Equals the GNU Octave colormap "summer".
|
||||
class Summer : public ColorMap { |
||||
public: |
||||
Summer() : ColorMap() { |
||||
init(256); |
||||
} |
||||
|
||||
Summer(int n) : ColorMap() { |
||||
init(n); |
||||
} |
||||
|
||||
void init(int n) { |
||||
float r[] = { 0, 0.01587301587301587, 0.03174603174603174, 0.04761904761904762, 0.06349206349206349, 0.07936507936507936, 0.09523809523809523, 0.1111111111111111, 0.126984126984127, 0.1428571428571428, 0.1587301587301587, 0.1746031746031746, 0.1904761904761905, 0.2063492063492063, 0.2222222222222222, 0.2380952380952381, 0.253968253968254, 0.2698412698412698, 0.2857142857142857, 0.3015873015873016, 0.3174603174603174, 0.3333333333333333, 0.3492063492063492, 0.3650793650793651, 0.3809523809523809, 0.3968253968253968, 0.4126984126984127, 0.4285714285714285, 0.4444444444444444, 0.4603174603174603, 0.4761904761904762, 0.492063492063492, 0.5079365079365079, 0.5238095238095238, 0.5396825396825397, 0.5555555555555556, 0.5714285714285714, 0.5873015873015873, 0.6031746031746031, 0.6190476190476191, 0.6349206349206349, 0.6507936507936508, 0.6666666666666666, 0.6825396825396826, 0.6984126984126984, 0.7142857142857143, 0.7301587301587301, 0.746031746031746, 0.7619047619047619, 0.7777777777777778, 0.7936507936507936, 0.8095238095238095, 0.8253968253968254, 0.8412698412698413, 0.8571428571428571, 0.873015873015873, 0.8888888888888888, 0.9047619047619048, 0.9206349206349206, 0.9365079365079365, 0.9523809523809523, 0.9682539682539683, 0.9841269841269841, 1}; |
||||
float g[] = { 0.5, 0.5079365079365079, 0.5158730158730158, 0.5238095238095238, 0.5317460317460317, 0.5396825396825397, 0.5476190476190477, 0.5555555555555556, 0.5634920634920635, 0.5714285714285714, 0.5793650793650793, 0.5873015873015873, 0.5952380952380952, 0.6031746031746031, 0.6111111111111112, 0.6190476190476191, 0.626984126984127, 0.6349206349206349, 0.6428571428571428, 0.6507936507936508, 0.6587301587301587, 0.6666666666666666, 0.6746031746031746, 0.6825396825396826, 0.6904761904761905, 0.6984126984126984, 0.7063492063492063, 0.7142857142857143, 0.7222222222222222, 0.7301587301587301, 0.7380952380952381, 0.746031746031746, 0.753968253968254, 0.7619047619047619, 0.7698412698412698, 0.7777777777777778, 0.7857142857142857, 0.7936507936507937, 0.8015873015873016, 0.8095238095238095, 0.8174603174603174, 0.8253968253968254, 0.8333333333333333, 0.8412698412698413, 0.8492063492063492, 0.8571428571428572, 0.8650793650793651, 0.873015873015873, 0.8809523809523809, 0.8888888888888888, 0.8968253968253967, 0.9047619047619048, 0.9126984126984127, 0.9206349206349207, 0.9285714285714286, 0.9365079365079365, 0.9444444444444444, 0.9523809523809523, 0.9603174603174602, 0.9682539682539683, 0.9761904761904762, 0.9841269841269842, 0.9920634920634921, 1}; |
||||
float b[] = { 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4}; |
||||
Mat X = linspace(0,1,64); |
||||
this->_lut = ColorMap::linear_colormap(X, |
||||
Mat(64,1, CV_32FC1, r).clone(), // red
|
||||
Mat(64,1, CV_32FC1, g).clone(), // green
|
||||
Mat(64,1, CV_32FC1, b).clone(), // blue
|
||||
n); // number of sample points
|
||||
} |
||||
}; |
||||
|
||||
// Equals the GNU Octave colormap "spring".
|
||||
class Spring : public ColorMap { |
||||
public: |
||||
Spring() : ColorMap() { |
||||
init(256); |
||||
} |
||||
|
||||
Spring(int n) : ColorMap() { |
||||
init(n); |
||||
} |
||||
|
||||
void init(int n) { |
||||
float r[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; |
||||
float g[] = { 0, 0.01587301587301587, 0.03174603174603174, 0.04761904761904762, 0.06349206349206349, 0.07936507936507936, 0.09523809523809523, 0.1111111111111111, 0.126984126984127, 0.1428571428571428, 0.1587301587301587, 0.1746031746031746, 0.1904761904761905, 0.2063492063492063, 0.2222222222222222, 0.2380952380952381, 0.253968253968254, 0.2698412698412698, 0.2857142857142857, 0.3015873015873016, 0.3174603174603174, 0.3333333333333333, 0.3492063492063492, 0.3650793650793651, 0.3809523809523809, 0.3968253968253968, 0.4126984126984127, 0.4285714285714285, 0.4444444444444444, 0.4603174603174603, 0.4761904761904762, 0.492063492063492, 0.5079365079365079, 0.5238095238095238, 0.5396825396825397, 0.5555555555555556, 0.5714285714285714, 0.5873015873015873, 0.6031746031746031, 0.6190476190476191, 0.6349206349206349, 0.6507936507936508, 0.6666666666666666, 0.6825396825396826, 0.6984126984126984, 0.7142857142857143, 0.7301587301587301, 0.746031746031746, 0.7619047619047619, 0.7777777777777778, 0.7936507936507936, 0.8095238095238095, 0.8253968253968254, 0.8412698412698413, 0.8571428571428571, 0.873015873015873, 0.8888888888888888, 0.9047619047619048, 0.9206349206349206, 0.9365079365079365, 0.9523809523809523, 0.9682539682539683, 0.9841269841269841, 1}; |
||||
float b[] = { 1, 0.9841269841269842, 0.9682539682539683, 0.9523809523809523, 0.9365079365079365, 0.9206349206349207, 0.9047619047619048, 0.8888888888888888, 0.873015873015873, 0.8571428571428572, 0.8412698412698413, 0.8253968253968254, 0.8095238095238095, 0.7936507936507937, 0.7777777777777778, 0.7619047619047619, 0.746031746031746, 0.7301587301587302, 0.7142857142857143, 0.6984126984126984, 0.6825396825396826, 0.6666666666666667, 0.6507936507936508, 0.6349206349206349, 0.6190476190476191, 0.6031746031746033, 0.5873015873015873, 0.5714285714285714, 0.5555555555555556, 0.5396825396825398, 0.5238095238095238, 0.5079365079365079, 0.4920634920634921, 0.4761904761904762, 0.4603174603174603, 0.4444444444444444, 0.4285714285714286, 0.4126984126984127, 0.3968253968253969, 0.3809523809523809, 0.3650793650793651, 0.3492063492063492, 0.3333333333333334, 0.3174603174603174, 0.3015873015873016, 0.2857142857142857, 0.2698412698412699, 0.253968253968254, 0.2380952380952381, 0.2222222222222222, 0.2063492063492064, 0.1904761904761905, 0.1746031746031746, 0.1587301587301587, 0.1428571428571429, 0.126984126984127, 0.1111111111111112, 0.09523809523809523, 0.07936507936507942, 0.06349206349206349, 0.04761904761904767, 0.03174603174603174, 0.01587301587301593, 0}; |
||||
Mat X = linspace(0,1,64); |
||||
this->_lut = ColorMap::linear_colormap(X, |
||||
Mat(64,1, CV_32FC1, r).clone(), // red
|
||||
Mat(64,1, CV_32FC1, g).clone(), // green
|
||||
Mat(64,1, CV_32FC1, b).clone(), // blue
|
||||
n); // number of sample points
|
||||
} |
||||
}; |
||||
|
||||
// Equals the GNU Octave colormap "cool".
|
||||
class Cool : public ColorMap { |
||||
public: |
||||
Cool() : ColorMap() { |
||||
init(256); |
||||
} |
||||
|
||||
Cool(int n) : ColorMap() { |
||||
init(n); |
||||
} |
||||
|
||||
void init(int n) { |
||||
float r[] = { 0, 0.01587301587301587, 0.03174603174603174, 0.04761904761904762, 0.06349206349206349, 0.07936507936507936, 0.09523809523809523, 0.1111111111111111, 0.126984126984127, 0.1428571428571428, 0.1587301587301587, 0.1746031746031746, 0.1904761904761905, 0.2063492063492063, 0.2222222222222222, 0.2380952380952381, 0.253968253968254, 0.2698412698412698, 0.2857142857142857, 0.3015873015873016, 0.3174603174603174, 0.3333333333333333, 0.3492063492063492, 0.3650793650793651, 0.3809523809523809, 0.3968253968253968, 0.4126984126984127, 0.4285714285714285, 0.4444444444444444, 0.4603174603174603, 0.4761904761904762, 0.492063492063492, 0.5079365079365079, 0.5238095238095238, 0.5396825396825397, 0.5555555555555556, 0.5714285714285714, 0.5873015873015873, 0.6031746031746031, 0.6190476190476191, 0.6349206349206349, 0.6507936507936508, 0.6666666666666666, 0.6825396825396826, 0.6984126984126984, 0.7142857142857143, 0.7301587301587301, 0.746031746031746, 0.7619047619047619, 0.7777777777777778, 0.7936507936507936, 0.8095238095238095, 0.8253968253968254, 0.8412698412698413, 0.8571428571428571, 0.873015873015873, 0.8888888888888888, 0.9047619047619048, 0.9206349206349206, 0.9365079365079365, 0.9523809523809523, 0.9682539682539683, 0.9841269841269841, 1}; |
||||
float g[] = { 1, 0.9841269841269842, 0.9682539682539683, 0.9523809523809523, 0.9365079365079365, 0.9206349206349207, 0.9047619047619048, 0.8888888888888888, 0.873015873015873, 0.8571428571428572, 0.8412698412698413, 0.8253968253968254, 0.8095238095238095, 0.7936507936507937, 0.7777777777777778, 0.7619047619047619, 0.746031746031746, 0.7301587301587302, 0.7142857142857143, 0.6984126984126984, 0.6825396825396826, 0.6666666666666667, 0.6507936507936508, 0.6349206349206349, 0.6190476190476191, 0.6031746031746033, 0.5873015873015873, 0.5714285714285714, 0.5555555555555556, 0.5396825396825398, 0.5238095238095238, 0.5079365079365079, 0.4920634920634921, 0.4761904761904762, 0.4603174603174603, 0.4444444444444444, 0.4285714285714286, 0.4126984126984127, 0.3968253968253969, 0.3809523809523809, 0.3650793650793651, 0.3492063492063492, 0.3333333333333334, 0.3174603174603174, 0.3015873015873016, 0.2857142857142857, 0.2698412698412699, 0.253968253968254, 0.2380952380952381, 0.2222222222222222, 0.2063492063492064, 0.1904761904761905, 0.1746031746031746, 0.1587301587301587, 0.1428571428571429, 0.126984126984127, 0.1111111111111112, 0.09523809523809523, 0.07936507936507942, 0.06349206349206349, 0.04761904761904767, 0.03174603174603174, 0.01587301587301593, 0}; |
||||
float b[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; |
||||
Mat X = linspace(0,1,64); |
||||
this->_lut = ColorMap::linear_colormap(X, |
||||
Mat(64,1, CV_32FC1, r).clone(), // red
|
||||
Mat(64,1, CV_32FC1, g).clone(), // green
|
||||
Mat(64,1, CV_32FC1, b).clone(), // blue
|
||||
n); // number of sample points
|
||||
} |
||||
}; |
||||
|
||||
// Equals the GNU Octave colormap "hsv".
|
||||
class HSV : public ColorMap { |
||||
public: |
||||
HSV() : ColorMap() { |
||||
init(256); |
||||
} |
||||
|
||||
HSV(int n) : ColorMap() { |
||||
init(n); |
||||
} |
||||
|
||||
void init(int n) { |
||||
float r[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9523809523809526, 0.8571428571428568, 0.7619047619047614, 0.6666666666666665, 0.5714285714285716, 0.4761904761904763, 0.3809523809523805, 0.2857142857142856, 0.1904761904761907, 0.0952380952380949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.09523809523809557, 0.1904761904761905, 0.2857142857142854, 0.3809523809523809, 0.4761904761904765, 0.5714285714285714, 0.6666666666666663, 0.7619047619047619, 0.8571428571428574, 0.9523809523809523, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; |
||||
float g[] = { 0, 0.09523809523809523, 0.1904761904761905, 0.2857142857142857, 0.3809523809523809, 0.4761904761904762, 0.5714285714285714, 0.6666666666666666, 0.7619047619047619, 0.8571428571428571, 0.9523809523809523, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9523809523809526, 0.8571428571428577, 0.7619047619047619, 0.6666666666666665, 0.5714285714285716, 0.4761904761904767, 0.3809523809523814, 0.2857142857142856, 0.1904761904761907, 0.09523809523809579, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
||||
float b[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.09523809523809523, 0.1904761904761905, 0.2857142857142857, 0.3809523809523809, 0.4761904761904762, 0.5714285714285714, 0.6666666666666666, 0.7619047619047619, 0.8571428571428571, 0.9523809523809523, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9523809523809526, 0.8571428571428577, 0.7619047619047614, 0.6666666666666665, 0.5714285714285716, 0.4761904761904767, 0.3809523809523805, 0.2857142857142856, 0.1904761904761907, 0.09523809523809579, 0}; |
||||
Mat X = linspace(0,1,64); |
||||
this->_lut = ColorMap::linear_colormap(X, |
||||
Mat(64,1, CV_32FC1, r).clone(), // red
|
||||
Mat(64,1, CV_32FC1, g).clone(), // green
|
||||
Mat(64,1, CV_32FC1, b).clone(), // blue
|
||||
n); // number of sample points
|
||||
} |
||||
}; |
||||
|
||||
// Equals the GNU Octave colormap "pink".
|
||||
class Pink : public ColorMap { |
||||
public: |
||||
Pink() : ColorMap() { |
||||
init(256); |
||||
} |
||||
|
||||
Pink(int n) : ColorMap() { |
||||
init(n); |
||||
} |
||||
|
||||
void init(int n) { |
||||
float r[] = { 0, 0.1571348402636772, 0.2222222222222222, 0.2721655269759087, 0.3142696805273544, 0.3513641844631533, 0.3849001794597505, 0.415739709641549, 0.4444444444444444, 0.4714045207910317, 0.4969039949999532, 0.5211573066470477, 0.5443310539518174, 0.5665577237325317, 0.5879447357921312, 0.6085806194501846, 0.6285393610547089, 0.6478835438717, 0.6666666666666666, 0.6849348892187751, 0.7027283689263065, 0.7200822998230956, 0.7370277311900888, 0.753592220347252, 0.7663560447348133, 0.7732293307186413, 0.7800420555749596, 0.7867957924694432, 0.7934920476158722, 0.8001322641986387, 0.8067178260046388, 0.8132500607904444, 0.8197302434079591, 0.8261595987094034, 0.8325393042503717, 0.8388704928078611, 0.8451542547285166, 0.8513916401208816, 0.8575836609041332, 0.8637312927246217, 0.8698354767504924, 0.8758971213537393, 0.8819171036881968, 0.8878962711712378, 0.8938354428762595, 0.8997354108424372, 0.9055969413076769, 0.9114207758701963, 0.9172076325837248, 0.9229582069908971, 0.9286731730990523, 0.9343531843023135, 0.9399988742535192, 0.9456108576893002, 0.9511897312113418, 0.9567360740266436, 0.9622504486493763, 0.9677334015667416, 0.9731854638710686, 0.9786071518602129, 0.9839989676081821, 0.9893613995077727, 0.9946949227868761, 1}; |
||||
float g[] = { 0, 0.1028688999747279, 0.1454785934906616, 0.1781741612749496, 0.2057377999494559, 0.2300218531141181, 0.2519763153394848, 0.2721655269759087, 0.2909571869813232, 0.3086066999241838, 0.3253000243161777, 0.3411775438127727, 0.3563483225498992, 0.3708990935094579, 0.3849001794597505, 0.3984095364447979, 0.4114755998989117, 0.4241393401869012, 0.4364357804719847, 0.4483951394230328, 0.4600437062282361, 0.4714045207910317, 0.4824979096371639, 0.4933419132673033, 0.5091750772173156, 0.5328701692569688, 0.5555555555555556, 0.5773502691896257, 0.5983516452371671, 0.6186404847588913, 0.6382847385042254, 0.6573421981221795, 0.6758625033664688, 0.6938886664887108, 0.7114582486036499, 0.7286042804780002, 0.7453559924999299, 0.7617394000445604, 0.7777777777777778, 0.7934920476158723, 0.8089010988089465, 0.8240220541217402, 0.8388704928078611, 0.8534606386520677, 0.8678055195451838, 0.8819171036881968, 0.8958064164776166, 0.9094836413191612, 0.9172076325837248, 0.9229582069908971, 0.9286731730990523, 0.9343531843023135, 0.9399988742535192, 0.9456108576893002, 0.9511897312113418, 0.9567360740266436, 0.9622504486493763, 0.9677334015667416, 0.9731854638710686, 0.9786071518602129, 0.9839989676081821, 0.9893613995077727, 0.9946949227868761, 1}; |
||||
float b[] = { 0, 0.1028688999747279, 0.1454785934906616, 0.1781741612749496, 0.2057377999494559, 0.2300218531141181, 0.2519763153394848, 0.2721655269759087, 0.2909571869813232, 0.3086066999241838, 0.3253000243161777, 0.3411775438127727, 0.3563483225498992, 0.3708990935094579, 0.3849001794597505, 0.3984095364447979, 0.4114755998989117, 0.4241393401869012, 0.4364357804719847, 0.4483951394230328, 0.4600437062282361, 0.4714045207910317, 0.4824979096371639, 0.4933419132673033, 0.5039526306789697, 0.5143444998736397, 0.5245305283129621, 0.5345224838248488, 0.5443310539518174, 0.5539659798925444, 0.563436169819011, 0.5727497953228163, 0.5819143739626463, 0.5909368402852788, 0.5998236072282915, 0.6085806194501846, 0.6172133998483676, 0.6257270902992705, 0.6341264874742278, 0.642416074439621, 0.6506000486323554, 0.6586823467062358, 0.6666666666666666, 0.6745564876468501, 0.6823550876255453, 0.6900655593423541, 0.6976908246297114, 0.7052336473499384, 0.7237468644557459, 0.7453559924999298, 0.7663560447348133, 0.7867957924694432, 0.8067178260046388, 0.8261595987094034, 0.8451542547285166, 0.8637312927246217, 0.8819171036881968, 0.8997354108424372, 0.9172076325837248, 0.9343531843023135, 0.9511897312113418, 0.9677334015667416, 0.9839989676081821, 1}; |
||||
Mat X = linspace(0,1,64); |
||||
this->_lut = ColorMap::linear_colormap(X, |
||||
Mat(64,1, CV_32FC1, r).clone(), // red
|
||||
Mat(64,1, CV_32FC1, g).clone(), // green
|
||||
Mat(64,1, CV_32FC1, b).clone(), // blue
|
||||
n); // number of sample points
|
||||
} |
||||
}; |
||||
|
||||
// Equals the GNU Octave colormap "hot".
|
||||
class Hot : public ColorMap { |
||||
public: |
||||
Hot() : ColorMap() { |
||||
init(256); |
||||
} |
||||
|
||||
Hot(int n) : ColorMap() { |
||||
init(n); |
||||
} |
||||
|
||||
void init(int n) { |
||||
float r[] = { 0, 0.03968253968253968, 0.07936507936507936, 0.119047619047619, 0.1587301587301587, 0.1984126984126984, 0.2380952380952381, 0.2777777777777778, 0.3174603174603174, 0.3571428571428571, 0.3968253968253968, 0.4365079365079365, 0.4761904761904762, 0.5158730158730158, 0.5555555555555556, 0.5952380952380952, 0.6349206349206349, 0.6746031746031745, 0.7142857142857142, 0.753968253968254, 0.7936507936507936, 0.8333333333333333, 0.873015873015873, 0.9126984126984127, 0.9523809523809523, 0.992063492063492, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; |
||||
float g[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.03174603174603163, 0.0714285714285714, 0.1111111111111112, 0.1507936507936507, 0.1904761904761905, 0.23015873015873, 0.2698412698412698, 0.3095238095238093, 0.3492063492063491, 0.3888888888888888, 0.4285714285714284, 0.4682539682539679, 0.5079365079365079, 0.5476190476190477, 0.5873015873015872, 0.6269841269841268, 0.6666666666666665, 0.7063492063492065, 0.746031746031746, 0.7857142857142856, 0.8253968253968254, 0.8650793650793651, 0.9047619047619047, 0.9444444444444442, 0.984126984126984, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; |
||||
float b[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.04761904761904745, 0.1269841269841265, 0.2063492063492056, 0.2857142857142856, 0.3650793650793656, 0.4444444444444446, 0.5238095238095237, 0.6031746031746028, 0.6825396825396828, 0.7619047619047619, 0.8412698412698409, 0.92063492063492, 1}; |
||||
Mat X = linspace(0,1,64); |
||||
this->_lut = ColorMap::linear_colormap(X, |
||||
Mat(64,1, CV_32FC1, r).clone(), // red
|
||||
Mat(64,1, CV_32FC1, g).clone(), // green
|
||||
Mat(64,1, CV_32FC1, b).clone(), // blue
|
||||
n); // number of sample points
|
||||
} |
||||
}; |
||||
|
||||
void ColorMap::operator()(InputArray _src, OutputArray _dst) const |
||||
{ |
||||
if(_lut.total() != 256) |
||||
CV_Error(Error::StsAssert, "cv::LUT only supports tables of size 256."); |
||||
Mat src = _src.getMat(); |
||||
// Return original matrix if wrong type is given (is fail loud better here?)
|
||||
if(src.type() != CV_8UC1 && src.type() != CV_8UC3) |
||||
{ |
||||
src.copyTo(_dst); |
||||
return; |
||||
} |
||||
// Turn into a BGR matrix into its grayscale representation.
|
||||
if(src.type() == CV_8UC3) |
||||
cvtColor(src.clone(), src, COLOR_BGR2GRAY); |
||||
cvtColor(src.clone(), src, COLOR_GRAY2BGR); |
||||
// Apply the ColorMap.
|
||||
LUT(src, _lut, _dst); |
||||
} |
||||
|
||||
Mat ColorMap::linear_colormap(InputArray X, |
||||
InputArray r, InputArray g, InputArray b, |
||||
InputArray xi) { |
||||
Mat lut, lut8; |
||||
Mat planes[] = { |
||||
interp1(X, b, xi), |
||||
interp1(X, g, xi), |
||||
interp1(X, r, xi)}; |
||||
merge(planes, 3, lut); |
||||
lut.convertTo(lut8, CV_8U, 255.); |
||||
return lut8; |
||||
} |
||||
|
||||
} |
||||
|
||||
void applyColorMap(InputArray src, OutputArray dst, int colormap) |
||||
{ |
||||
colormap::ColorMap* cm = |
||||
colormap == COLORMAP_AUTUMN ? (colormap::ColorMap*)(new colormap::Autumn) : |
||||
colormap == COLORMAP_BONE ? (colormap::ColorMap*)(new colormap::Bone) : |
||||
colormap == COLORMAP_COOL ? (colormap::ColorMap*)(new colormap::Cool) : |
||||
colormap == COLORMAP_HOT ? (colormap::ColorMap*)(new colormap::Hot) : |
||||
colormap == COLORMAP_HSV ? (colormap::ColorMap*)(new colormap::HSV) : |
||||
colormap == COLORMAP_JET ? (colormap::ColorMap*)(new colormap::Jet) : |
||||
colormap == COLORMAP_OCEAN ? (colormap::ColorMap*)(new colormap::Ocean) : |
||||
colormap == COLORMAP_PINK ? (colormap::ColorMap*)(new colormap::Pink) : |
||||
colormap == COLORMAP_RAINBOW ? (colormap::ColorMap*)(new colormap::Rainbow) : |
||||
colormap == COLORMAP_SPRING ? (colormap::ColorMap*)(new colormap::Spring) : |
||||
colormap == COLORMAP_SUMMER ? (colormap::ColorMap*)(new colormap::Summer) : |
||||
colormap == COLORMAP_WINTER ? (colormap::ColorMap*)(new colormap::Winter) : 0; |
||||
|
||||
if( !cm ) |
||||
CV_Error( Error::StsBadArg, "Unknown colormap id; use one of COLORMAP_*"); |
||||
|
||||
(*cm)(src, dst); |
||||
|
||||
delete cm; |
||||
} |
||||
} |