为了账号安全,请及时绑定邮箱和手机立即绑定

OpenCV 相当于 np.where()

OpenCV 相当于 np.where()

Go
慕沐林林 2023-07-31 17:33:20
例如,当使用gocv包时,可以执行图像内模式的模板匹配。该包还提供MinMaxLoc函数来检索矩阵内最小值和最大值的位置。然而,在下面的 python 示例中,作者使用numpy.Where对矩阵进行阈值处理并获取多个最大值的位置。python zip函数用于将值粘合在一起,因此它们就像一个切片[][2]int,内部切片是找到的匹配项的 xs 和 ys。该语法loc[::-1] 反转数组。中的星号运算符zip(*loc..)用于解压提供给 zip 的切片。import cv2 as cvimport numpy as npfrom matplotlib import pyplot as pltimg_rgb = cv.imread('mario.png')img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)template = cv.imread('mario_coin.png',0)w, h = template.shape[::-1]res = cv.matchTemplate(img_gray,template,cv.TM_CCOEFF_NORMED)threshold = 0.8loc = np.where( res >= threshold)for pt in zip(*loc[::-1]):    cv.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)cv.imwrite('res.png',img_rgb)如何np.where在 Go 中实现相同的算法来获取应用阈值后的多个位置?
查看完整描述

2 回答

?
翻翻过去那场雪

TA贡献2065条经验 获得超13个赞

OpenCV 有一个与 内置(半)等效的函数np.where(),即findNonZero()。正如名称所暗示的,它会查找图像中的非零元素,这就是np.where()使用单个参数调用时的作用,如numpy 文档所述。

这在 golang 绑定中也可用。来自gocvFindNonZero 的文档:

func FindNonZero(src Mat, idx *Mat)

FindNonZero 返回非零像素位置的列表。

注意:np.where()按数组顺序返回索引,即 (row, col) 或 (i, j),这与典型的图像索引 (x, y) 相反。这就是为什么locPython 中是相反的。使用时findNonZero()你不需要这样做,因为 OpenCV 总是使用 (x, y) 来表示点。


查看完整回答
反对 回复 2023-07-31
?
慕哥6287543

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)

    }

}



查看完整回答
反对 回复 2023-07-31
  • 2 回答
  • 0 关注
  • 185 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信