OpenCV+python:HoughLines累加器访问自3.4.2

2024-05-15 01:03:08 发布

您现在位置:Python中文网/ 问答频道 /正文

在opencv3.4.2中,添加了为HoughLines()返回的每一行返回投票数(累加器值)的选项。在python中,这似乎得到了支持,而且在OpenCV安装的python docstring中也可以看到:

"Each line is represented by a 2 or 3 element vector (ρ, θ) or (ρ, θ, votes) ."

它也包含在docs中(带有一些中断的格式)。 然而,我无法在python中返回3元素选项(ρθ投票 下面是演示问题的代码:

import numpy as np
import cv2
print('OpenCV should be at least 3.4.2 to test: ', cv2.__version__)
image = np.eye(10, dtype='uint8')
lines = cv2.HoughLines(image, 1, np.pi/180, 5)
print('(number of lines, 1, output vector dimension): ', lines.shape)
print(lines)

输出

^{pr2}$

所需的行为是一个额外的列,其中包含每行收到的投票数。对于投票值,可以应用比标准阈值更高级的选项,因此经常在SE(herehereherehere)上请求和询问,有时与HoughCircles()等效。然而,这些问题和答案(如修改源代码和重新编译)都是在它正式添加之前提出的,因此不适用于当前的情况。在


Tags: orimageimporthere选项np投票cv2
1条回答
网友
1楼 · 发布于 2024-05-15 01:03:08

从vanilla opencv3.4.3开始,您不能使用Python中的这个功能。在

< H1>如何在C++ +/H1中工作

首先在implementation of ^{}中,我们可以看到选择输出数组lines类型的代码:

int type = CV_32FC2;
if (lines.fixedType())
{
    type = lines.type();
    CV_CheckType(type, type == CV_32FC2 || type == CV_32FC3, "Wrong type of output lines");
}

当填充lines时,我们可以看到在implementation of ^{}中使用的这个参数:

^{pr2}$

可以看到类似的代码in ^{}。在

基于此,我们需要传入一个固定类型的_OutputArray,并在3个通道中存储32位浮点。如何使一个固定类型(但不是固定大小,因为算法需要能够调整大小)_OutputArray?让我们再看看implementation

  • 泛型cv::Mat不是固定类型,也不是{}
  • {cd10>选项^
  • 另一个选项是cv::Mat3f(即cv::Matx<_Tp, m, n>

样本代码:

#include <opencv2/opencv.hpp>

int main()
{
    cv::Mat image(cv::Mat::eye(10, 10, CV_8UC1) * 255);

    cv::Mat2f lines2;
    cv::HoughLines(image, lines2, 1, CV_PI / 180, 4); // runs the actual detection
    std::cout << lines2 << "\n";

    cv::Mat3f lines3;;
    cv::HoughLines(image, lines3, 1, CV_PI / 180, 4); // runs the actual detection
    std::cout << lines3 << "\n";

    return 0;
}

控制台输出:

[0, 2.3212879;
 1, 2.2340214;
 -1, 2.4609141]
[0, 2.3212879, 10;
 1, 2.2340214, 6;
 -1, 2.4609141, 6]

Python包装器的工作原理

让我们看看包装HoughLines函数的自动生成代码:

static PyObject* pyopencv_cv_HoughLines(PyObject* , PyObject* args, PyObject* kw)
{
    using namespace cv;

    {
    PyObject* pyobj_image = NULL;
    Mat image;
    PyObject* pyobj_lines = NULL;
    Mat lines;
    double rho=0;
    double theta=0;
    int threshold=0;
    double srn=0;
    double stn=0;
    double min_theta=0;
    double max_theta=CV_PI;

    const char* keywords[] = { "image", "rho", "theta", "threshold", "lines", "srn", "stn", "min_theta", "max_theta", NULL };
    if( PyArg_ParseTupleAndKeywords(args, kw, "Oddi|Odddd:HoughLines", (char**)keywords, &pyobj_image, &rho, &theta, &threshold, &pyobj_lines, &srn, &stn, &min_theta, &max_theta) &&
        pyopencv_to(pyobj_image, image, ArgInfo("image", 0)) &&
        pyopencv_to(pyobj_lines, lines, ArgInfo("lines", 1)) )
    {
        ERRWRAP2(cv::HoughLines(image, lines, rho, theta, threshold, srn, stn, min_theta, max_theta));
        return pyopencv_from(lines);
    }
    }
    PyErr_Clear();

    // Similar snippet handling UMat...

    return NULL;
}

总结一下,它尝试将在lines参数中传递的对象转换为cv::Mat,然后调用cv::HoughLines,并将{}作为输出参数。(如果这失败了,那么它将对cv::UMat进行相同的尝试)不幸的是,这意味着没有办法给cv::HoughLines一个固定类型{},因此从3.4.3起,Python无法访问此功能。在


解决方案

据我所知,唯一的解决方案是修改OpenCV源代码并重新构建。在

快速破解

这很简单,编辑implementation of ^{}并将默认类型改为CV_32FC3

int type = CV_32FC3;

然而,这意味着您将始终获得投票权(这也意味着OpenCL优化(如果存在的话)将不会被使用)。在

更好的补丁

添加一个可选的布尔参数return_votes,默认值为false。修改代码,使return_votestrue,则{}强制为{}。在

Header

CV_EXPORTS_W void HoughLines( InputArray image, OutputArray lines,
                              double rho, double theta, int threshold,
                              double srn = 0, double stn = 0,
                              double min_theta = 0, double max_theta = CV_PI,
                              bool return_votes = false );

Implementation

void HoughLines( InputArray _image, OutputArray lines,
                 double rho, double theta, int threshold,
                 double srn, double stn, double min_theta, double max_theta,
                 bool return_votes )
{
    CV_INSTRUMENT_REGION()

    int type = CV_32FC2;
    if (return_votes)
    {
         type = CV_32FC3;
    }
    else if (lines.fixedType())
    {
        type = lines.type();
        CV_CheckType(type, type == CV_32FC2 || type == CV_32FC3, "Wrong type of output lines");
    }
    // the rest...

相关问题 更多 >

    热门问题