提取霍夫线交点坐标并将数据获取到记事本或 Excel

Posted

技术标签:

【中文标题】提取霍夫线交点坐标并将数据获取到记事本或 Excel【英文标题】:Extracting Hough lines intersection coordinate and getting the data to Notepad or Excel 【发布时间】:2014-12-15 06:42:57 【问题描述】:

我需要帮助来获取 HoughLines 生成的线条的坐标并将其提取到输出文件(记事本、Excel 或任何其他输出文件)。

我设法获得了这些线条,根据我在这个网站上的研究,我找到了一篇说明如何获得坐标的帖子,但是由于我的理解有限,我无法让代码沿着我的原始 Hough 代码运行并获得交点坐标到输出文件上。

这是我原来的霍夫代码:

#pragma once
#include <C:\OpenCV2.2\include\opencv\cv.h>
#include <C:\OpenCV2.2\include\opencv\highgui.h>
#include <C:\OpenCV2.2\include\opencv2\core\core.hpp>
#include <C:\OpenCV2.2\include\opencv2\imgproc\imgproc.hpp>
#include <C:\OpenCV2.2\include\opencv2\highgui\highgui.hpp>

#include <stdio.h>
#include <math.h>

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main(int argc, char* argv[])



cv::Mat dst_img, gray_img, contour_img, contrast_img;
cv::Mat src_img = cv::imread("C:\\Frame-1.bmp"); //Source image path
dst_img = src_img.clone();
dst_img.convertTo(contrast_img, -1, 1.5, 0);
cv::cvtColor(contrast_img, gray_img, CV_BGR2GRAY);
cv::Canny(gray_img, contour_img, 75, 225, 3);

vector<Vec2f> lines_;

HoughLines(contour_img, lines_, 1, CV_PI/180, 200);

for( size_t i = 0; i < lines_.size(); i++ )

float rho = lines_[i][0];
float theta = lines_[i][1];

double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;

Point pt1(cvRound(x0 + 1000*(-b)),
    cvRound(y0 + 1000*(a)));
Point pt2(cvRound(x0 - 1000*(-b)),
    cvRound(y0 - 1000*(a)));

cv::clipLine(gray_img.size(), pt1, pt2);

if(!dst_img.empty())
    line( dst_img, pt1, pt2, Scalar(0, 0, 255), 1, CV_AA);

cv::imwrite("result.bmp", dst_img);


namedWindow("My Image");
imshow("My Image", dst_img);

waitKey(0);

return 0;


这里是我想放入原始代码的代码的链接:

I am struck at finding the point of intersection of most lines in an image

现在我的原始代码绘制 Houghlines 并导出图像(作为 result.bmp),同时在新窗口上显示图像。

我只需要弄清楚如何以及在何处将新代码加上一个附加代码以获取坐标的原始数据到像记事本这样的输出文件中,最好是与 result.bmp 相同的文件夹(名称输出文件可以是任何东西,只需要它在那里)。

对不起,如果这个问题听起来像是初学者的问题(我真的是),非常感谢任何帮助。非常感谢。

附加信息:我正在使用 OpenCV 2.2 和 Microsoft Visual Studio Academic 2010

编辑:这是所有三个代码(霍夫、坐标提取和将数据导出到记事本),但作为一个完整的初学者,我不知道如何让它们都在一个代码中工作。

#pragma once
#include <C:\OpenCV2.2\include\opencv\cv.h>
#include <C:\OpenCV2.2\include\opencv\highgui.h>
#include <C:\OpenCV2.2\include\opencv2\core\core.hpp>
#include <C:\OpenCV2.2\include\opencv2\imgproc\imgproc.hpp>
#include <C:\OpenCV2.2\include\opencv2\highgui\highgui.hpp>

#include <stdio.h>
#include <math.h>

#include <opencv2/opencv.hpp>
#include <iostream>

#define PointMinusPoint(P,Q,R)      (P).x = (Q).x - (R).x; (P).y = (Q).y - (R).y;
#define PointCross(P,Q)             (((P).x*(Q).y)-((P).y*(Q).x))
#define SIGN(X)             (((X)>=0)? 1:-1 )
#define ABS(a)              ((a) >= 0 ? (a) : (-(a)))
#define ROUND(a)            ((SIGN(a)) * ( ( int )( ABS(a) + 0.5 ) ) ) 

typedef struct
   int x,y;
 MYintPOINT;

typedef struct 
    MYintPOINT  pStart;
    MYintPOINT  pEnd;
 MyLine;

using namespace std;
using namespace cv;

int main(int argc, char* argv[])



cv::Mat dst_img, gray_img, contour_img, contrast_img;
cv::Mat src_img = cv::imread("C:\\Frame-1.bmp"); //Source image path
dst_img = src_img.clone();
dst_img.convertTo(contrast_img, -1, 1.5, 0);
cv::cvtColor(contrast_img, gray_img, CV_BGR2GRAY);
cv::Canny(gray_img, contour_img, 75, 225, 3);

vector<Vec2f> lines_;

HoughLines(contour_img, lines_, 1, CV_PI/180, 200);

for( size_t i = 0; i < lines_.size(); i++ )

