3 回答
TA贡献1936条经验 获得超6个赞
如果您尝试比较两个图像并且只需要将其归结为一个数字,则以下方法将起作用。这在(例如)遗传算法中很有用,您希望比较一组候选对象并选择与参考图像差异最小的一个:
访问每一个像素,将它分解为它的部分:R,G,B,A(在去:
image.At(x,y).RGBA()
)从参考图像中相应的像素值中减去 RGBA 值。
将差异平方,将它们相加。
取总和的平方根。
这个数字会让您大致了解图像的差异程度。
如果你知道这两个图像都是image.RGBA
(或者你可以转换它们)的实例,那么你可以做更快的事情:直接从RGBA.Pix
. 这就是我在这里所做的,它大约比img.At(x,y).RGBA()
每个像素对快 10 倍:
func FastCompare(img1, img2 *image.RGBA) (int64, error) {
if img1.Bounds() != img2.Bounds() {
return 0, fmt.Errorf("image bounds not equal: %+v, %+v", img1.Bounds(), img2.Bounds())
}
accumError := int64(0)
for i := 0; i < len(img1.Pix); i++ {
accumError += int64(sqDiffUInt8(img1.Pix[i], img2.Pix[i]))
}
return int64(math.Sqrt(float64(accumError))), nil
}
func sqDiffUInt8(x, y uint8) uint64 {
d := uint64(x) - uint64(y)
return d * d
}
TA贡献1876条经验 获得超6个赞
试试https://github.com/vitali-fedulov/images。我写这个包是为了能够找到接近的重复项。有一个使用相同算法的实时网络演示,因此您可以了解该软件包如何满足您的需求。
TA贡献1784条经验 获得超9个赞
对于这里的两个当前答案,图像需要具有相同的大小,否则比较失败。这里的第三个答案使用Vitali-fedulov/images,它没有任何方法来获取两个图像之间的差异,只有一个Similar返回bool确定两个图像是否相似的函数。此外,如果图像大小不同,Rosetta Code的答案也会失败。
所以如果我要实现我自己的解决方案,首先我需要缩小更大的图像。为此,我找到了x/image/draw和nfnt/resize,但我想也许我可以找到一些东西,用一块石头杀死两只鸟。为此,我确实找到了一些可以根据需要缩放图像的软件包,对每个图像进行散列,并获得散列的差异。这是corona10/goimagehash:
package main
import (
"github.com/corona10/goimagehash"
"image/jpeg"
"os"
)
func hash(name string) (*goimagehash.ImageHash, error) {
f, err := os.Open(name)
if err != nil {
return nil, err
}
defer f.Close()
i, err := jpeg.Decode(f)
if err != nil {
return nil, err
}
return goimagehash.AverageHash(i)
}
例子:
package main
func main() {
a, err := hash("mb.jpg")
if err != nil {
panic(err)
}
b, err := hash("hqdefault.jpg")
if err != nil {
panic(err)
}
d, err := a.Distance(b)
if err != nil {
panic(err)
}
println(d)
}
- 3 回答
- 0 关注
- 257 浏览
添加回答
举报