所以我尝试使用 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)
但它也没有奏效。你能发现我的错误吗?我在这上面坐了很长一段时间,所以非常感谢您的帮助!