gocv是opencv的封装,gocv是儿子,opencv是爸爸
比如在Mat结构体中,只有c.Mat属性,看不见其它属性
所以儿子有事,得去找爸爸
原图
处理后的图片
代码
package main
import (
"fmt"
"image"
"image/color"
"log"
"gocv.io/x/gocv"
)
// 绘制角点
func main() {
src := gocv.IMRead("img/terrain.png", -1)
if src.Empty() {
log.Fatalln("图片不存在...")
}
srcW := gocv.NewWindow("src")
defer srcW.Close()
srcW.IMShow(src)
//转灰度图
gray := gocv.NewMat()
gocv.CvtColor(src, &gray, gocv.ColorRGBToGray)
dstW := gocv.NewWindow("dst")
defer dstW.Close()
dstW.IMShow(gray)
//二值化
edges := gocv.NewMat()
gocv.Canny(gray, &edges, 200, 250) //后面这两个数值调节很重要,数值大可以去除长轮廓
edgesW := gocv.NewWindow("edges")
defer edgesW.Close()
edgesW.IMShow(edges)
//高斯模糊 去除噪点
gaussBlur := gocv.NewMat()
gocv.GaussianBlur(edges, &gaussBlur, image.Point{1, 1}, 1, 1, gocv.BorderWrap)
gaussBlurW := gocv.NewWindow("gaussBlur")
defer gaussBlurW.Close()
gaussBlurW.IMShow(gaussBlur)
//查找轮廓
pointsVector := gocv.FindContours(gaussBlur, gocv.RetrievalCComp, gocv.ChainApproxNone)
contours := gocv.Zeros(edges.Rows(), edges.Cols(), edges.Type())
contoursW := gocv.NewWindow("contours")
defer contoursW.Close()
c := color.RGBA{0, 255, 255, 0}
PV := gocv.NewPointsVector()
for k := range pointsVector.ToPoints() {
//ApproxPolyDP 将曲线变成直线 epsilon 这个参数有关*0.01 数在0.1和0.2之间会将曲线变成直线
//gocv.ArcLength轮廓周长判断 去除短轮廓
if gocv.ArcLength(pointsVector.At(k), false) > 90 && gocv.ArcLength(pointsVector.At(k), false) < 100 {
pv := gocv.ApproxPolyDP(pointsVector.At(k), gocv.ArcLength(pointsVector.At(k), false)*0.2, false)
PV.Append(pv)
}
}
//画轮廓
for k := range PV.ToPoints() { //这个for少个参数,我也很意外
//再次去除短轮廓 要获取gocv.PointsVector中的gocv.PointVector 要使用 At方法
if gocv.ArcLength(PV.At(k), false) > 50 && gocv.ArcLength(PV.At(k), false) < 100 {
gocv.DrawContours(&contours, PV, k, c, 1)
}
}
contoursW.IMShow(contours)
//使用Shi_Tomasi角点检测
corners := gocv.NewMat()
gocv.GoodFeaturesToTrack(contours, &corners, 10, 0.01, 20) //参数调节好很重要 根据需求调节
//绘制角点
for row := 0; row < corners.Rows(); row++ {
point := corners.Row(row)
for col := 0; col < point.Cols(); col++ {
vf := point.GetVecfAt(col, 0) //GetVecfAt这个方法是用来解析检测的角点
fmt.Println(vf[0], vf[1])
gocv.Circle(&contours, image.Point{int(vf[0]), int(vf[1])}, 3, color.RGBA{25, 25, 255, 0}, -1)
}
}
cornersW := gocv.NewWindow("corners")
defer cornersW.Close()
cornersW.IMShow(contours)
gocv.IMWrite("img/corners.png", contours)
srcW.WaitKey(0)
}