直线拟合(Ransac+Opencv)

直线拟合(Ransac+Opencv)
直线拟合(Ransac+Opencv)
Ransac原理
Ransac直线拟合原理(待补充)
出现的Bug
OpenCV Error: Assertion failed (npoints2 >= 0 || npoints3 >= 0) in fitLine
原因
代码错误表明问题出现在fitLine(),下⾯是Opencv提供的源码
void cv::fitLine( InputArray _points, OutputArray _line, int distType,  double param, double reps, double aeps )
{
CV_INSTRUMENT_REGION();
Mat points = _Mat();
float linebuf[6]={0.f};
int npoints2 = points.checkVector(2, -1, false);
int npoints3 = points.checkVector(3, -1, false);
CV_Assert( npoints2 >= 0 || npoints3 >= 0 );
if( points.depth() != CV_32F || !points.isContinuous() )
{
Mat temp;
points = temp;
}
if( npoints2 >= 0 )
fitLine2D( points.ptr<Point2f>(), npoints2, distType,
(float)param, (float)reps, (float)aeps, linebuf);
else
fitLine3D( points.ptr<Point3f>(), npoints3, distType,
(float)param, (float)reps, (float)aeps, linebuf);
Mat(npoints2 >= 0 ? 4 : 6, 1, CV_32F, linebuf).copyTo(_line);
}
可以发现错误提⽰来⾃CV_Assert(npoints2 >= 0 || npoints3 >= 0)
研究函数 checkVector() 的定义
int cv::Mat::checkVector
(  int elemChannels,
int depth = -1,
bool requireContinuous = true
)const
调⽤checkVector() 的矩阵,我的理解是⽤checkVector() 来检查矩阵的通道数和连续性,⽆误时可以返回矩阵的维数,⼆维Mat返回2,三维Mat返回3,否则返回-1
再看⼀下矩阵points是由以下代码⽣成的
Mat points = _Mat();
由此可以判断出我代码中出现问题的部分是 进⼊fitLIine()时_points传参的时候出现了问题
进⽽检查代码(如下)
detectangle_step = 4;
detectangle_width = 30;
for (int i = 0 ; i < 1080/detectangle_step; i++){
std::vector<Point2d>::const_iterator first1 = ptSet_original.begin() + i*detectangle_step;
拟合直线std::vector<Point2d>::const_iterator last1  = ptSet_original.begin() + i*detectangle_step + detectangle_width;
std::vector<Point2d> ptSet(first1, last1);
fitLineRANSAC(ptSet, A, B, C, inliers);
...(省略)
}
产⽣问题的是遍历器数据出现了越界情况
在代码中,ptSet⼀共只有1080个数据,⽽最开始的代码版本由于编写的问题,i最⼤可能出现超过1080的情况正是由于这个原因,导致代码在运⾏初始和运⾏阶段,必然由于遍历器超过数据实际长度
引发assert
解决⽅案
更改代码为
detectangle_step = 4;
detectangle_width = 30;
for (int i = 0 ; i < (1080 - detectangle_width)/detectangle_step; i++){
std::vector<Point2d>::const_iterator first1 = ptSet_original.begin() + i*detectangle_step;
std::vector<Point2d>::const_iterator last1  = ptSet_original.begin() + i*detectangle_step + detectangle_width;
std::vector<Point2d> ptSet(first1, last1);
fitLineRANSAC(ptSet, A, B, C, inliers);
...(省略)
}
成功!不再报错了

本文发布于:2024-09-23 14:31:05,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/4/359514.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:代码   出现   问题
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议