可靠性研究:图片相似性检测

文章介绍了通过缩小尺寸、简化色彩、计算DCT、截取DCT、计算平均值、生成hash值和使用汉明距离比较图像相似度的方法。这种方法用于检测售后安装图片的重复或误用,以减少人工稽查的工作量。Python示例代码展示了实现过程,但实际应用中可能使用更快的C#实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

可靠性做久后,我常常感到无力,因为很多东西不在控制范围内。

比如说安装,声明是售后安装,但很多人是自己安装,或者装修时找水电工等人安装。即使是售后人员去安装,也会有很多不按要求来的。

首先要做的是设计保证,减少对安装人员的要求。但即使设计上做得再多,也很难做到免安装,依然要管控安装的质量。于是有了拍照上传确认,对安装中重要的点进行拍照。

这就涉及到图像的质量的检测。最好是在上传的时候就进行判断,比如照片是否重复利用,照片数量是否全,是否模糊,是否违反安装红线等等。也可以事后抽一些图稽查。很多时候,稽查是靠人工的,但工作量很大,我们可以考虑用程序去实现。

本文讲相似相同图片的识别,后续讲模糊检测,AI审图进行红线管控等。

以下面这个例子为例:

图1 一组相似图片

这两张图片一眼看上去,感觉左边的图是右边的图的局部截取放大图。仔细再看,可以发现并不是,细节上还是有差异,不是同一张图的截取。这种情况人工稽查可能会误判。

售后系统上存在大量此类图片,为了减少人工稽查工作量,我们使用程序来帮助识别。

图像相似检测有很多种方法,这里我们采用感知哈希方法来进行比较。它的总体思想是为图片生成一个指纹,两张图片的指纹越相似,说明两张图片就越相似。

整体步骤可以描述为以下几步:

第1步:缩小尺寸。由于图片的原始尺寸可能不同,我们把图片都缩放到32*32去比较,总共1024个像素。这样可以把图片的尺寸差异去除,只保留结构,另外32*32这个尺寸也是为了减少后续DCT变换的计算量。

图片缩放时,比较有影响的是采用哪种插值方法。我暂时还没有去详细研究哪种插值方法好,但据网络搜索的结果,说是在缩小图像时,用Area插值方法比较好,就先用这个方法,后续可以进一步研究。

第2步:简化色彩。把图片转为灰度图,使得进一步减少计算量。

第3步:计算DCT。把图片进行DCT变换,得到一个32*32的矩阵。DCT变换又称离散余弦变换(DCT,Discrete Cosine Transform)是与傅里叶变换相关的一种变换,它类似于离散傅里叶变换(DFT, Discrete Fourier Transform)。

图像处理二维DCT变换数学公式如下:

二维DCT变换就是将二维图像从空间域转换到频率域。计算出图像由哪些二维余弦波构成,计算出的结果为c(u ,v),其中u为二维波的水平方向频率,v为二维波的垂直方向频率;最终会计算出很多的c(u,v) ; 每一个c称为一个DCT系数,代表的是频率为(u,v)的二维波的振幅(或者能量),所有这些二维波的叠加就是那个原始的图片。

第4步:截取DCT。虽然DCT结果是32*32的矩阵,但我们只取左上角8*8的部分作为后续计算,这部分呈现了图像的低频部分。DCT变换的时候,滤掉了高频的部分,一般图形高频部分的系数是比较小的,在量化的时候可以忽略掉。

  图1右侧图片经过DCT变换后的图像

第5步:计算平均值。计算8*8矩阵,共64个像素的灰度平均值。

第6步:计算hash值。根据8*8的DCT矩阵,设置0或1的值,大于等于DCT均值的设为”1”,小于DCT均值的设为“0”。组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。

第7步:比较图片。汉明距离可以衡量两张图片的差异。汉明距离越小,则代表相似度越高。这里定义相似度的计算公式为:(1-汉明距离/64)*100%

通过上述步骤,我们就得到了开头两张图的相似度:

实现上述过程,可以借助opencv第三方库实现,它里面已经定义有很多函数,例如缩放,转灰度,DCT变换等。当然,如果想加深对图像处理的理解,在学习之初,我建议自己编写程序去实现,把这些库函数自己写一遍。

以下是用python实现的参考代码:

import cv2
import numpy as np

# 感知哈希算法
def pHash(path):
    # 读图片
    img = cv2.imread(path)
    # 缩放32*32,这里使用了AREA插值
    img = cv2.resize(img, (32, 32), interpolation=cv2.INTER_AREA)
    # 转换为灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 将灰度图转为浮点型,再进行dct变换    
    dct = cv2.dct(np.float32(gray))
    # 只取左上角8*8计算
    dct_roi = dct[0:8, 0:8]
 
    hash = []
    avreage = np.mean(dct_roi)
    for i in range(dct_roi.shape[0]):
        for j in range(dct_roi.shape[1]):
            if dct_roi[i, j] > avreage:
                hash.append(1)
            else:
                hash.append(0)
    return hash
    
# Hash值对比 
def cmpHash(hash1, hash2):
    n = 0
    # hash长度不同则返回-1代表传参出错
    if len(hash1) != len(hash2):
        return -1
    # 遍历判断
    for i in range(len(hash1)):
        # 不相等则n计数+1,n最终为相似度
        if hash1[i] != hash2[i]:
            n = n + 1
    return n
 
if __name__ == "__main__":
    hash1 = pHash("D:/0/t3.png")
    hash2 = pHash("D:/0/t4.png")
    n = cmpHash(hash1, hash2)
    print('感知哈希算法相似度:%.2f'%(1-float(n/64)))

 但python处理速度实在太慢,不适合在大量图片处理中使用,实际软件开发中,我是用C#编程实现的。

### VMware有线连接无法启用的解决方案 当遇到VMware有线连接无法启用的情况时,可以按照以下方法排查并解决问题: #### 1. 检查VMware NAT和DHCP服务状态 如果VMware NAT和DHCP服务未启动,则可能导致虚拟机内的有线络不可用。可以通过以下操作确认服务运行状况: - 打开Windows的服务管理器(`services.msc`),查找名为 `VMware NAT Service` 和 `VMware DHCP Service` 的条目。 - 如果这些服务处于停止状态,请手动将其设置为自动启动,并重新启动它们[^1]。 #### 2. 虚拟络编辑器配置调整 进入VMware的虚拟络编辑器界面,检查当前NAT模式下的虚拟卡配置是否存在异常: - 点击菜单栏上的 **编辑 -> 虚拟络编辑器**。 - 切换到高级选项中的“更改设置”,确保拥有管理员权限。 - 删除可能冲突的旧版NAT模式对应的虚拟卡(如 VMnet8 或其他自定义名称)[^2]。 完成上述修改后重启计算机以及VMware软件本身,观察是否有改善效果。 #### 3. 配置Ubuntu内部络环境 对于基于Linux的操作系统而言,有时即使外部条件满足仍可能出现络功能失效的现象。此时需重点核查以下几个方面: - 使用命令行工具ping测试主机可达性;若失败则可能是驱动加载错误或者IP地址分配不正确等问题所致。 - 编辑 `/etc/netplan/*.yaml` 文件来指定静态IP或其他参数适配实际需求场景[^3]: ```bash network: version: 2 renderer: networkd ethernets: ens33: # 这替换为你自己的卡名 dhcp4: true ``` 最后执行应用改动指令让新设定生效: ```bash sudo netplan apply ``` --- ### 注意事项 以上提到的方法适用于大多数常规性的故障现象处理流程,在具体实施过程中还需结合实际情况灵活运用各种诊断手段加以辅助判断。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值