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);
}