opencv3找直线并求任意两条直线交点

opencv3找直线并求任意两条直线交点,并显示出来,是直线交点,因为我把线段延长了。

求交点函数

/*函数功能:求两条直线交点*/
/*输入:两条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;
}

效果图:

这里写图片描述

整体代码


#pragma warning(disable:4996)

#include <stdio.h>  
#include <time.h>  
#include <math.h>  
#include <iostream> 
#include <io.h>
#include "windows.h"  
#include "fstream" 

//opencv相关
#include <opencv2/opencv.hpp>  
#include <opencv2/video.hpp>
#include <opencv2/imgproc/imgproc.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <opencv/cv.h>  
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <opencv2/ml/ml.hpp>  
#include <opencv2/objdetect/objdetect.hpp>//hog特征的c文件

//自己编写的文件
#include "UART.h"
#include "findline.h"
#include "DrawImage.h"//绘制图形
#include "Manipulator_positioning.h" //棋子挡板识别及定位
#include "Number.h"
#include "Locate.h"

using namespace std;
using namespace cv;
using namespace cv::ml;

RNG rng(12345);

using namespace cv;
using namespace std;

RNG g_rng(12345);

/*函数功能:求两条直线交点*/
/*输入:两条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;
}



//-----------------------------------【main( )函数】--------------------------------------------
//      描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main()
{   //【1】载入原始图和Mat变量定义   
    Mat srcImage = imread("11.jpg");  //工程目录下应该有一张名为1.jpg的素材图
    Mat midImage, dstImage;//临时变量和目标图的定义

    //彩色转灰度
    cv::cvtColor(srcImage, srcImage, CV_BGR2GRAY);
    cv::namedWindow("灰度化", 0);
    imshow("灰度化", srcImage);
    //模糊
    cv::blur(srcImage, srcImage, cv::Size(3, 3));
    cv::namedWindow("模糊", 0);
    imshow("模糊", srcImage);
    //【2】进行边缘检测和转化为灰度图
    Canny(srcImage, midImage, 50, 200, 3);//进行一此canny边缘检测
    cvtColor(midImage, dstImage, COLOR_GRAY2BGR);//转化边缘检测后的图为灰度图

    //【3】进行霍夫线变换
    vector<Vec4i> lines;//定义一个矢量结构lines用于存放得到的线段矢量集合
    HoughLinesP(midImage, lines, 1, CV_PI / 180, 320, 240, 30);

    printf("\n\n\t\t\t   当前使用的OpenCV版本为:\n" CV_VERSION);
    cout << "共检测到原始直线" << lines.size() << "条" << endl;

    //这里是将检测的线调整到延长至全屏,即射线的效果,其实可以不必这么做 
    for (unsigned int i = 0; i<lines.size(); i++)
    {
        cv::Vec4i v = lines[i];
        lines[i][0] = 0;
        lines[i][1] = ((float)v[1] - v[3]) / (v[0] - v[2])* -v[0] + v[1];
        lines[i][2] = midImage.cols;
        lines[i][3] = ((float)v[1] - v[3]) / (v[0] - v[2])*(midImage.cols - v[2]) + v[3];
    }

    //【4】依次在图中绘制出每条线段
    for (size_t i = 0; i < lines.size(); i++)
    {
        Vec4i l = lines[i];
        //此句代码的OpenCV2版为:
        //line( dstImage, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(186,88,255), 1, CV_AA);
        //此句代码的OpenCV3版为:
        line(dstImage, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 1, LINE_AA);
    }
    vector<Point2f> corners;//线的交点存储  
    for (unsigned int i = 0; i<lines.size(); i++)
    {
        for (unsigned int j = i + 1; j<lines.size(); j++)
        {
            cv::Point2f pt = getCrossPoint(lines[i], lines[j]);
            if (pt.x >= 0 && pt.y >= 0)
            {
                corners.push_back(pt);
            }
        }
    }
    //【4】依次在图中绘制出角点
    for (size_t i = 0; i < corners.size(); i++)
    {
        circle(dstImage, corners[i], 3, CV_RGB(0, 255, 0), 2);


    }






    //【5】显示原始图  
    namedWindow("【原始图】", 0);//参数为零,则可以自由拖动
    imshow("【原始图】", srcImage);

    //【6】边缘检测后的图 
    namedWindow("【边缘检测后的图】", 0);//参数为零,则可以自由拖动
    imshow("【边缘检测后的图】", midImage);

    //【7】显示效果图  
    namedWindow("【效果图】", 0);//参数为零,则可以自由拖动
    imshow("【效果图】", dstImage);

    waitKey(0);





}

猜你喜欢

转载自blog.csdn.net/mao_hui_fei/article/details/80977137