以下是一个使用 golang 在一张图片中查找直线的例子:
package main
import (
"fmt"
"image"
"image/color"
"image/jpeg"
"math"
)
func findLines(img image.Image, threshold float64) []Line {
// Convert the image to grayscale
grayImg := image.NewGray(img.Bounds())
for x := 0; x < img.Bounds().Size().X; x++ {
for y := 0; y < img.Bounds().Size().Y; y++ {
r, g, b, _ := img.At(x, y).RGBA()
grayVal := float64(r)/65535.0*0.299 + float64(g)/65535.0*0.587 + float64(b)/65535.0*0.114
grayImg.SetGray(x, y, color.Gray{uint8(grayVal * 255)})
}
}
// Apply edge detection using Sobel filter
gx := [][]float64{{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}}
gy := [][]float64{{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}}
edges := make([][]float64, img.Bounds().Size().X)
for x := range edges {
edges[x] = make([]float64, img.Bounds().Size().Y)
for y := range edges[x] {
var sumx float64
var sumy float64
for i := -1; i <= 1; i++ {
for j := -1; j <= 1; j++ {
if (x+i >= 0 && x+i < img.Bounds().Size().X && y+j >= 0 && y+j < img.Bounds().Size().Y) {
grayVal := float64(grayImg.GrayAt(x+i, y+j).Y)
sumx += gx[i+1][j+1] * grayVal
sumy += gy[i+1][j+1] * grayVal
}
}
}
edges[x][y] = math.Sqrt(sumx*sumx + sumy*sumy)
}
}
// Apply Hough transform to detect lines
var maxDist int = int(math.Sqrt(float64(img.Bounds().Size().X*img.Bounds().Size().X + img.Bounds().Size().Y*img.Bounds().Size().Y)))
accum := make([][]int, 2*maxDist)
for i := range accum {
accum[i] = make([]int, 180)
}
for x := range edges {
for y := range edges[x] {
if (edges[x][y] > threshold) {
for theta := -89; theta <= 90; theta++ {
r := int((float64(x)*math.Cos(float64(theta)*math.Pi/180.0) +
float64(y)*math.Sin(float64(theta)*math.Pi/180.0)) / math.Sqrt2)
if (r >= -maxDist && r < maxDist) {
accum[r+maxDist][theta+89]++
}
}
}
}
}
// Find the lines with highest accumulation values
var lines []Line
for r := range accum {
for theta := range accum[r] {
if (accum[r][theta] > 100) { // Only consider lines with at least 100 votes
rho := float64(r-maxDist) * math.Sqrt2
angle := float64(theta-89) * math.Pi / 180.0
lines = append(lines, Line{rho, angle})
}
}
}
return lines
}
type Line struct {
Rho float64 // Distance from origin to line along the normal vector.
Angle float64 // Angle in radians between the x-axis and the normal vector.
}
func main() {
file, err := os.Open("input.jpg")
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
img, err := jpeg.Decode(file)
if err != nil {
fmt.Println(err)
return
}
lines := findLines(img, 10000)
for _, line := range lines {
fmt.Printf("Line with rho=%.2f and angle=%.2f degrees\n", line.Rho, line.Angle*180.0/math.Pi)
}
}
该代码实现了一个名为 findLines 的函数,该函数接受一张图片和阈值作为参数,并返回所有检测到的直线。该算法使用 Sobel 算子进行边缘检测,然后应用 Hough 变换来检测直线。
在 main 函数中,我们打开一个 JPEG 文件并将其解码成一张图片。然后调用 findLines 函数并打印出检测到的每条直线的参数(即距离和角度)。




