
离线 TA的专栏
- 打卡等级:即来则安
- 打卡总天数:15
- 打卡月天数:0
- 打卡总奖励:204
- 最近打卡:2023-08-27 07:15:39
|
在介绍技术细节前,我们先来看看图片对比在哪些场景下可以用得到:
- 图片去重:自动删除重复图片,为存储空间"瘦身"。想象你是一个社交媒体平台的运营,每天要处理数万张图片。重复图片不仅占用存储空间,还会影响用户体验。
- 内容审核:一些平台需要筛选相似或重复的内容,防止版权侵犯和内容垃圾。
- 版权维 权:检测图片有无被未经授权使用的情况,比如,摄影师和设计师需要知道自己的作品是否被未经授权使用。
- 相似图片搜索:网盘、云存储服务需要帮助用户清理重复文件。
在这些场景中,图片对比技术可以帮我们自动化处理大量图片,提高工作效率。
但是,图片对比可不像 字符那样可以直接使用等于号 直接对比,那么,我们有哪些对比方式呢?
方法一:MD5指纹对比 - 精确匹配
MD5 是一种信息摘要算法,可以将任意长度的数据映射为固定长度的字符串。对于图片文件,我们可以将其计算出一个独一无二的 MD5 值,就像一个数字指纹,可以用来 精确比对两个文件(不仅仅是图片)是否完全相同。
下面是使用 Go 语言计算图片 MD5 值的示例代码: - package main
- import (
- "crypto/md5"
- "fmt"
- "io"
- "os"
- )
- // calculateMD5 计算文件的MD5值
- // 为图片颁发独一无二的“身份证”
- func calculateMD5(filePath string) (string, error) {
- // 打开文件
- file, err := os.Open(filePath)
- if err != nil {
- return "", fmt.Errorf("无法打开文件:%v", err)
- }
- defer file.Close()
- // 创建MD5哈希器
- hash := md5.New()
- // 将文件内容复制到哈希器中
- if _, err := io.Copy(hash, file); err != nil {
- return "", fmt.Errorf("计算MD5时出错:%v", err)
- }
- // 返回MD5字符串
- return fmt.Sprintf("%x", hash.Sum(nil)), nil
- }
- func main() {
- // 比较两张图片
- md51, err := calculateMD5("image1.jpg")
- if err != nil {
- fmt.Println("图片1处理失败:", err)
- return
- }
- md52, err := calculateMD5("image2.jpg")
- if err != nil {
- fmt.Println("图片2处理失败:", err)
- return
- }
- // 对比结果
- if md51 == md52 {
- fmt.Println("图片完全相同")
- } else {
- fmt.Println("图片不同")
- }
- }
复制代码代码解读:
- 我们定义了一个函数,传入文件路径,返回计算出的 MD5 字符串。
- 函数中先打开文件,创建一个 MD5 哈希器。
- 通过将文件内容写入哈希器中,计算出 MD5 值。
- 最后将 MD5 字节数组格式化为字符串返回。
- 在函数中,我们计算两个图片文件的 MD5 值,比对它们是否相等,输出结果。
MD5 比对的特点:
- 速度快、计算简单
- 可精确判断两个文件是否完全相同(只要是文件,都可以通过这种方式进行判断是否一样)
- 无法检测内容相似但不完全相同的图片
- 图片稍有改动(如添加水印)就会导致 MD5 值完全不同
所以 MD5 比对适合用于检测完全相同的图片,如文件去重等场景。如果两张图片只是稍作修改(如调整亮度、旋转等),MD5 就无能为力了。
方法二:图像哈希对比
图像哈希(Image Hashing)是一类可以比较图片相似程度的算法。其基本原理是:将图片缩小、简化为一个哈希值,然后比较不同图片哈希值的差异度,来判断它们的相似程度。
常见的图像哈希算法有:
- 平均哈希(Average Hash)
- 感知哈希(Perceptual Hash)
- 差异哈希(Difference Hash)
- 小波哈希(Wavelet Hash)
这里我们以第三方包为例:
首先先安装这个包 - go get github.com/corona10/goimagehash
复制代码然后我们来尝试实现一个图片相似度比对: - package main
- import (
- "fmt"
- "image/png"
- "os"
- "github.com/corona10/goimagehash"
- )
- // compareImageSimilarity 比较图片相似度
- func compareImageSimilarity(image1Path, image2Path string) error {
- file1, err := os.Open(image1Path)
- if err != nil {
- return fmt.Errorf("打开图片1失败:%v", err)
- }
- defer file1.Close()
- file2, err := os.Open(image2Path)
- if err != nil {
- return fmt.Errorf("打开图片2失败:%v", err)
- }
- defer file2.Close()
- // 加载图片
- img1, err := png.Decode(file1)
- if err != nil {
- return fmt.Errorf("加载图片1失败:%v", err)
- }
- img2, err := png.Decode(file2)
- if err != nil {
- return fmt.Errorf("加载图片2失败:%v", err)
- }
- // 生成平均哈希
- avgHash1, err := goimagehash.AverageHash(img1)
- if err != nil {
- return fmt.Errorf("生成图片1哈希失败:%v", err)
- }
- avgHash2, err := goimagehash.AverageHash(img2)
- if err != nil {
- return fmt.Errorf("生成图片2哈希失败:%v", err)
- }
- // 计算差异哈希
- diffHash1, err := goimagehash.DifferenceHash(img1)
- if err != nil {
- return fmt.Errorf("生成图片1差异哈希失败:%v", err)
- }
- diffHash2, err := goimagehash.DifferenceHash(img2)
- if err != nil {
- return fmt.Errorf("生成图片2差异哈希失败:%v", err)
- }
- // 计算汉明距离
- avgDistance, err := avgHash1.Distance(avgHash2)
- if err != nil {
- return fmt.Errorf("计算平均哈希距离失败:%v", err)
- }
- diffDistance, err := diffHash1.Distance(diffHash2)
- if err != nil {
- return fmt.Errorf("计算差异哈希距离失败:%v", err)
- }
- // 打印相似度
- fmt.Printf("平均哈希距离:%d\n", avgDistance)
- fmt.Printf("差异哈希距离:%d\n", diffDistance)
- // 判断相似程度
- if avgDistance == 0 && diffDistance == 0 {
- fmt.Println("两张图一样")
- } else if avgDistance <= 5 || diffDistance <= 5 {
- fmt.Println("图片高度相似")
- } else if avgDistance <= 10 || diffDistance <= 10 {
- fmt.Println("图片相似")
- } else {
- fmt.Println("图片差异较大")
- }
- return nil
- }
- func main() {
- err := compareImageSimilarity("img.png", "img_1.png")
- if err != nil {
- fmt.Println("图片对比出错:", err)
- }
- }
复制代码图像哈希的特点:
- 可以比较图片内容的相似程度
- 对图片的缩放、旋转、亮度变化等稍微鲁棒
- 计算难度适中,可应用于相似图片搜索等场景
- 仍无法识别完全不同但语义相似的图片(比如同一物体不同角度的照片)
它们各有特点和适用场景:
MD5指纹:简单快速,适合精确匹配完全相同的图片。 图像哈希:可以比较图片的相似程度,在相似图片搜索等场景下很有用。
当然,这只是图像相似度算法的冰山一角。在实际应用中,我们还需要考虑性能、精度、复杂度等因素,选择最适合的方案。
图像识别领域在不断发展,一些前沿技术如机器学习、深度神经网络等,为图片相似度判断带来了更多的可能性,值得我们去学习和探索。
到此这篇关于Go语言如何判断两张图片的相似度的文章就介绍到这了,更多相关Go判断图片相似度内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:  进行删除处理。
4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
|