笛卡尔参数化直线霍夫变换 Hough Transform for lines with cartesian parameterisation
笛卡尔参数化直线霍夫变换 Hough Transform for lines with cartesian parameterisation
import numpy as np
from PIL import Image
import requests
from io import BytesIO
import itertools
from IPython.display import display
读取图片
首先,读取并显示图片。读取图片时,返回一个灰度图,每个灰度为 RGB 的均值
# Read an image returning an array with 1 component
def image_read_l(filename):input_image = Image.open(filename)width, height = input_image.sizeinput_array = np.array(input_image)output_array = np.zeros((height, width), dtype='uint8')# Combine pixel values, for each row and columnfor y in range(0, height):for x in range(0, width):rgb = input_array[y, x]output_array[y,x] = (int(rgb[0]) + int(rgb[1]) + int(rgb[2])) / 3return output_array, width, height# Show an array containing image data
def show_image_l(image):# Create output and showoutput_image = Image.fromarray(image, 'L')display(output_image)# output_image.show()
input_image, width, height = image_read_l("attachments/Road.png")
show_image_l(input_image)
print((width, height), input_image.shape)
(240, 196) (196, 240)
读取 Edge 图
读取对应的 Edge 图。该 Edge 图是由 Canny 边缘检测算法图生成的,具体参见 [[https://github.com/Nixon-Aguado/Feature-Extraction-and-Image-Processing-Book-Examples/blob/d6f4c45314b481705958ee336e83ce331926e894/ExamplesPython_3.6/Modules/ImageOperatorsUtilities.py#L78]]。
从本地读取 Edge 图
edges = Image.open("attachments/RoadEdges.png").convert('L')magnitude = np.array(edges)print(magnitude.shape)display(edges)
(196, 240)
从 URL 读取 Edge 图
# Read edges image
image_url = 'https://raw.githubusercontent.com/Nixon-Aguado/Feature-Extraction-and-Image-Processing-Book-Examples/refs/heads/master/Images/Chapter5/Input/RoadEdges.png'
response = requests.get(image_url)
edges = Image.open(BytesIO(response.content)).convert('L')
magnitude = np.array(edges)print(magnitude.shape)display(edges)
(196, 240)
Hough transform
Hough transform 的思路
我们可以将一条已知斜率和截距的直线表示为:
y=mx+c(1) y = mx + c \tag{1} y=mx+c(1)
其中
- 有 2 个参数,mmm 为斜率,ccc 为(y 轴上的)截距。
- yyy 和 xxx 是变量
同时,我们将所有经过点 (x,y)(x,y)(x,y) 的直线表示为
c=y−mx(2) c = y - mx \tag{2} c=y−mx(2)
其中
- 有 2 个参数,(x,y)(x,y)(x,y),表示一个点,所有直线都经过这个点
- mmm 和 ccc 是变量,表示所有经过点 (x,y)(x,y)(x,y) 的直线的斜率和截距
对于一个 Edge 图,Hough Transform 采用以下思路检测直线:
- 定义由斜率和截距组成的的参数空间:(m,c)(m,c)(m,c)。
- 生成离散化的 mmm 和 ccc
- 定义一个 Accumulator A(m,c)A(m,c)A(m,c)
- 遍历 Edge 图中的所有点,如果点在某个 mmm 和 ccc 定义的直线上,给该 mmm 和 ccc 计一张投票
- 寻找 Accumulator A(m,c)A(m,c)A(m,c) 的局部最大值
关于截距 ccc 的取值范围
对于经过图片某个点的 45∘45^\circ45∘ 和 −45∘-45^\circ−45∘ 的直线,其 y-intercept 如何取值?
回顾:
c=y−mxm=tanθ \begin{align*} c = y - mx \\ m = \tan \theta \end{align*} c=y−mxm=tanθ
对于一张宽为 www,高为 hhh 的图片,其 xxx 的取值范围为 [0,w−1][0, w-1][