camAlgo/camCalib/lineDetection_steger.cpp

463 lines
13 KiB
C++
Raw Normal View History

2025-08-16 15:25:29 +08:00
#include<iostream>
#include<opencv2\opencv.hpp>
#include<unordered_map>
#include<math.h>
#include <corecrt_math_defines.h>
#include "lineDetection_steger.h"
#if 1
using namespace std;
using namespace cv;
struct EV_VAL_VEC {
double nx, ny;//nx<6E><78>nyΪ<79><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
};
void SetFilterMat(Mat& Dx, Mat& Dy, Mat& Dxx, Mat& Dyy, Mat& Dxy, int size_m)//radius * 2= size
{
if (size_m % 2 == 0 || size_m == 1) cout << "size is not illegal !!" << endl;
Mat m1 = Mat::zeros(Size(size_m, size_m), CV_64F);//Dx
Mat m2 = Mat::zeros(Size(size_m, size_m), CV_64F);//Dy
Mat m3 = Mat::zeros(Size(size_m, size_m), CV_64F);//Dxx
Mat m4 = Mat::zeros(Size(size_m, size_m), CV_64F);//Dyy
Mat m5 = Mat::zeros(Size(size_m, size_m), CV_64F);//Dxy
for (int i = 0; i < size_m / 2; i++)
{
m1.row(i) = 1;
m2.col(i) = 1;
m3.row(i) = -1;
m4.col(i) = -1;
}
for (int i = size_m / 2 + 1; i < size_m; i++)
{
m1.row(i) = -1;
m2.col(i) = -1;
m3.row(i) = -1;
m4.col(i) = -1;
}
m3.row(size_m / 2) = (size_m / 2) * 2;
m4.col(size_m / 2) = (size_m / 2) * 2;
m5.row(size_m / 2) = 1;
m5.col(size_m / 2) = 1;
m5.at<double>(size_m / 2, size_m / 2) = -(size_m / 2) * 4;
if (size_m == 5) m5 = (Mat_<double>(5, 5) << 0, 0, 1, 0, 0, 0, 1, 2, 1, 0, 1, 2, -16, 2, 1, 0, 1, 2, 1, 0, 0, 0, 1, 0, 0);
Dx = m2;
Dy = m1;
Dxx = m4;
Dyy = m3;
Dxy = m5;
cout << Dx << endl;
cout << Dy << endl;
cout << Dxx << endl;
cout << Dyy << endl;
cout << Dxy << endl;
return;
}
#if 0
bool isMax(int i, int j, Mat& img, int dx, int dy)//<2F>ڷ<EFBFBD><DAB7>߷<EFBFBD><DFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA>ֵ
{
double val = img.at<double>(j, i);
double max_v = max(img.at<double>(j + dy, i + dx), img.at<double>(j - dy, i - dx));
if (val >= max_v) return true;
else return false;
}
void StegerLine(Mat& img0, vector<Point2d>& sub_pixel, int size_m)
{
Mat img;
cvtColor(img0, img0, cv::COLOR_BGR2GRAY);
img = img0.clone();
//<2F><>˹<EFBFBD>˲<EFBFBD>
img.convertTo(img, CV_64FC1);
cv::GaussianBlur(img, img, Size(3, 3), 0.9, 0.9);
cv::imwrite("gauss_blur_src.bmp", img);
//ho_Image = Mat2Hobject(img);
//Threshold(ho_Image, &ho_Region, 80, 255);
//GetRegionPoints(ho_Region, &hv_Rows, &hv_Columns);
//һ<><D2BB>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD>
Mat m1, m2;
//<2F><><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD>
Mat m3, m4, m5;
SetFilterMat(m1, m2, m3, m4, m5, size_m);
cout << m5 << endl;
Mat dx, dy;
filter2D(img, dx, CV_64FC1, m1);
filter2D(img, dy, CV_64FC1, m2);
Mat dxx, dyy, dxy;
filter2D(img, dxx, CV_64FC1, m3);
filter2D(img, dyy, CV_64FC1, m4);
filter2D(img, dxy, CV_64FC1, m5);
//hessian<61><6E><EFBFBD><EFBFBD>
int imgcol = img.cols;
int imgrow = img.rows;
vector<double> Pt;
for (int i = 0; i < imgcol; i++)
{
for (int j = 0; j < imgrow; j++)
{
double pixel_val = img.at<double>(j, i);
if (img.at<double>(j, i) > 50) //<2F><>Ҫȷ<D2AA><C8B7>ROI<4F><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
Mat hessian(2, 2, CV_64FC1);
hessian.at<double>(0, 0) = dxx.at<double>(j, i);
hessian.at<double>(0, 1) = dxy.at<double>(j, i);
hessian.at<double>(1, 0) = dxy.at<double>(j, i);
hessian.at<double>(1, 1) = dyy.at<double>(j, i);
Mat eValue;
Mat eVectors;
eigen(hessian, eValue, eVectors);
double nx, ny;
double EV_max = 0;//<2F><><EFBFBD><EFBFBD>ֵ
double EV_min = 0;
if (fabs(eValue.at<double>(0, 0)) >= fabs(eValue.at<double>(1, 0))) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
nx = eVectors.at<double>(0, 0);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ny = eVectors.at<double>(0, 1);
EV_max = max(eValue.at<double>(0, 0), eValue.at<double>(1, 0));
EV_min = min(eValue.at<double>(0, 0), eValue.at<double>(1, 0));
}
else
{
nx = eVectors.at<double>(1, 0);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ny = eVectors.at<double>(1, 1);
EV_max = max(eValue.at<double>(0, 0), eValue.at<double>(1, 0));
EV_min = min(eValue.at<double>(0, 0), eValue.at<double>(1, 0));
}
//t <20><>ʽ ̩<><CCA9>չ<EFBFBD><D5B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׵<EFBFBD><D7B5><EFBFBD>
double a = nx * nx * dxx.at<double>(j, i) + 2 * nx * ny * dxy.at<double>(j, i) + ny * ny * dyy.at<double>(j, i);
double b = nx * dx.at<double>(j, i) + ny * dy.at<double>(j, i);
double t = -b / a;
int dx;
int dy;
if (abs(nx) >= 2 * abs(ny)) dx = 1, dy = 0;//<2F><>ֱ
else if (abs(ny) >= 2 * abs(nx)) dx = 0, dy = 1;//ˮƽ
else if (nx > 0) dx = 1, dy = 1;
else if (ny > 0) dx = -1, dy = -1;
if (isMax(i, j, img, dx, dy))
//if(EV_min<-120)
{
double temp1 = t * nx;
double temp2 = t * ny;
if (fabs(t * nx) <= 0.5 && fabs(t * ny) <= 0.5)//(x + t * Nx, y + t * Ny)Ϊ<><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
Pt.push_back(i + t * nx);
Pt.push_back(j + t * ny);
}
}
}
}
}
for (int k = 0; k < Pt.size() / 2; k++)
{
Point2d rpt;
rpt.x = Pt[2 * k + 0];
rpt.y = Pt[2 * k + 1];
sub_pixel.push_back(rpt);
}
}
//E:/workplace/Line_Dtection/Project1/1/1-0.bmp
int main()//E:/workplace/get_line_width/<2F><>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>ԭͼ/<2F><>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>/1300us.bmp
{
Mat src = imread("E:/workplace/Line_Dtection/Project1/1/1-9.bmp");
vector<Point2d>sub_pixel;
StegerLine(src, sub_pixel, 5);
ofstream outfile_r, outfile_c;
outfile_r.open("subpixel_row.txt");
outfile_c.open("subpixel_col.txt");
outfile_r << sub_pixel.size() << endl;
outfile_c << sub_pixel.size() << endl;
for (int i = 0; i < sub_pixel.size(); i++)
{
outfile_r << setprecision(15) << "2 " << sub_pixel[i].y << endl;
outfile_c << setprecision(15) << "2 " << sub_pixel[i].x << endl;
}
outfile_c.close();
outfile_r.close();
return 0;
}
#endif
#endif
typedef struct
{
double dx;
double dy;
double dxx;
double dyy;
double dxy;
}sPtDerivate;
//ֱ<>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD>
double gaussKernel2D(double x, double y, double sigma)
{
double sigma2 = sigma * sigma;
double norm = 1.0 / (2 * M_PI * sigma2);
return (norm * exp(-(x * x + y * y) / (2 * sigma2)));
}
// 2D<32><44>˹һ<CBB9>׵<EFBFBD><D7B5><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>
void generate_1st_2Dmask_directSample(double sigma, int radius, cv::Mat& mask_x, cv::Mat& mask_y)
{
int size = 2 * radius + 1;
mask_x = cv::Mat::zeros(size, size, CV_64FC1);
mask_y = cv::Mat::zeros(size, size, CV_64FC1);
double norm = -1.0 / (sigma * sigma);
for (int row = 0; row < size; row++)
{
double y = (double)(row - radius);
for (int col = 0; col < size; col++)
{
double x = (double)(col - radius);
double dx = x * norm * gaussKernel2D(x, y, sigma);
double dy = y * norm * gaussKernel2D(x, y, sigma);
mask_x.at<double>(row, col) = dx;
mask_y.at<double>(row, col) = dy;
}
}
return;
}
// 2D<32><44>˹<EFBFBD><CBB9><EFBFBD>׵<EFBFBD><D7B5><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>
void generate_2nd_2Dmask_directSample(double sigma, int radius, cv::Mat& mask_xx, cv::Mat& mask_yy, cv::Mat& mask_xy)
{
int size = 2 * radius + 1;
mask_xx = cv::Mat::zeros(size, size, CV_64FC1);
mask_yy = cv::Mat::zeros(size, size, CV_64FC1);
mask_xy = cv::Mat::zeros(size, size, CV_64FC1);
double sigma2 = sigma * sigma;
double norm = 1.0 / (sigma2 * sigma2);
double offset = 1.0 / sigma2;
for (int row = 0; row < size; row++)
{
double y = (double)(row - radius);
for (int col = 0; col < size; col++)
{
double x = (double)(col - radius);
double dxx = (x * x * norm - offset) * gaussKernel2D(x, y, sigma);
double dyy = (y * y * norm - offset) * gaussKernel2D(x, y, sigma);
double dxy = x * y * norm * gaussKernel2D(x, y, sigma);
mask_xx.at<double>(row, col) = dxx;
mask_yy.at<double>(row, col) = dyy;
mask_xy.at<double>(row, col) = dxy;
}
}
return;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
sPtDerivate pointConvolve(
cv::Point ptPos, //<2F><>λ<EFBFBD><CEBB>
int radius, //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
cv::Mat& img, //double<6C>͵<EFBFBD>ͨ<EFBFBD><CDA8>ͼ<EFBFBD><CDBC>
cv::Mat& mask_x, //һ<><D2BB><EFBFBD><EFBFBD>Ĥx
cv::Mat& mask_y, //һ<><D2BB><EFBFBD><EFBFBD>Ĥy
cv::Mat& mask_xx, //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĥxx
cv::Mat& mask_yy, //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĥyy
cv::Mat& mask_xy //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĥxy
)
{
sPtDerivate result = { 0.0, 0.0, 0.0, 0.0, 0.0 };
cv::Size imgSize = img.size(); //
if ((ptPos.x < radius ) || (ptPos.x > (imgSize.width-radius-1)) || (ptPos.y < radius) || (ptPos.y > (imgSize.height - radius - 1)))
return result;
int size = 2 * radius + 1;
for (int i = 0; i < size; i++)
{
int row = i - radius;
int y = ptPos.y + row;
for (int j = 0; j < size; j++)
{
int col = j - radius;
int x = ptPos.x + col;
double value = img.at<double>(y, x);
result.dx += mask_x.at<double>(i, j) * value;
result.dy += mask_y.at<double>(i, j) * value;
result.dxx += mask_xx.at<double>(i, j) * value;
result.dyy += mask_yy.at<double>(i, j) * value;
result.dxy += mask_xy.at<double>(i, j) * value;
}
}
return result;
}
bool isMax(int i, int j, cv::Mat& img, int dx, int dy)//<2F>ڷ<EFBFBD><DAB7>߷<EFBFBD><DFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA>ֵ
{
double val = img.at<double>(j, i);
double max_v = std::max(img.at<double>(j + dy, i + dx), img.at<double>(j - dy, i - dx));
if (val >= max_v) return true;
else return false;
}
//<2F><><EFBFBD><EFBFBD>Hessian<61>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
cv::Point2f computeHessianSubpix(
cv::Point ptPos, //<2F><>λ<EFBFBD><CEBB>
cv::Mat& img, //double<6C>͵<EFBFBD>ͨ<EFBFBD><CDA8>ͼ<EFBFBD><CDBC>
sPtDerivate _ptDerivate
)
{
double subTh = 0.7;
cv::Mat hessian(2, 2, CV_64FC1);
hessian.at<double>(0, 0) = _ptDerivate.dxx;
hessian.at<double>(0, 1) = _ptDerivate.dxy;
hessian.at<double>(1, 0) = _ptDerivate.dxy;
hessian.at<double>(1, 1) = _ptDerivate.dyy;
cv::Mat eigenValue, eigenVector;
cv::eigen(hessian, eigenValue, eigenVector);
double nx, ny;
double vnx, vny;
double EV_max = 0;//<2F><><EFBFBD><EFBFBD>ֵ
double EV_min = 0;
if (fabs(eigenValue.at<double>(0, 0)) >= fabs(eigenValue.at<double>(1, 0))) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
nx = eigenVector.at<double>(0, 0);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ny = eigenVector.at<double>(0, 1);
vnx = eigenVector.at<double>(1, 0);//С<><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
vny = eigenVector.at<double>(1, 1);
EV_max = std::max(eigenValue.at<double>(0, 0), eigenValue.at<double>(1, 0));
EV_min = std::min(eigenValue.at<double>(0, 0), eigenValue.at<double>(1, 0));
}
else
{
nx = eigenVector.at<double>(1, 0);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ny = eigenVector.at<double>(1, 1);
vnx = eigenVector.at<double>(0, 0);//С<><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
vny = eigenVector.at<double>(0, 1);
EV_max = std::max(eigenValue.at<double>(0, 0), eigenValue.at<double>(1, 0));
EV_min = std::min(eigenValue.at<double>(0, 0), eigenValue.at<double>(1, 0));
}
cv::Point2f subPix = { -1.0f, -1.0f }; //<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
//t <20><>ʽ ̩<><CCA9>չ<EFBFBD><D5B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׵<EFBFBD><D7B5><EFBFBD>
double a = nx * nx * _ptDerivate.dxx + 2 * nx * ny * _ptDerivate.dxy + ny * ny * _ptDerivate.dyy;
double b = nx * _ptDerivate.dx + ny * _ptDerivate.dy;
if (a != 0.0)
{
double t = b / a; // -b / a;
int dx;
int dy;
if (abs(nx) >= 2 * abs(ny)) dx = 1, dy = 0;//<2F><>ֱ
else if (abs(ny) >= 2 * abs(nx)) dx = 0, dy = 1;//ˮƽ
else if (nx > 0) dx = 1, dy = 1;
else if (ny > 0) dx = -1, dy = -1;
if (isMax(ptPos.x, ptPos.y, img, dx, dy))
//if(EV_min<-120)
{
double temp1 = t * nx;
double temp2 = t * ny;
if (fabs(t * nx) <= subTh && fabs(t * ny) <= subTh)//(x + t * Nx, y + t * Ny)Ϊ<><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
subPix.x = (float)(ptPos.x + t * nx);
subPix.y = (float)(ptPos.y + t * ny);
}
}
}
return subPix;
}
// <20>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void computePointSubpix(
cv::Mat& inputImg, //uchar<61>͵<EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD>񣨻Ҷ<F1A3A8BB>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>
std::vector<cv::Point>&pos, //<2F><>ֵ<EFBFBD><D6B5><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int gaussWin, //ʹ<><CAB9>steger<65>㷨ʱָ<CAB1><D6B8><EFBFBD>Ĵ<EFBFBD><C4B4>ڿ<EFBFBD><DABF>ȡ<EFBFBD><C8A1>˿<EFBFBD><CBBF><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EBBCA4><EFBFBD>ߵĿ<DFB5><C4BF>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD>Ǻ<EFBFBD>
std::vector<cv::Point2f>& posSubpix //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
)
{
cv::Mat mask_x, mask_y, mask_xx, mask_yy, mask_xy;
double sigma = (double)gaussWin / sqrt(3);
//double sigma = 1.0;
#if 0
SetFilterMat(mask_x, mask_y, mask_xx, mask_yy, mask_xy, gaussWin*2+1);
#else
generate_1st_2Dmask_directSample(sigma, gaussWin, mask_x, mask_y);
generate_2nd_2Dmask_directSample(sigma, gaussWin, mask_xx, mask_yy, mask_xy);
#endif
#if 0
std::cout << "mask::" << std::endl;
std::cout << mask_x << std::endl;
std::cout << mask_y << std::endl;
std::cout << mask_xx << std::endl;
std::cout << mask_yy << std::endl;
std::cout << mask_xy << std::endl;
#endif
//<2F><>˹<EFBFBD>˲<EFBFBD>
cv::Mat img;
inputImg.convertTo(img, CV_64FC1);
cv::GaussianBlur(img, img, cv::Size(3, 3), 0.9, 0.9);
//cv::imwrite("gauss_blur_src.bmp", img);
for (int i = 0, i_max = (int)pos.size(); i < i_max; i++)
{
cv::Point ptPos = pos[i];
int doSubPix = 0;
while (doSubPix >= 0)
{
sPtDerivate a_ptDerivate = pointConvolve(
ptPos, //<2F><>λ<EFBFBD><CEBB>
gaussWin, //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
img, //double<6C>͵<EFBFBD>ͨ<EFBFBD><CDA8>ͼ<EFBFBD><CDBC>
mask_x, //һ<><D2BB><EFBFBD><EFBFBD>Ĥx
mask_y, //һ<><D2BB><EFBFBD><EFBFBD>Ĥy
mask_xx, //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĥxx
mask_yy, //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĥyy
mask_xy //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĥxy
);
cv::Point2f subpix = computeHessianSubpix(
ptPos, //<2F><>λ<EFBFBD><CEBB>
img, //double<6C>͵<EFBFBD>ͨ<EFBFBD><CDA8>ͼ<EFBFBD><CDBC>
a_ptDerivate
);
if ((subpix.x >= 0) && (subpix.y >= 0))
{
2025-08-18 10:19:31 +08:00
subpix.x += 0.5; //ͼ<><CDBC><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>ñ<EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½ǣ<C2BD><C7A3><EFBFBD><EFBFBD>˴<EFBFBD><CBB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD>λ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0.5<EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD>
subpix.y -= 0.5; //<2F>˴<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>Y<EFBFBD><59><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>ķ<EFBFBD><C4B7><EFBFBD><EFBFBD>
2025-08-16 15:25:29 +08:00
posSubpix.push_back(subpix);
doSubPix = -1;
}
else
{
if (0 == doSubPix)
{
ptPos.x = pos[i].x - 1;
doSubPix = 1;
}
else if (1 == doSubPix)
{
ptPos.x = pos[i].x + 1;
doSubPix = 2;
}
else
{
doSubPix = -1;
}
}
}
}
return;
}