您的位置:首页 > 运维架构

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

2017-03-16 18:28 936 查看




// 5. 用直线拟合一组点------------------------------------------------------

cv::Mat image = cv::imread("../../aTestImage/road2.jpg", 0);//Building
cv::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
[0], lines
[1]),
cv::Point(lines
[2], lines
[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,颜色黑,宽度3
cv::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.1415926
class 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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  图像识别 opencv