2 回答
TA贡献2065条经验 获得超13个赞
OpenCV 有一个与 内置(半)等效的函数np.where()
,即findNonZero()
。正如名称所暗示的,它会查找图像中的非零元素,这就是np.where()
使用单个参数调用时的作用,如numpy 文档所述。
这在 golang 绑定中也可用。来自gocv
FindNonZero 的文档:
func FindNonZero(src Mat, idx *Mat)FindNonZero 返回非零像素位置的列表。
注意:
np.where()
按数组顺序返回索引,即 (row, col) 或 (i, j),这与典型的图像索引 (x, y) 相反。这就是为什么loc
Python 中是相反的。使用时findNonZero()
你不需要这样做,因为 OpenCV 总是使用 (x, y) 来表示点。
TA贡献1831条经验 获得超10个赞
对于任何遇到这个问题的人,我希望有一个完整的例子,让你不用花几天时间把头撞在墙上,一遍又一遍地阅读相同的谷歌结果,直到有东西点击。
package main
import (
"fmt"
"image"
"image/color"
"os"
"gocv.io/x/gocv"
)
func OpenImage(path string) (image.Image, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
img, _, err := image.Decode(f)
return img, err
}
func main() {
src := gocv.IMRead("haystack.png", gocv.IMReadGrayScale)
tgt := gocv.IMRead("needle.png", gocv.IMReadGrayScale)
if src.Empty() {
fmt.Printf("failed to read image")
os.Exit(1)
}
if tgt.Empty() {
fmt.Printf("failed to read image")
os.Exit(1)
}
// Get image size
tgtImg, _ := tgt.ToImage()
iX, iY := tgtImg.Bounds().Size().X, tgtImg.Bounds().Size().Y
// Perform a match template operation
res := gocv.NewMat()
gocv.MatchTemplate(src, tgt, &res, gocv.TmSqdiffNormed, gocv.NewMat())
// Set a thresh hold. Using the `gocv.TmSqdiffNormed` confidence levels are
// reversed. Meaning the lowest value is actually the greatest confidence.
// So here I perform an Inverse Binary Threshold setting all values
// above 0.16 to 1.
thresh := gocv.NewMat()
gocv.Threshold(res, &thresh, 0.16, 1.0, gocv.ThresholdBinaryInv)
// Filter out all the non-zero values.
gocv.FindNonZero(thresh, &res)
// FindNonZero returns a list or vector of locations in the form of a gocv.Mat when using gocv.
// There may be a better way to do this, but I iterate through each found location getting the int vector in value
// at each row. I have to convert the returned int32 values into ints. Then draw a rectangle around each point.
//
// The result of get res.GetVeciAt(i, 0) is just a slice of x, y integers so each value can be accessed by
// using slice/array syntax.
for i := 0; i < res.Rows(); i++ {
x, y := res.GetVeciAt(i, 0)[0], res.GetVeciAt(i, 0)[1]
xi, yi := int(x), int(y)
gocv.Rectangle(&src, image.Rect(xi, yi, xi+iX, yi+iY), color.RGBA{0, 0, 0, 1}, 2)
}
w := gocv.NewWindow("Test")
w.IMShow(src)
if w.WaitKey(0) > 1 {
os.Exit(0)
}
}
- 2 回答
- 0 关注
- 185 浏览
添加回答
举报