OpenCV 直线拟合及应用

OpenCV提供了7种(-1为用户定义)直线拟合方法,如下:

CV_DIST_USER    =-1,  /* User defined distance */
CV_DIST_L1      =1,   /* distance = |x1-x2| + |y1-y2| */
CV_DIST_L2      =2,   /* the simple euclidean distance */
CV_DIST_C       =3,   /* distance = max(|x1-x2|,|y1-y2|) */
CV_DIST_L12     =4,   /* L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1)) */
CV_DIST_FAIR    =5,   /* distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998 */
CV_DIST_WELSCH  =6,   /* distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846 */
CV_DIST_HUBER   =7    /* distance = |x|<c ? x^2/2 : c(|x|-c/2), c=1.345 */

OpenCV直线拟合函数:

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

points为2D的点: distType即为上面提到的算法; param 是 上述公式中的常数C。如果取 0,则程序自动选取合适的值; reps 表示直线到原点距离的精度,建议取 0.01; aeps 表示直线角度的精度,建议取 0.01; 拟合结果即为函数的输出 line,为Vec4f类型,line[0]、line[1] 存放的是直线的方向向量。line[2]、line[3] 存放的是直线上一个点的坐标。 所以 ,直线的斜率即为:line[1]/line[0]。

直线拟合的应用:

#include <iostream>  
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <opencv2/opencv.hpp>  

#define  PI 3.141592653

using namespace cv;  
using namespace std;  

int main()
{   
    Mat SrcImage, thresholdImage,grayImage;
    SrcImage = imread("2.jpg");
    cvtColor(SrcImage,grayImage,CV_BGR2GRAY);
    threshold(grayImage,thresholdImage, 0, 255, CV_THRESH_OTSU+CV_THRESH_BINARY);
    imshow("threshold",thresholdImage);
    vector<Point2f> onefitlinepoints,twofitlinepoints;
   //从上自下选择点
    for (int i =SrcImage.cols/2-SrcImage.cols/5;i<SrcImage.cols/2+SrcImage.cols/5;i++)
     { for (int j=0;j<SrcImage.rows-1;j++)
        {if ((int)thresholdImage.at<uchar>(j,i)==255)
            {  circle(thresholdImage,Point(i,j),2,Scalar(0,255,0));
                onefitlinepoints.push_back(Point(i,j));
                break; 
             }}}
             //从下自上选择点
     for (int k =SrcImage.cols/2-SrcImage.cols/5;k<SrcImage.cols/2+SrcImage.cols/5;k++)
      {  for (int l=SrcImage.rows-1;l>0;l--)
         {if ((int)thresholdImage.at<uchar>(l,k)==255)
            { circle(thresholdImage,Point(k,l),2,Scalar(0,255,0));
               twofitlinepoints.push_back(Point(k,l));
               break; 
             }}}
         //计算第一次拟合角度
     Vec4f oneline;
     fitLine(onefitlinepoints, oneline, CV_DIST_L1, 0, 0.01, 0.01);
     cout<<oneline[0]<<endl;
     cout<<oneline[1]<<endl;
    //求角度
     double  onefitlineradian =  atan(oneline[1]/oneline[0]);
     double  onefitlineangle = (onefitlineradian*180)/CV_PI;
     cout<<"直线拟合角度="<<onefitlineangle<<endl;

    //计算第二次拟合角度
    Vec4f twoline;
    fitLine(twofitlinepoints, twoline, CV_DIST_L1, 0, 0.01, 0.01);
    cout<<twoline[0]<<endl;
    cout<<twoline[1]<<endl;
    //求角度
    double  twofitlineradian =  atan(twoline[1]/twoline[0]);
    double  twofitlineangle = (twofitlineradian*180)/CV_PI;
    cout<<"直线拟合角度="<<twofitlineangle<<endl;

    double averagefitlineangle = (onefitlineangle+twofitlineangle)/2;
    cout<<"直线拟合平均角度="<<averagefitlineangle<<endl;

    //画出直线
    Point2f point1,point2,point3;
    point2.x = oneline[2];
    point2.y = oneline[3];

    point1.x = 0;
    point1.y = oneline[1]*(point1.x-oneline[2])/oneline[0]+oneline[3];

    point3.x = SrcImage.cols;
    point3.y = oneline[1]*(point3.x-oneline[2])/oneline[0]+oneline[3];

    line(SrcImage,point1,point3,Scalar(0,0,255));

    imshow("直线拟合",SrcImage);
    waitKey(0);
    getchar();
    return 0;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏贾志刚-OpenCV学堂

OpenCV实现人脸对齐

OpenCV实现人脸对齐 一:人脸对齐介绍 在人脸识别中有一个重要的预处理步骤-人脸对齐,该操作可以大幅度提高人脸识别的准确率与稳定性,但是早期的OpenCV版...

6724
来自专栏斜述视角

自然语言处理 | 隐马尔可夫模型(1)

马尔可夫链(Markov chain),又称离散时间马尔可夫链,因俄国数学家安德烈·马尔可夫得名,为状态空间中经过从一个状态到另一个状态转换的随机过程。该过程要...

1044
来自专栏Java与Android技术栈

二值图像分析:案例实战(文本分离+硬币计数)

在实际应用中,很多图像的分析最终都转换为二值图像的分析,比如:医学图像分析、前景检测、字符识别,形状识别。二值化+数学形态学能解决很多计算机识别工程中目标提取的...

1183
来自专栏yl 成长笔记

opencv 视觉项目学习笔记(二): 基于 svm 和 knn 车牌识别

    训练数据: 所有训练数据存储再一个 N x M 的矩阵中, 其中 N 为样本数, M 为特征数(每个样本是该训练矩阵中的一行)。这些数据  所有数据存在...

4132
来自专栏听雨堂

地理坐标系与投影坐标系的区别

1、首先理解地理坐标系(Geographic coordinate system),Geographic coordinate system直译为 地理坐标...

1826
来自专栏专知

【ACM MM论文集】国际多媒体顶级会议ACM Multimedia 2017 Open Access Repository

点击上方“专知”关注获取更多AI知识! 【导读】第25届ACM国际多媒体会议(ACM International Conference on Multimedi...

4065
来自专栏专知

【论文推荐】最新六篇序列推荐相关论文—卷积序列嵌入学习、用户记忆网络、上下文GRU、迁移学习

【导读】专知内容组整理了最近五篇序列推荐(Sequential Recommendation)相关文章,为大家进行介绍,欢迎查看! 1. Personalize...

5665
来自专栏CreateAMind

tensorpack

See some examples to learn about the framework:

1592
来自专栏专知

【论文推荐】最新六篇命名实体识别相关论文—跨专业医学、阿拉伯命名实体、中国临床、深度多任务学习、多模态、图卷积网络

2332
来自专栏专知

【紫冬分享】文章想投哪里?这里有2019年AI最全会议信息!

今天小编与大家分享的是2019年与AI相关最齐全的会议信息,涵盖控制、机器人、模式识别、机器学习、人工智能、计算机视觉等领域,共计136个学术会议。部分会议已经...

3373

扫码关注云+社区