OpenCV_(Fit Line with points)用直线拟合一组点

来源:互联网 发布:万艾可用多少毫克 知乎 编辑:程序博客网 时间:2024/04/28 18:28



 // 5. 用直线拟合一组点------------------------------------------------------cv::Mat image = cv::imread("../../aTestImage/road2.jpg", 0);//Buildingcv::Mat contours;//阈值1:确定应该包含所有认为是属于明显图像轮廓的边缘像素//阈值2:定义属于所有重要边缘,剔除异常值(不连续边缘点)//磁滞阈值化cv::Canny(image, contours, 125, 350);//主体为白色cv::namedWindow("contours", 1);cv::imshow("contours", contours);LinesFinder  finder;finder.setLineLengthAndGap(100, 20);finder.setMinVote(80);//cv::Vec4i : (x0,y0, x1,y1)std::vector<cv::Vec4i> lines = finder.findLines(contours);int n = 1;//选择contours中的一条线: 如第2条cv::Mat oneline(contours.size(), CV_8U, cv::Scalar(0));cv::line(oneline, cv::Point(lines[n][0], lines[n][1]),cv::Point(lines[n][2], lines[n][3]), cv::Scalar(255), 10);cv::bitwise_and(contours, oneline, oneline);// 跟轮廓contours作 与 运算cv::namedWindow("oneline", 1);cv::imshow("oneline", oneline);//将oneline中的点放入到cv::points集合中std::vector<cv::Point> points;for (int y = 0; y < oneline.rows; y++){uchar *rowPtr = oneline.ptr<uchar>(y);for (int x = 0; x < oneline.cols; x++){if (rowPtr[x]){points.push_back(cv::Point(x, y));}}}//使用cv::fitline函数 将点数组 拟合成直线cv::Vec4f line;  //(cos, sin, x0,y0)cv::fitLine(cv::Mat(points), line, CV_DIST_L2, 0, 0.01, 0.01);std::cout << "line: (" << line[0] << "," << line[1] << ")(" << line[2] << "," << line[3] << ")\n";
int x0 = line[2];int y0 = line[3];int x1 = x0 - 200 * line[0];int y1 = y0 - 200 * line[1];//在图像image上标记出该直线 设定长度100,颜色黑,宽度3cv::line(image, cv::Point(x0, y0), cv::Point(x1, y1), cv::Scalar(0), 3);cv::namedWindow("imageL", 1);cv::imshow("imageL", image);cv::waitKey(0);return 0;

linesFinder类 .h:

#pragma once#include <opencv2\core\core.hpp>#include <opencv2\highgui\highgui.hpp>#include <opencv2\imgproc\imgproc.hpp>#include <iostream>#define  PI 3.1415926class LinesFinder{public:LinesFinder() :deltaRho(1), deltaTheta(PI / 180),minVote(10),minLength(0.),maxGap(0.) {}  //初始化~LinesFinder();//设置累加器的分辨率void setAccResolution(double dRho, double dTheta){deltaRho = dRho;deltaTheta = dTheta;}//设置最小投票数void setMinVote(int minv){minVote = minv;}//设置缺口及长度void setLineLengthAndGap(double length, double gap){minLength = length;maxGap = gap;}//使用概率霍夫变换std::vector<cv::Vec4i> findLines(cv::Mat &binary);//绘制线段void drawDetectLines(cv::Mat &image, cv::Scalar color = cv::Scalar(255, 255, 255));private:cv::Mat img;std::vector<cv::Vec4i> lines; //向量中包含检查到直线的端点double deltaRho; //半径double deltaTheta;// 与垂直线之间的角度int minVote; //最小投票数double minLength; // 线段最小长度double maxGap; //沿直线方向最大缺口};


linesFinder类 .cpp:
#include "stdafx.h"#include "LinesFinder.h"//LinesFinder::LinesFinder()//{//}LinesFinder::~LinesFinder(){}std::vector<cv::Vec4i> LinesFinder::findLines(cv::Mat & binary){lines.clear();cv::HoughLinesP(binary, lines, deltaRho, deltaTheta, minVote, minLength, maxGap);return lines;}void LinesFinder::drawDetectLines(cv::Mat & image, cv::Scalar color){std::vector<cv::Vec4i>::const_iterator it2 = lines.begin();while (it2 != lines.end()){cv::Point pt1((*it2)[0], (*it2)[1]);cv::Point pt2((*it2)[2], (*it2)[3]);cv::line(image, pt1, pt2, color);++it2;}}



0 0
原创粉丝点击