opencv+hough直线检测+fitline直线拟合

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

using namespace std;
using namespace cv;
 

/*函数功能:求两条直线交点*/
/*输入:两条Vec4i类型直线*/
/*返回:Point2f类型的点*/
Point2f getCrossPoint(Vec4i LineA, Vec4i LineB)
{
    double ka, kb;
    ka = (double)(LineA[3] - LineA[1]) / (double)(LineA[2] - LineA[0]); //求出LineA斜率
    kb = (double)(LineB[3] - LineB[1]) / (double)(LineB[2] - LineB[0]); //求出LineB斜率
    Point2f crossPoint;
    crossPoint.x = (ka*LineA[0] - LineA[1] - kb*LineB[0] + LineB[1]) / (ka - kb);
    crossPoint.y = (ka*kb*(LineA[0] - LineB[0]) + ka*LineB[1] - kb*LineA[1]) / (ka - kb);
    return crossPoint;
}

//函数功能,直线拟合
Vec4i fitline(vector<cv::Point> points)
{
    cv::Vec4f line_para;
    cv::fitLine(points, line_para, CV_DIST_HUBER, 0, 0.01, 0.01);
    cv::Point point0;
    point0.x = line_para[2];
    point0.y = line_para[3];
    double k = line_para[1] / line_para[0];
    /*cout << k << endl;*/
    //计算直线的端点(y = k(x - x0) + y0)
    /*vector<Point2f> Points;*/
    Vec4i temp;
    cv::Point point1, point2;
    if (k < 0)
    {
        point1.x = 0;
        point1.y = k * (0 - point0.x) + point0.y;
        point2.x = 640;
        point2.y = k * (640 - point0.x) + point0.y;
    }
    else 
    {
        point1.x = 500;
        point1.y = k * (500-point0.x) + point0.y;
        point2.x = 1400;
        point2.y = k * (1400- point0.x) + point0.y;
    }
    temp[0] = point1.x;
    temp[1] = point1.y;
    temp[2] = point2.x;
    temp[3] = point2.y;
    return temp;
}


void main()
{
    Mat img,grayimg,blurimg,dstimg;
    double vmin, vmax, alpha;
    img = imread("image4.jpg",1);
    cvtColor(img,grayimg,CV_BGR2GRAY);
    GaussianBlur(grayimg, blurimg, Size(3, 3), 0, 0);
    Canny(blurimg, dstimg, 100, 180, 3);
    minMaxLoc(img, &vmin, &vmax);
    alpha = (255.0 / (vmax - vmin))*0.8;
    img.convertTo(img, CV_8U, alpha, -vmin * alpha);
    Mat im_color;
    applyColorMap(img, im_color, COLORMAP_JET);
    int rho = 1;//距离分辨率
    vector<Vec4i>lines;//长度等于找到的线段数
    HoughLinesP(dstimg, lines, rho, CV_PI / 180, 40, 60, 10);//直线检测
    cout << "the detected lines numbers is: "<<lines.size() << endl;
    std::vector<cv::Point> pointsL;//
    std::vector<cv::Point> pointsR;
    cv::Mat image = cv::Mat::zeros(img.rows, img.cols, CV_8UC3);
    for (size_t i = 0; i < lines.size(); i++)
    {
        Vec4i I = lines[i];
        int dx = I[2] - I[0];
        int dy = I[3] - I[1];
        if (dy < 0)//dy>0取的是右边
        {
            pointsL.push_back(cv::Point(I[0], I[1]));
            pointsL.push_back(cv::Point(I[2], I[3]));
        }
        else
        {
            pointsR.push_back(cv::Point(I[0], I[1]));
            pointsR.push_back(cv::Point(I[2], I[3]));
        }
       line(img, Point(I[0], I[1]), Point(I[2], I[3]), Scalar(0, 0, 255), 2, CV_AA);
    }

    for (int i = 0; i < pointsL.size(); i++)
    {
        cv::circle(image, pointsL[i], 3, cv::Scalar(0, 0, 255), 2, 8, 0);
        cv::circle(image, pointsR[i], 3, cv::Scalar(0, 255, 255), 2, 8, 0);
    }
    Vec4i templ = fitline(pointsL);
    Vec4i tempr = fitline(pointsR);

    //cv::line(img, Point(templ[0], templ[1]), Point(templ[2], templ[3]), cv::Scalar(0, 255, 0), 2, 8, 0);
    //cv::line(img, Point(tempr[0], tempr[1]), Point(tempr[2], tempr[3]), cv::Scalar(0, 255, 255), 2, 8, 0);
    vector<Point2f> corners;//线的交点存储  
    cv::Point2f pt = getCrossPoint(templ, tempr);
    circle(im_color, pt, 3, Scalar(0, 0, 255), 2);
    cout << "(x,y): (" << pt.x << ","<< pt.y<<")" << endl;
    imshow("deteceted lines", dstimg);
    imshow("xxx",im_color);
    waitKey(0);
    system("pause");
}


 

猜你喜欢

转载自blog.csdn.net/qq_35699505/article/details/85294567