461 lines
12 KiB
C++
461 lines
12 KiB
C++
|
|
#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))
|
|||
|
|
{
|
|||
|
|
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;
|
|||
|
|
}
|