我很震惊地找到了图像中大多数线条的交点

时间:2012-12-26 15:09:19

标签: c++ image-processing opencv

我使用标准霍夫变换来使用OpenCV获取图像中的直线。现在,我需要找到图像中大多数线的交点的x和y坐标。我的想法是将图像划分为几个8 * 8像素段(我尚未确定尺寸),然后在区域中搜索线条。但我不确定如何计算细分中的线条。我很震惊。所以我无法做的事情(使用openCV)是 1.将图像分成8 * 8像素段(我不知道是否有功能,如果不能,我该怎么办) 2.计算每个段中的行数。 任何阅读材料或代码提示都会非常有用。

3 个答案:

答案 0 :(得分:1)

检测交叉点的方法是完全错误的。有一个简单的数学公式。我在简单的C中给你一个示例代码:

// This is a point
typedef struct{
   int x,y;
} MYintPOINT;

// This is line
typedef struct {
    MYintPOINT  pStart;
    MYintPOINT  pEnd;
} MyLine;

#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 ) ) ) 

// Given 2 line segments, find their intersection point
// rerurns [Px,Py] point in 'res' or FALSE if parallel. Uses vector cross product technique.
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;
}

答案 1 :(得分:0)

我可以帮助您将图像分成8 * 8像素段。

OpenCV中的rowRange()colRange()函数对此非常有用。 (documentation here)以下是一个例子:

cv::Mat img = cv::imread("myImage.png");
cv::Mat region = img.rowRange(0,7).colRange(0,7);  //upper-left 8x8 image region

答案 2 :(得分:0)

请注意,由于噪音,大多数线条可能根本不会在某一点相交,除此之外,请尝试以下方法:

create black_image 
for each line
    create temporary_black_image
    draw a line to temporary_black_image, use cvScalar(1) as a color for the line
    cvAdd both temporary_black_image to black_image
apply cvSmooth to black_image
CvPoint minLoc; CvPoint maxLoc;
double minVal; double maxVal;
cvMinMaxLoc( black_image, &minVal, &maxVal, &minLoc, &maxLoc );

maxLoc->x and maxLoc-> y will be your estimate

您可以尝试通过改变cvSmooth函数

的参数来稍微调整结果