OpenCV概率霍夫线变换在C ++和Python中给出不同的结果吗?

问题描述

我当时正在使用OpenCV(Python)在一个项目的某些部分中使用概率霍夫线变换函数houghlinesp”的项目。我的代码工作得很好,没有问题。然后我想到了将相同的代码转换为C ++。

代码转换为C ++后,输出与Python代码不同。经过长时间的调试,我发现其他所有东西都可以正常工作,但是在C ++的情况下,“ houghlinesp函数给出的输出不同。两种语言对该函数的输入相同,参数的值也相同,但输出不同。

有人可以向我解释为什么会发生这种情况以及对此进行任何可能的修复吗?

此外,我已经检查了两种语言的OpenCV版本,并且相同: 4.5.0 dev 另外,我尝试使用传递给C ++代码的值,但无法获得相似的结果。

输入边缘图像:

Input Edge Image

Python houghlinesp()输出

Python HoughLinesP() output

C ++ houghlinesp()输出

C++ HoughLinesP() output

以下是每种语言的代码: Python:

Lines = cv2.houghlinesp(EdgeImage,1,np.pi / 180,50,10,15)

C ++:

std::vector<cv::Vec4i> Lines;
cv::houghlinesp(EdgeImage,Lines,CV_PI / 180,15);

如果有人可以提出建议,那将是一个很大的帮助。

解决方法

说明和修复

出现问题是因为在Python版本中,您没有设置您认为正在设置的参数。与在Python接口中为其调整参数列表的其他某些函数相反,HoughLinesP不仅返回行,而且仍将参数lines用于行输出。您可以在HoughLinesP的帮助中看到它:

import cv2
help(cv2.HoughLinesP)

为您提供(省略号):

Help on built-in function HoughLinesP:

HoughLinesP(...)
    HoughLinesP(image,rho,theta,threshold[,lines[,minLineLength[,maxLineGap]]]) -> lines
    .   @brief Finds line segments in a binary image using the probabilistic Hough transform.
    .   
...
    .   @param lines Output vector of lines. Each line is represented by a 4-element vector
    .   \f$(x_1,y_1,x_2,y_2)\f$,where \f$(x_1,y_1)\f$ and \f$(x_2,y_2)\f$ are the ending points of each detected
    .   line segment.
...

因此,基本上,在您的python示例中,您将10传递为lines而不是minLineLength。要解决此问题,您可以将空数组作为lines传递,也可以将参数作为关键字参数传递:

Lines = cv2.HoughLinesP(EdgeImage,rho=1,theta=np.pi/180,threshold=50,minLineLength=10,maxLineGap=15)

这样做应该使您的Python版本的输出与C ++版本的输出匹配。

或者,如果您对Python版本的结果感到满意,则必须省略参数lines(即,仅将minLineLength设置为15,将{{1}使用默认值0 } [see docs])

maxLineGap

然后应该复制您的Python版本。

示例

使用openCV documentation of HoughLinesP中列出的示例,您可以看到它解决了该问题。

C ++版本

(取自上面列出的openCV文档,改成保存图像。)

std::vector<cv::Vec4i> Lines;
cv::HoughLinesP(EdgeImage,Lines,1,CV_PI / 180,50,15);

如果将其编译并在文档中提供的示例图片上运行,则会得到以下结果:

C++ result

错误的Python版本

(基本上,只是翻译后的C ++版本,没有lines参数。)

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
int main(int argc,char** argv)
{
    Mat src,dst,color_dst;
    if( argc != 3 || !(src=imread(argv[1],0)).data)
        return -1;
    Canny( src,200,3 );
    cvtColor( dst,color_dst,COLOR_GRAY2BGR );
    vector<Vec4i> lines;
    HoughLinesP( dst,lines,CV_PI/180,80,30,10 );
    for( size_t i = 0; i < lines.size(); i++ )
    {
        line( color_dst,Point(lines[i][0],lines[i][1]),Point( lines[i][2],lines[i][3]),Scalar(0,255),3,8 );
    }
    imwrite( argv[2],color_dst );
    return 0;
}

运行此命令可获得以下(不同的)结果:

Wrong Python result

更正的python版本

(通过传递关键字args代替)

import argparse
import cv2
import numpy as np

parser = argparse.ArgumentParser()
parser.add_argument("input_file",type=str)
parser.add_argument("output_file",type=str)
args = parser.parse_args()

src = cv2.imread(args.input_file,0)
dst = cv2.Canny(src,50.,200.,3)
color_dst = cv2.cvtColor(dst,cv2.COLOR_GRAY2BGR)
lines = cv2.HoughLinesP(dst,1.,np.pi/180.,10.)
for this_line in lines:
    cv2.line(color_dst,(this_line[0][0],this_line[0][1]),(this_line[0][2],this_line[0][3]),[0,255],8)
cv2.imwrite(args.output_file,color_dst)

这将给出正确的结果(即与C ++版本相同的结果):

Fixed Python result

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...