您的位置:首页 > 运维架构

opencv之7.4用直线拟合一组点

2017-10-23 22:55 302 查看
获取直线的位置和方向的精确估计,解决直线拟合的问题。

思想:

用HoughlinesP检测直线,将直线保存在lines中,获取Canny图像并获取lines与canny图相交的点集,再用点集拟合直线。

代码:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "LineFinder.h"
#define PI 3.141591653
using namespace std;
using namespace cv;

int main()
{
Mat image, result, result2;
image = imread("D:/round.jpg", 0);
namedWindow("image");
imshow("image", image);
Canny(image, result, 120, 200);
namedWindow("Canny");
imshow("Canny", result);
vector<Vec4f> li;       //若此处没有检查到直线则之后使用li会出错
HoughLinesP(result, li, 1, PI/180, 180, 100, 20);
vector<Vec4f>::iterator it = li.begin();
for (;it != li.end();++it)
{
Point ptr1((*it)[0], (*it)[1]);
Point ptr2((*it)[2], (*it)[3]);
line(image, ptr1, ptr2, Scalar(255));
}
namedWindow("HoughP");
imshow("HoughP", image);
int n = 0;
cv::line(image, cv::Point(li
[0], li
[1]), cv::Point(li
[2], li
[3]), cv::Scalar(255), 5);
cv::Mat oneline(image.size(), CV_8U, cv::Scalar(0));
cv::line(oneline, cv::Point(li
[0], li
[1]), cv::Point(li
[2], li
[3]), cv::Scalar(255), 5);
cv::bitwise_and(result, oneline, oneline);//按位与
cv::Mat onelineInv;
cv::threshold(oneline, onelineInv, 128, 255, cv::THRESH_BINARY_INV);//反转图像
cv::namedWindow("One line");
cv::imshow("One line", onelineInv);
vector<Point> points;
for (int y = 0;y < oneline.rows;y++)
{
uchar *ptr = oneline.ptr<uchar>(y);
for (int x = 0;x < oneline.cols;++x)
{
if (ptr[x])
{
points.push_back(Point(x, y));
}
}
}
Vec4f line;
fitLine(points, line, DIST_L2, 0, 0.01, 0.01);//寻找直线
int x0 = line[2];
int y0 = line[3];
int x1 = x0 - 200 * line[0];
int y1 = y0 - 200 * line[1];
image = imread("D:/round.jpg", 0);
cv::line(image, Point(x0, y0), Point(x1, y1), Scalar(255), 1);
namedWindow("imageline");
imshow("imageline", image);
waitKey(0);
return 0;
}


[/code]

void fitLine( InputArray points, OutputArray line, int distType, double param, double reps, double aeps );

参数详解:

第一个参数: 存储点序列

第二个参数: line中存储返回值

二维空间时: line[0–3] 分别为 (vx,vy, x0,y0)

其中 vx, vy 是正规化之后的斜率向量。 x0,y0 是直线经过的点。

第三,distType

拟合算法,其中 CV_DIST_L2 就是平常的最小二乘法

dist_type=CV_DIST_L2 (L2): ρ(r)=r2/2 (最简单和最快的最小二乘法)

dist_type=CV_DIST_L1 (L1): ρ(r)=r

dist_type=CV_DIST_L12 (L1-L2): ρ(r)=2•[sqrt(1+r2/2) - 1]

dist_type=CV_DIST_FAIR (Fair): ρ(r)=C2•[r/C - log(1 + r/C)], C=1.3998

dist_type=CV_DIST_WELSCH (Welsch): ρ(r)=C2/2•[1 - exp(-(r/C)2)], C=2.9846

dist_type=CV_DIST_HUBER (Huber): ρ(r)= r2/2, if r < C C•(r-C/2), otherwise; C=1.345

第四,第五参数第六参数:推荐值是 0, 0.01, 0.01, 三维空间时: line[0–5] 分别是 (vx, vy, vz,x0, y0,z0)

fitEllipse可以用来绘制椭圆。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: