1

所以我尝试使用 python 和 c++ 实现霍夫变换(使用 Pybind11 进行两种语言之间的接口)。当我绘制霍夫空间时,它似乎没问题,但我无法从投票矩阵的最大值中得到一条线。这是 C++ 代码(在我使用 PyBind11 之前看起来有点不同):

py::array_t<int> houghTransform(py::array_t<int> image, int angleStep, int angleAmount) {
    auto imageBuf = image.mutable_unchecked<3>();
    int height = imageBuf.shape(0);
    int width = imageBuf.shape(1);

    py::array_t<int> edgeMatrix = edgeDetect(imageBuf, height, width);
    auto edgeMatrixBuf = edgeMatrix.mutable_unchecked<2>();

    int distanceAxis = 2 * sqrt(pow((float) height, 2.0) + pow((float) width, 2.0));
    int angleAxis = angleAmount;
    
    int angleDim = (int) angleAxis / angleStep;
    int distanceDim = (int) distanceAxis / 2;

    py::array_t<int> votingMatrix = py::array_t<int>({distanceAxis, angleDim});
    auto votingMatrixBuf = votingMatrix.mutable_unchecked<2>();

    // fill voting matrices with zeros
    for(int i=0; i<distanceDim; i++) {
        for(int j=0; j<angleDim; j++) {
            votingMatrixBuf(i, j) = 0;
        }
    }

    // vote
    for(int x=0; x<edgeMatrixBuf.shape(0); x++) {
        for(int y=0; y<edgeMatrixBuf.shape(1); y++) {
            if(edgeMatrixBuf(x, y) == 1) {

                int counter = 0;
                float theta;
                float ro;

                for(int thetaIdx=0; thetaIdx<=angleAxis; thetaIdx++) {
                    if(thetaIdx % angleStep == 0) {
                        counter++;
                        theta = (float) (thetaIdx) * (M_PI / 180);
                        ro = distanceDim + std::round((x * cos(theta)) + (y * sin(theta)));
                        votingMatrixBuf(ro, counter) += 1;
                    }
                }

            }
        }
    }

    return votingMatrix;
}

如您所见,函数的参数是图像矩阵,我将其转换为边缘为 1 其余为 0 的矩阵,所以我得到了我感兴趣的像素。 int angleAmount是我想尝试的角度范围int angleStep以及我真正想要使用的θ角的多少(例如,每隔一秒跳过一次θ)。但是对于这个例子,我将使用 angleAmount = 360 和 angleStep = 1。所以我将使用从 1 到 360 的所有角度。

这是python代码:


from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import time

from houghTransform import houghTransform


def apply_hough_transform(image_path: str=""):
    image = np.array(Image.open(image_path))
    lines = houghTransform(image, 1, 360)

    p = np.unravel_index(lines.argmax(), lines.shape)
    
    max_distance = 2 * np.sqrt(pow(image.shape[0], 2) + pow(image.shape[1], 2))

    ro = p[0] - (max_distance / 2)
    theta = p[1] * (np.pi / 180)

    a = np.cos(theta)
    b = np.sin(theta)
    x = a * ro
    y = b * ro

    pt1 = (int(x + 1000*(-b)), int(y + 1000*(a)))
    pt2 = (int(x - 1000*(-b)), int(y - 1000*(a)))
    
    fig, axs = plt.subplots(2)

    axs[0].matshow(lines)
    axs[0].scatter(p[1], p[0], facecolors="none", edgecolors="r")

    axs[1].plot([pt1[0], pt2[0]], [pt1[1], pt2[1]])
    axs[1].imshow(image)
    plt.show()

apply_hough_transform(image_path="images/black_line.png")

该函数houghTransform与我使用 PyBind11 导出到 Python 的 c++ 代码中的函数相同。以下是图片: 在此处输入图像描述

我还尝试使用此函数创建行:

def line(x):
    return -(1 / np.arctan(theta)) * (x - ro * np.cos(theta)) + ro * np.sin(theta)

但它也没有奏效。你能发现我的错误吗?我在这上面坐了很长一段时间,所以非常感谢您的帮助!

4

0 回答 0