float rho = lines_[i][0];
float theta = lines_[i][1];

double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;

Point pt1(cvRound(x0 + 1000*(-b)),
    cvRound(y0 + 1000*(a)));
Point pt2(cvRound(x0 - 1000*(-b)),
    cvRound(y0 - 1000*(a)));

cv::clipLine(gray_img.size(), pt1, pt2);

if(!dst_img.empty())
line( dst_img, pt1, pt2, Scalar(0, 0, 255), 1, CV_AA);

cv::imwrite("result.bmp", dst_img);


int findLinesIntersectionPoint(const MyLine*l1, const MyLine*l2, MYintPOINT *res)
    MYintPOINT  p  = l1->pStart;
    MYintPOINT  dp;
    MYintPOINT  q  = l2->pStart;
    MYintPOINT  dq;
    MYintPOINT  qmp;            // q-p
    int         dpdq_cross;     // 2 cross products
    int         qpdq_cross;     // dp with dq,  q-p with dq
    float       a;

PointMinusPoint(dp,l1->pEnd,l1->pStart);
PointMinusPoint(dq,l2->pEnd,l2->pStart);
PointMinusPoint(qmp,q,p);

dpdq_cross = PointCross(dp,dq);
if (!dpdq_cross)
    // Perpendicular Lines
    return 0;


qpdq_cross = PointCross(qmp,dq);
a = (qpdq_cross*1.0f/dpdq_cross);

res->x = ROUND(p.x+a*dp.x);
res->y = ROUND(p.y+a*dp.y);
return 1;


string FileName= FileName_S.c_str();
string::size_type Extension = FileName_S.find_last_of('.');                  // Find extension point

Mat mInputImg;
mInputImg= imread(FileName_S,1);
Size szInput= mInputImg.size();
const string DestinationFileName = FileName_S.substr(0, Extension) + "_ImageData.csv";   // Form the new name with container
ofstream myfile (DestinationFileName.c_str());
if (!myfile.is_open())

    MessageBox(L"Unable to Open File");

string Text= format("Row, Col , Pixel Data,\n");
myfile << Text;

for (int Row = 0; Row < szInput.height; Row++)

    for (int Col = 0; Col < szInput.width; Col++)
    
        string Text= format("%d , %d , %d",Row,Col,mInputImg.at<uchar>(Row,Col));
        myfile << Text;
        myfile << "\n";
    

myfile.close();

namedWindow("My Image");
imshow("My Image", dst_img);

waitKey(0);

return 0;


【问题讨论】:

【参考方案1】:

将数据导出到记事本或 Excel 文件非常容易。这是将垫子导出到 csv 文件的代码。使用您想要的数据格式化您的字符串以导出您想要的数据。

/*Exporting a Mat to Excel(.csv) file*/
    string FileName= FileName_S.c_str();
    string::size_type Extension = FileName_S.find_last_of('.');                  // Find extension point

    Mat mInputImg;
    mInputImg= imread(FileName_S,1);
    Size szInput= mInputImg.size();
    const string DestinationFileName = FileName_S.substr(0, Extension) + "_ImageData.csv";   // Form the new name with container
    ofstream myfile (DestinationFileName.c_str());
    if (!myfile.is_open())
    
        MessageBox(L"Unable to Open File");
    
    string Text= format("Row, Col , Pixel Data,\n");
    myfile << Text;

    for (int Row = 0; Row < szInput.height; Row++)
    
        for (int Col = 0; Col < szInput.width; Col++)
        
            string Text= format("%d , %d , %d",Row,Col,mInputImg.at<uchar>(Row,Col));
            myfile << Text;
            myfile << "\n";
        
    
    myfile.close();

【讨论】:

您好,感谢您的及时回复。但是我仍然不知道如何将上面的代码与 Houghline 代码和坐标提取代码链接起来。我希望这三个代码都在一个有凝聚力的代码中,但不幸的是我总是得到一个未定义的标识符错误。我知道将所有三个代码复制并粘贴在一起很愚蠢,但我需要它们一起工作。 你试过什么?它在哪里失败?你能告诉我们一些更新的代码吗? 我已经用我目前使用的最新源代码更新了我的问题。我知道定义名称和括号很可能是关闭的,但我不知道如何使它们一起工作(我没有定义哪些文件,我应该在哪里替换文件名等)任何帮助都非常感谢。 很抱歉对这个网站不太了解。我只是想让代码工作。如果我以任何方式冒犯了您,我真诚地道歉。 哈哈这不是冒犯!这是关于你自己尝试一点。你不能指望别人完成你的工作!所以以后你可以尽量避免这些!再次花时间修复您的代码!祝您编码愉快!

以上是关于提取霍夫线交点坐标并将数据获取到记事本或 Excel的主要内容,如果未能解决你的问题,请参考以下文章

Excel折线图或散点折线图线与坐标轴的交点坐标?

霍夫变换理解

用Hough变换检测矩形

从霍夫线中选择线

opencv —— HoughLinesHoughLinesP 霍夫线变换(标准霍夫线变换多尺度霍夫线变换累积概率霍夫线变换)

霍夫变换直线检测