ZBLOG

使用golang写一个在一张图片中查找直线的例子

以下是一个使用 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 函数并打印出检测到的每条直线的参数(即距离和角度)。

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=4149

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?