*v = false;
Mat matEdge;
Mat src = srcMat.clone();
threshold(src, matEdge, 0, 255, THRESH_OTSU);
Canny(matEdge, matEdge, 3, 9, 3);
Mat pointList = Mat(1, 2, CV_32FC1, Scalar(0));
Mat List1 = Mat(1, 2, CV_32FC1, Scalar(0));
Mat List2 = Mat(1, 2, CV_32FC1, Scalar(0));
Mat point = Mat(1, 2, CV_32FC1, Scalar(0));
float cu = 0, cv = 0;
int row = matEdge.rows, col = matEdge.cols;
for (int v = 0; v < row; v++)
{
for (int u = 0; u < col; u++)
{
if (matEdge.ptr<uchar>(v)[u] > 0)
{
point.ptr<float>(0)[0] = u;
point.ptr<float>(0)[1] = v;
pointList.push_back(point);
cu = cu + u;
cv = cv + v;
}
}
}
if (pointList.rows < 3)
return;
pointList = pointList(Range(1, pointList.rows), Range(0, 2));
cu = cu / pointList.rows;
cv = cv / pointList.rows;
float a1, b1, a2, b2, dt;
a1 = 1, b1 = 0, a2 = 0, b2 = 1;
dt = 0.20*matEdge.rows;
float tempu, tempv, d, tempa, tempb, tempR1, tempR2;
row = pointList.rows;
for (int i = 0; i < row; i++)
{
tempu = pointList.ptr<float>(i)[0] - cu;
tempv = pointList.ptr<float>(i)[1] - cv;
pointList.ptr<float>(i)[0] = tempu;
pointList.ptr<float>(i)[1] = tempv;
d = sqrt(tempu*tempu + tempv*tempv);
if (d < dt)
continue; //忽略离中心太近的点
tempa = tempu / d;
tempb = tempv / d;
tempR1 = abs(a1*tempa + b1*tempb);
tempR2 = abs(a2*tempa + b2*tempb);
if (tempR1 > tempR2)
{
if ((a1*tempa + b1*tempb) > 0)
{
a1 = (a1 + tempa) / 2;
b1 = (b1 + tempb) / 2;
}
else
{
a1 = (a1 - tempa) / 2;
b1 = (b1 - tempb) / 2;
}
point.ptr<float>(0)[0] = tempu;
point.ptr<float>(0)[1] = tempv;
List1.push_back(point);
}
else
{
if ((a2*tempa + b2*tempb) > 0)
{
a2 = (a2 + tempa) / 2;
b2 = (b2 + tempb) / 2;
}
else
{
a2 = (a2 - tempa) / 2;
b2 = (b2 - tempb) / 2;
}
point.ptr<float>(0)[0] = tempu;
point.ptr<float>(0)[1] = tempv;
List2.push_back(point);
}
}
//修正直线向量
List1 = List1(Range(1, List1.rows), Range(0, 2));
List2 = List2(Range(1, List2.rows), Range(0, 2));
if (List1.rows < 3 || List2.rows < 3)
return;
Mat U1, W1, V1, U2, W2, V2;
SVD::compute(List1, W1, U1, V1);
SVD::compute(List2, W2, U2, V2);
a1 = V1.ptr<float>(0)[0];
b1 = V1.ptr<float>(0)[1];
a2 = V2.ptr<float>(0)[0];
b2 = V2.ptr<float>(0)[1];
Mat mR = (Mat_<float>(1, 4) << a1, b1, a2, b2);
//检查点数量
float numT = 0;
if (abs(a1) > abs(b1))
numT = 2 * matEdge.rows / abs(a1);
else
numT = 2 * matEdge.rows / abs(b1);
if (pointList.rows < 0.8 * numT || pointList.rows > 2 * numT)
return;
//记录与正交直线的近似性
float record = 0, temp1, temp2;
row = pointList.rows;
for (int i = 0; i < row; i++)
{
temp1 = abs(pointList.ptr<float>(i)[0] * a1 + pointList.ptr<float>(i)[1] * b1);
temp2 = abs(pointList.ptr<float>(i)[0] * a2 + pointList.ptr<float>(i)[1] * b2);
if (temp1 > temp2)
temp1 = temp2;
if (temp1 > dt)
record++;
}
if (record == 0)
{
*lineVec = mR.clone();
*v = true;
}
怎么提高垂直度的判断
最新发布