猿问

如何用go比较图像?

在 go图像包中,我没有看到任何可用于比较两个图像的方法?是否可以在类似于 ImageMagick 的 go 中进行图像比较?


红糖糍粑
浏览 258回答 3
3回答

LEATH

如果您尝试比较两个图像并且只需要将其归结为一个数字,则以下方法将起作用。这在(例如)遗传算法中很有用,您希望比较一组候选对象并选择与参考图像差异最小的一个:访问每一个像素,将它分解为它的部分:R,G,B,A(在去:image.At(x,y).RGBA())从参考图像中相应的像素值中减去 RGBA 值。将差异平方,将它们相加。取总和的平方根。这个数字会让您大致了解图像的差异程度。如果你知道这两个图像都是image.RGBA(或者你可以转换它们)的实例,那么你可以做更快的事情:直接从RGBA.Pix.&nbsp;这就是我在这里所做的,它大约比img.At(x,y).RGBA()每个像素对快 10 倍:func FastCompare(img1, img2 *image.RGBA) (int64, error) {&nbsp; &nbsp; if img1.Bounds() != img2.Bounds() {&nbsp; &nbsp; &nbsp; &nbsp; return 0, fmt.Errorf("image bounds not equal: %+v, %+v", img1.Bounds(), img2.Bounds())&nbsp; &nbsp; }&nbsp; &nbsp; accumError := int64(0)&nbsp; &nbsp; for i := 0; i < len(img1.Pix); i++ {&nbsp; &nbsp; &nbsp; &nbsp; accumError += int64(sqDiffUInt8(img1.Pix[i], img2.Pix[i]))&nbsp; &nbsp; }&nbsp; &nbsp; return int64(math.Sqrt(float64(accumError))), nil}func sqDiffUInt8(x, y uint8) uint64 {&nbsp; &nbsp;&nbsp; &nbsp; d := uint64(x) - uint64(y)&nbsp; &nbsp; return d * d}

HUX布斯

试试https://github.com/vitali-fedulov/images。我写这个包是为了能够找到接近的重复项。有一个使用相同算法的实时网络演示,因此您可以了解该软件包如何满足您的需求。

千万里不及你

对于这里的两个当前答案,图像需要具有相同的大小,否则比较失败。这里的第三个答案使用Vitali-fedulov/images,它没有任何方法来获取两个图像之间的差异,只有一个Similar返回bool确定两个图像是否相似的函数。此外,如果图像大小不同,Rosetta Code的答案也会失败。所以如果我要实现我自己的解决方案,首先我需要缩小更大的图像。为此,我找到了x/image/draw和nfnt/resize,但我想也许我可以找到一些东西,用一块石头杀死两只鸟。为此,我确实找到了一些可以根据需要缩放图像的软件包,对每个图像进行散列,并获得散列的差异。这是corona10/goimagehash:package mainimport (&nbsp; &nbsp;"github.com/corona10/goimagehash"&nbsp; &nbsp;"image/jpeg"&nbsp; &nbsp;"os")func hash(name string) (*goimagehash.ImageHash, error) {&nbsp; &nbsp;f, err := os.Open(name)&nbsp; &nbsp;if err != nil {&nbsp; &nbsp; &nbsp; return nil, err&nbsp; &nbsp;}&nbsp; &nbsp;defer f.Close()&nbsp; &nbsp;i, err := jpeg.Decode(f)&nbsp; &nbsp;if err != nil {&nbsp; &nbsp; &nbsp; return nil, err&nbsp; &nbsp;}&nbsp; &nbsp;return goimagehash.AverageHash(i)}例子:package mainfunc main() {&nbsp; &nbsp;a, err := hash("mb.jpg")&nbsp; &nbsp;if err != nil {&nbsp; &nbsp; &nbsp; panic(err)&nbsp; &nbsp;}&nbsp; &nbsp;b, err := hash("hqdefault.jpg")&nbsp; &nbsp;if err != nil {&nbsp; &nbsp; &nbsp; panic(err)&nbsp; &nbsp;}&nbsp; &nbsp;d, err := a.Distance(b)&nbsp; &nbsp;if err != nil {&nbsp; &nbsp; &nbsp; panic(err)&nbsp; &nbsp;}&nbsp; &nbsp;println(d)}
随时随地看视频慕课网APP

相关分类

Go
我要回答