mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 07:43:03 +04:00
Merge branch 4.x
This commit is contained in:
@@ -44,6 +44,8 @@
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
// Requires CMake flag: DEBUG_opencv_features2d=ON
|
||||
//#define DEBUG_BLOB_DETECTOR
|
||||
|
||||
@@ -317,6 +319,19 @@ void SimpleBlobDetectorImpl::detect(InputArray image, std::vector<cv::KeyPoint>&
|
||||
CV_Error(Error::StsUnsupportedFormat, "Blob detector only supports 8-bit images!");
|
||||
}
|
||||
|
||||
CV_CheckGT(params.thresholdStep, 0.0f, "");
|
||||
if (params.minThreshold + params.thresholdStep >= params.maxThreshold)
|
||||
{
|
||||
// https://github.com/opencv/opencv/issues/6667
|
||||
CV_LOG_ONCE_INFO(NULL, "SimpleBlobDetector: params.minDistBetweenBlobs is ignored for case with single threshold");
|
||||
#if 0 // OpenCV 5.0
|
||||
CV_CheckEQ(params.minRepeatability, 1u, "Incompatible parameters for case with single threshold");
|
||||
#else
|
||||
if (params.minRepeatability != 1)
|
||||
CV_LOG_WARNING(NULL, "SimpleBlobDetector: params.minRepeatability=" << params.minRepeatability << " is incompatible for case with single threshold. Empty result is expected.");
|
||||
#endif
|
||||
}
|
||||
|
||||
std::vector < std::vector<Center> > centers;
|
||||
for (double thresh = params.minThreshold; thresh < params.maxThreshold; thresh += params.thresholdStep)
|
||||
{
|
||||
@@ -325,19 +340,13 @@ void SimpleBlobDetectorImpl::detect(InputArray image, std::vector<cv::KeyPoint>&
|
||||
|
||||
std::vector < Center > curCenters;
|
||||
findBlobs(grayscaleImage, binarizedImage, curCenters);
|
||||
if(params.maxThreshold - params.minThreshold <= params.thresholdStep) {
|
||||
// if the difference between min and max threshold is less than the threshold step
|
||||
// we're only going to enter the loop once, so we need to add curCenters
|
||||
// to ensure we still use minDistBetweenBlobs
|
||||
centers.push_back(curCenters);
|
||||
}
|
||||
std::vector < std::vector<Center> > newCenters;
|
||||
for (size_t i = 0; i < curCenters.size(); i++)
|
||||
{
|
||||
bool isNew = true;
|
||||
for (size_t j = 0; j < centers.size(); j++)
|
||||
{
|
||||
double dist = norm(centers[j][centers[j].size() / 2 ].location - curCenters[i].location);
|
||||
double dist = norm(centers[j][ centers[j].size() / 2 ].location - curCenters[i].location);
|
||||
isNew = dist >= params.minDistBetweenBlobs && dist >= centers[j][ centers[j].size() / 2 ].radius && dist >= curCenters[i].radius;
|
||||
if (!isNew)
|
||||
{
|
||||
|
||||
@@ -183,7 +183,8 @@ static void _prepareImgAndDrawKeypoints( InputArray img1, const std::vector<KeyP
|
||||
}
|
||||
|
||||
static inline void _drawMatch( InputOutputArray outImg, InputOutputArray outImg1, InputOutputArray outImg2 ,
|
||||
const KeyPoint& kp1, const KeyPoint& kp2, const Scalar& matchColor, DrawMatchesFlags flags )
|
||||
const KeyPoint& kp1, const KeyPoint& kp2, const Scalar& matchColor, DrawMatchesFlags flags,
|
||||
const int matchesThickness )
|
||||
{
|
||||
RNG& rng = theRNG();
|
||||
bool isRandMatchColor = matchColor == Scalar::all(-1);
|
||||
@@ -199,7 +200,7 @@ static inline void _drawMatch( InputOutputArray outImg, InputOutputArray outImg1
|
||||
line( outImg,
|
||||
Point(cvRound(pt1.x*draw_multiplier), cvRound(pt1.y*draw_multiplier)),
|
||||
Point(cvRound(dpt2.x*draw_multiplier), cvRound(dpt2.y*draw_multiplier)),
|
||||
color, 1, LINE_AA, draw_shift_bits );
|
||||
color, matchesThickness, LINE_AA, draw_shift_bits );
|
||||
}
|
||||
|
||||
void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
|
||||
@@ -207,6 +208,21 @@ void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
|
||||
const std::vector<DMatch>& matches1to2, InputOutputArray outImg,
|
||||
const Scalar& matchColor, const Scalar& singlePointColor,
|
||||
const std::vector<char>& matchesMask, DrawMatchesFlags flags )
|
||||
{
|
||||
drawMatches( img1, keypoints1,
|
||||
img2, keypoints2,
|
||||
matches1to2, outImg,
|
||||
1, matchColor,
|
||||
singlePointColor, matchesMask,
|
||||
flags);
|
||||
}
|
||||
|
||||
void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
|
||||
InputArray img2, const std::vector<KeyPoint>& keypoints2,
|
||||
const std::vector<DMatch>& matches1to2, InputOutputArray outImg,
|
||||
const int matchesThickness, const Scalar& matchColor,
|
||||
const Scalar& singlePointColor, const std::vector<char>& matchesMask,
|
||||
DrawMatchesFlags flags )
|
||||
{
|
||||
if( !matchesMask.empty() && matchesMask.size() != matches1to2.size() )
|
||||
CV_Error( Error::StsBadSize, "matchesMask must have the same size as matches1to2" );
|
||||
@@ -226,11 +242,12 @@ void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
|
||||
CV_Assert(i2 >= 0 && i2 < static_cast<int>(keypoints2.size()));
|
||||
|
||||
const KeyPoint &kp1 = keypoints1[i1], &kp2 = keypoints2[i2];
|
||||
_drawMatch( outImg, outImg1, outImg2, kp1, kp2, matchColor, flags );
|
||||
_drawMatch( outImg, outImg1, outImg2, kp1, kp2, matchColor, flags, matchesThickness );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
|
||||
InputArray img2, const std::vector<KeyPoint>& keypoints2,
|
||||
const std::vector<std::vector<DMatch> >& matches1to2, InputOutputArray outImg,
|
||||
@@ -254,7 +271,7 @@ void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
|
||||
if( matchesMask.empty() || matchesMask[i][j] )
|
||||
{
|
||||
const KeyPoint &kp1 = keypoints1[i1], &kp2 = keypoints2[i2];
|
||||
_drawMatch( outImg, outImg1, outImg2, kp1, kp2, matchColor, flags );
|
||||
_drawMatch( outImg, outImg1, outImg2, kp1, kp2, matchColor, flags, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ private:
|
||||
void KAZEFeatures::Determinant_Hessian(std::vector<KeyPoint>& kpts)
|
||||
{
|
||||
int level = 0;
|
||||
float dist = 0.0, smax = 3.0;
|
||||
float smax = 3.0;
|
||||
int npoints = 0, id_repeated = 0;
|
||||
int left_x = 0, right_x = 0, up_y = 0, down_y = 0;
|
||||
bool is_extremum = false, is_repeated = false, is_out = false;
|
||||
@@ -338,17 +338,24 @@ void KAZEFeatures::Determinant_Hessian(std::vector<KeyPoint>& kpts)
|
||||
for (int j = 0; j < (int)kpts_par_[i].size(); j++)
|
||||
{
|
||||
level = i + 1;
|
||||
const TEvolution& evolution_level = evolution_[level];
|
||||
|
||||
is_extremum = true;
|
||||
is_repeated = false;
|
||||
is_out = false;
|
||||
|
||||
// Check in case we have the same point as maxima in previous evolution levels
|
||||
for (int ik = 0; ik < (int)kpts.size(); ik++) {
|
||||
if (kpts[ik].class_id == level || kpts[ik].class_id == level + 1 || kpts[ik].class_id == level - 1) {
|
||||
dist = pow(kpts_par_[i][j].pt.x - kpts[ik].pt.x, 2) + pow(kpts_par_[i][j].pt.y - kpts[ik].pt.y, 2);
|
||||
const KeyPoint& kpts_par_ij = kpts_par_[i][j];
|
||||
|
||||
if (dist < evolution_[level].sigma_size*evolution_[level].sigma_size) {
|
||||
if (kpts_par_[i][j].response > kpts[ik].response) {
|
||||
// Check in case we have the same point as maxima in previous evolution levels
|
||||
for (int ik = 0; ik < (int)kpts.size(); ik++)
|
||||
{
|
||||
const KeyPoint& kpts_ik = kpts[ik];
|
||||
if (kpts_ik.class_id == level || kpts_ik.class_id == level + 1 || kpts_ik.class_id == level - 1) {
|
||||
Point2f diff = kpts_par_ij.pt - kpts_ik.pt;
|
||||
float dist = diff.dot(diff);
|
||||
|
||||
if (dist < evolution_level.sigma_size*evolution_level.sigma_size) {
|
||||
if (kpts_par_ij.response > kpts_ik.response) {
|
||||
id_repeated = ik;
|
||||
is_repeated = true;
|
||||
}
|
||||
@@ -363,23 +370,23 @@ void KAZEFeatures::Determinant_Hessian(std::vector<KeyPoint>& kpts)
|
||||
|
||||
if (is_extremum == true) {
|
||||
// Check that the point is under the image limits for the descriptor computation
|
||||
left_x = cvRound(kpts_par_[i][j].pt.x - smax*kpts_par_[i][j].size);
|
||||
right_x = cvRound(kpts_par_[i][j].pt.x + smax*kpts_par_[i][j].size);
|
||||
up_y = cvRound(kpts_par_[i][j].pt.y - smax*kpts_par_[i][j].size);
|
||||
down_y = cvRound(kpts_par_[i][j].pt.y + smax*kpts_par_[i][j].size);
|
||||
left_x = cvRound(kpts_par_ij.pt.x - smax*kpts_par_ij.size);
|
||||
right_x = cvRound(kpts_par_ij.pt.x + smax*kpts_par_ij.size);
|
||||
up_y = cvRound(kpts_par_ij.pt.y - smax*kpts_par_ij.size);
|
||||
down_y = cvRound(kpts_par_ij.pt.y + smax*kpts_par_ij.size);
|
||||
|
||||
if (left_x < 0 || right_x >= evolution_[level].Ldet.cols ||
|
||||
up_y < 0 || down_y >= evolution_[level].Ldet.rows) {
|
||||
if (left_x < 0 || right_x >= evolution_level.Ldet.cols ||
|
||||
up_y < 0 || down_y >= evolution_level.Ldet.rows) {
|
||||
is_out = true;
|
||||
}
|
||||
|
||||
if (is_out == false) {
|
||||
if (is_repeated == false) {
|
||||
kpts.push_back(kpts_par_[i][j]);
|
||||
kpts.push_back(kpts_par_ij);
|
||||
npoints++;
|
||||
}
|
||||
else {
|
||||
kpts[id_repeated] = kpts_par_[i][j];
|
||||
kpts[id_repeated] = kpts_par_ij;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -513,16 +520,16 @@ public:
|
||||
if (options_.upright)
|
||||
{
|
||||
kpts[i].angle = 0.0;
|
||||
if (options_.extended)
|
||||
if (options_.extended)
|
||||
Get_KAZE_Upright_Descriptor_128(kpts[i], desc.ptr<float>((int)i));
|
||||
else
|
||||
Get_KAZE_Upright_Descriptor_64(kpts[i], desc.ptr<float>((int)i));
|
||||
}
|
||||
else
|
||||
{
|
||||
KAZEFeatures::Compute_Main_Orientation(kpts[i], evolution, options_);
|
||||
KAZEFeatures::Compute_Main_Orientation(kpts[i], evolution, options_);
|
||||
|
||||
if (options_.extended)
|
||||
if (options_.extended)
|
||||
Get_KAZE_Descriptor_128(kpts[i], desc.ptr<float>((int)i));
|
||||
else
|
||||
Get_KAZE_Descriptor_64(kpts[i], desc.ptr<float>((int)i));
|
||||
@@ -712,26 +719,26 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Upright_Descriptor_64(const KeyPoint &kpt
|
||||
y1 = (int)(sample_y - 0.5f);
|
||||
x1 = (int)(sample_x - 0.5f);
|
||||
|
||||
checkDescriptorLimits(x1, y1, options_.img_width, options_.img_height);
|
||||
checkDescriptorLimits(x1, y1, options_.img_width, options_.img_height);
|
||||
|
||||
y2 = (int)(sample_y + 0.5f);
|
||||
x2 = (int)(sample_x + 0.5f);
|
||||
|
||||
checkDescriptorLimits(x2, y2, options_.img_width, options_.img_height);
|
||||
checkDescriptorLimits(x2, y2, options_.img_width, options_.img_height);
|
||||
|
||||
fx = sample_x - x1;
|
||||
fy = sample_y - y1;
|
||||
|
||||
res1 = *(evolution[level].Lx.ptr<float>(y1)+x1);
|
||||
res2 = *(evolution[level].Lx.ptr<float>(y1)+x2);
|
||||
res3 = *(evolution[level].Lx.ptr<float>(y2)+x1);
|
||||
res4 = *(evolution[level].Lx.ptr<float>(y2)+x2);
|
||||
res1 = *(evolution[level].Lx.ptr<float>(y1)+x1);
|
||||
res2 = *(evolution[level].Lx.ptr<float>(y1)+x2);
|
||||
res3 = *(evolution[level].Lx.ptr<float>(y2)+x1);
|
||||
res4 = *(evolution[level].Lx.ptr<float>(y2)+x2);
|
||||
rx = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4;
|
||||
|
||||
res1 = *(evolution[level].Ly.ptr<float>(y1)+x1);
|
||||
res2 = *(evolution[level].Ly.ptr<float>(y1)+x2);
|
||||
res3 = *(evolution[level].Ly.ptr<float>(y2)+x1);
|
||||
res4 = *(evolution[level].Ly.ptr<float>(y2)+x2);
|
||||
res1 = *(evolution[level].Ly.ptr<float>(y1)+x1);
|
||||
res2 = *(evolution[level].Ly.ptr<float>(y1)+x2);
|
||||
res3 = *(evolution[level].Ly.ptr<float>(y2)+x1);
|
||||
res4 = *(evolution[level].Ly.ptr<float>(y2)+x2);
|
||||
ry = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4;
|
||||
|
||||
rx = gauss_s1*rx;
|
||||
|
||||
@@ -131,12 +131,17 @@ static void
|
||||
HarrisResponses(const Mat& img, const std::vector<Rect>& layerinfo,
|
||||
std::vector<KeyPoint>& pts, int blockSize, float harris_k)
|
||||
{
|
||||
CV_Assert( img.type() == CV_8UC1 && blockSize*blockSize <= 2048 );
|
||||
CV_CheckTypeEQ(img.type(), CV_8UC1, "");
|
||||
CV_CheckGT(blockSize, 0, "");
|
||||
CV_CheckLE(blockSize*blockSize, 2048, "");
|
||||
|
||||
size_t ptidx, ptsize = pts.size();
|
||||
|
||||
const uchar* ptr00 = img.ptr<uchar>();
|
||||
int step = (int)(img.step/img.elemSize1());
|
||||
size_t size_t_step = img.step;
|
||||
CV_CheckLE(size_t_step * blockSize + blockSize + 1, (size_t)INT_MAX, ""); // ofs computation, step+1
|
||||
int step = static_cast<int>(size_t_step);
|
||||
|
||||
int r = blockSize/2;
|
||||
|
||||
float scale = 1.f/((1 << 2) * blockSize * 255.f);
|
||||
@@ -154,7 +159,7 @@ HarrisResponses(const Mat& img, const std::vector<Rect>& layerinfo,
|
||||
int y0 = cvRound(pts[ptidx].pt.y);
|
||||
int z = pts[ptidx].octave;
|
||||
|
||||
const uchar* ptr0 = ptr00 + (y0 - r + layerinfo[z].y)*step + x0 - r + layerinfo[z].x;
|
||||
const uchar* ptr0 = ptr00 + (y0 - r + layerinfo[z].y)*size_t_step + (x0 - r + layerinfo[z].x);
|
||||
int a = 0, b = 0, c = 0;
|
||||
|
||||
for( int k = 0; k < blockSize*blockSize; k++ )
|
||||
|
||||
@@ -450,31 +450,184 @@ public:
|
||||
const sift_wt* currptr = img.ptr<sift_wt>(r);
|
||||
const sift_wt* prevptr = prev.ptr<sift_wt>(r);
|
||||
const sift_wt* nextptr = next.ptr<sift_wt>(r);
|
||||
int c = SIFT_IMG_BORDER;
|
||||
|
||||
for( int c = SIFT_IMG_BORDER; c < cols-SIFT_IMG_BORDER; c++)
|
||||
#if CV_SIMD && !(DoG_TYPE_SHORT)
|
||||
const int vecsize = v_float32::nlanes;
|
||||
for( ; c <= cols-SIFT_IMG_BORDER - vecsize; c += vecsize)
|
||||
{
|
||||
v_float32 val = vx_load(&currptr[c]);
|
||||
v_float32 _00,_01,_02;
|
||||
v_float32 _10, _12;
|
||||
v_float32 _20,_21,_22;
|
||||
|
||||
v_float32 vmin,vmax;
|
||||
|
||||
|
||||
v_float32 cond = v_abs(val) > vx_setall_f32((float)threshold);
|
||||
if (!v_check_any(cond))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_00 = vx_load(&currptr[c-step-1]); _01 = vx_load(&currptr[c-step]); _02 = vx_load(&currptr[c-step+1]);
|
||||
_10 = vx_load(&currptr[c -1]); _12 = vx_load(&currptr[c +1]);
|
||||
_20 = vx_load(&currptr[c+step-1]); _21 = vx_load(&currptr[c+step]); _22 = vx_load(&currptr[c+step+1]);
|
||||
|
||||
vmax = v_max(v_max(v_max(_00,_01),v_max(_02,_10)),v_max(v_max(_12,_20),v_max(_21,_22)));
|
||||
vmin = v_min(v_min(v_min(_00,_01),v_min(_02,_10)),v_min(v_min(_12,_20),v_min(_21,_22)));
|
||||
|
||||
v_float32 condp = cond & (val > vx_setall_f32(0)) & (val >= vmax);
|
||||
v_float32 condm = cond & (val < vx_setall_f32(0)) & (val <= vmin);
|
||||
|
||||
cond = condp | condm;
|
||||
if (!v_check_any(cond))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_00 = vx_load(&prevptr[c-step-1]); _01 = vx_load(&prevptr[c-step]); _02 = vx_load(&prevptr[c-step+1]);
|
||||
_10 = vx_load(&prevptr[c -1]); _12 = vx_load(&prevptr[c +1]);
|
||||
_20 = vx_load(&prevptr[c+step-1]); _21 = vx_load(&prevptr[c+step]); _22 = vx_load(&prevptr[c+step+1]);
|
||||
|
||||
vmax = v_max(v_max(v_max(_00,_01),v_max(_02,_10)),v_max(v_max(_12,_20),v_max(_21,_22)));
|
||||
vmin = v_min(v_min(v_min(_00,_01),v_min(_02,_10)),v_min(v_min(_12,_20),v_min(_21,_22)));
|
||||
|
||||
condp &= (val >= vmax);
|
||||
condm &= (val <= vmin);
|
||||
|
||||
cond = condp | condm;
|
||||
if (!v_check_any(cond))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
v_float32 _11p = vx_load(&prevptr[c]);
|
||||
v_float32 _11n = vx_load(&nextptr[c]);
|
||||
|
||||
v_float32 max_middle = v_max(_11n,_11p);
|
||||
v_float32 min_middle = v_min(_11n,_11p);
|
||||
|
||||
_00 = vx_load(&nextptr[c-step-1]); _01 = vx_load(&nextptr[c-step]); _02 = vx_load(&nextptr[c-step+1]);
|
||||
_10 = vx_load(&nextptr[c -1]); _12 = vx_load(&nextptr[c +1]);
|
||||
_20 = vx_load(&nextptr[c+step-1]); _21 = vx_load(&nextptr[c+step]); _22 = vx_load(&nextptr[c+step+1]);
|
||||
|
||||
vmax = v_max(v_max(v_max(_00,_01),v_max(_02,_10)),v_max(v_max(_12,_20),v_max(_21,_22)));
|
||||
vmin = v_min(v_min(v_min(_00,_01),v_min(_02,_10)),v_min(v_min(_12,_20),v_min(_21,_22)));
|
||||
|
||||
condp &= (val >= v_max(vmax,max_middle));
|
||||
condm &= (val <= v_min(vmin,min_middle));
|
||||
|
||||
cond = condp | condm;
|
||||
if (!v_check_any(cond))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int mask = v_signmask(cond);
|
||||
for (int k = 0; k<vecsize;k++)
|
||||
{
|
||||
if ((mask & (1<<k)) == 0)
|
||||
continue;
|
||||
|
||||
CV_TRACE_REGION("pixel_candidate_simd");
|
||||
|
||||
KeyPoint kpt;
|
||||
int r1 = r, c1 = c+k, layer = i;
|
||||
if( !adjustLocalExtrema(dog_pyr, kpt, o, layer, r1, c1,
|
||||
nOctaveLayers, (float)contrastThreshold,
|
||||
(float)edgeThreshold, (float)sigma) )
|
||||
continue;
|
||||
float scl_octv = kpt.size*0.5f/(1 << o);
|
||||
float omax = calcOrientationHist(gauss_pyr[o*(nOctaveLayers+3) + layer],
|
||||
Point(c1, r1),
|
||||
cvRound(SIFT_ORI_RADIUS * scl_octv),
|
||||
SIFT_ORI_SIG_FCTR * scl_octv,
|
||||
hist, n);
|
||||
float mag_thr = (float)(omax * SIFT_ORI_PEAK_RATIO);
|
||||
for( int j = 0; j < n; j++ )
|
||||
{
|
||||
int l = j > 0 ? j - 1 : n - 1;
|
||||
int r2 = j < n-1 ? j + 1 : 0;
|
||||
|
||||
if( hist[j] > hist[l] && hist[j] > hist[r2] && hist[j] >= mag_thr )
|
||||
{
|
||||
float bin = j + 0.5f * (hist[l]-hist[r2]) / (hist[l] - 2*hist[j] + hist[r2]);
|
||||
bin = bin < 0 ? n + bin : bin >= n ? bin - n : bin;
|
||||
kpt.angle = 360.f - (float)((360.f/n) * bin);
|
||||
if(std::abs(kpt.angle - 360.f) < FLT_EPSILON)
|
||||
kpt.angle = 0.f;
|
||||
|
||||
kpts_.push_back(kpt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif //CV_SIMD && !(DoG_TYPE_SHORT)
|
||||
|
||||
// vector loop reminder, better predictibility and less branch density
|
||||
for( ; c < cols-SIFT_IMG_BORDER; c++)
|
||||
{
|
||||
sift_wt val = currptr[c];
|
||||
if (std::abs(val) <= threshold)
|
||||
continue;
|
||||
|
||||
// find local extrema with pixel accuracy
|
||||
if( std::abs(val) > threshold &&
|
||||
((val > 0 && val >= currptr[c-1] && val >= currptr[c+1] &&
|
||||
val >= currptr[c-step-1] && val >= currptr[c-step] && val >= currptr[c-step+1] &&
|
||||
val >= currptr[c+step-1] && val >= currptr[c+step] && val >= currptr[c+step+1] &&
|
||||
val >= nextptr[c] && val >= nextptr[c-1] && val >= nextptr[c+1] &&
|
||||
val >= nextptr[c-step-1] && val >= nextptr[c-step] && val >= nextptr[c-step+1] &&
|
||||
val >= nextptr[c+step-1] && val >= nextptr[c+step] && val >= nextptr[c+step+1] &&
|
||||
val >= prevptr[c] && val >= prevptr[c-1] && val >= prevptr[c+1] &&
|
||||
val >= prevptr[c-step-1] && val >= prevptr[c-step] && val >= prevptr[c-step+1] &&
|
||||
val >= prevptr[c+step-1] && val >= prevptr[c+step] && val >= prevptr[c+step+1]) ||
|
||||
(val < 0 && val <= currptr[c-1] && val <= currptr[c+1] &&
|
||||
val <= currptr[c-step-1] && val <= currptr[c-step] && val <= currptr[c-step+1] &&
|
||||
val <= currptr[c+step-1] && val <= currptr[c+step] && val <= currptr[c+step+1] &&
|
||||
val <= nextptr[c] && val <= nextptr[c-1] && val <= nextptr[c+1] &&
|
||||
val <= nextptr[c-step-1] && val <= nextptr[c-step] && val <= nextptr[c-step+1] &&
|
||||
val <= nextptr[c+step-1] && val <= nextptr[c+step] && val <= nextptr[c+step+1] &&
|
||||
val <= prevptr[c] && val <= prevptr[c-1] && val <= prevptr[c+1] &&
|
||||
val <= prevptr[c-step-1] && val <= prevptr[c-step] && val <= prevptr[c-step+1] &&
|
||||
val <= prevptr[c+step-1] && val <= prevptr[c+step] && val <= prevptr[c+step+1])))
|
||||
sift_wt _00,_01,_02;
|
||||
sift_wt _10, _12;
|
||||
sift_wt _20,_21,_22;
|
||||
_00 = currptr[c-step-1]; _01 = currptr[c-step]; _02 = currptr[c-step+1];
|
||||
_10 = currptr[c -1]; _12 = currptr[c +1];
|
||||
_20 = currptr[c+step-1]; _21 = currptr[c+step]; _22 = currptr[c+step+1];
|
||||
|
||||
bool calculate = false;
|
||||
if (val > 0)
|
||||
{
|
||||
sift_wt vmax = std::max(std::max(std::max(_00,_01),std::max(_02,_10)),std::max(std::max(_12,_20),std::max(_21,_22)));
|
||||
if (val >= vmax)
|
||||
{
|
||||
_00 = prevptr[c-step-1]; _01 = prevptr[c-step]; _02 = prevptr[c-step+1];
|
||||
_10 = prevptr[c -1]; _12 = prevptr[c +1];
|
||||
_20 = prevptr[c+step-1]; _21 = prevptr[c+step]; _22 = prevptr[c+step+1];
|
||||
vmax = std::max(std::max(std::max(_00,_01),std::max(_02,_10)),std::max(std::max(_12,_20),std::max(_21,_22)));
|
||||
if (val >= vmax)
|
||||
{
|
||||
_00 = nextptr[c-step-1]; _01 = nextptr[c-step]; _02 = nextptr[c-step+1];
|
||||
_10 = nextptr[c -1]; _12 = nextptr[c +1];
|
||||
_20 = nextptr[c+step-1]; _21 = nextptr[c+step]; _22 = nextptr[c+step+1];
|
||||
vmax = std::max(std::max(std::max(_00,_01),std::max(_02,_10)),std::max(std::max(_12,_20),std::max(_21,_22)));
|
||||
if (val >= vmax)
|
||||
{
|
||||
sift_wt _11p = prevptr[c], _11n = nextptr[c];
|
||||
calculate = (val >= std::max(_11p,_11n));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else { // val cant be zero here (first abs took care of zero), must be negative
|
||||
sift_wt vmin = std::min(std::min(std::min(_00,_01),std::min(_02,_10)),std::min(std::min(_12,_20),std::min(_21,_22)));
|
||||
if (val <= vmin)
|
||||
{
|
||||
_00 = prevptr[c-step-1]; _01 = prevptr[c-step]; _02 = prevptr[c-step+1];
|
||||
_10 = prevptr[c -1]; _12 = prevptr[c +1];
|
||||
_20 = prevptr[c+step-1]; _21 = prevptr[c+step]; _22 = prevptr[c+step+1];
|
||||
vmin = std::min(std::min(std::min(_00,_01),std::min(_02,_10)),std::min(std::min(_12,_20),std::min(_21,_22)));
|
||||
if (val <= vmin)
|
||||
{
|
||||
_00 = nextptr[c-step-1]; _01 = nextptr[c-step]; _02 = nextptr[c-step+1];
|
||||
_10 = nextptr[c -1]; _12 = nextptr[c +1];
|
||||
_20 = nextptr[c+step-1]; _21 = nextptr[c+step]; _22 = nextptr[c+step+1];
|
||||
vmin = std::min(std::min(std::min(_00,_01),std::min(_02,_10)),std::min(std::min(_12,_20),std::min(_21,_22)));
|
||||
if (val <= vmin)
|
||||
{
|
||||
sift_wt _11p = prevptr[c], _11n = nextptr[c];
|
||||
calculate = (val <= std::min(_11p,_11n));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (calculate)
|
||||
{
|
||||
CV_TRACE_REGION("pixel_candidate");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user