摘要: 本文使用opencv。numpy等简单的工具库,根据mse及ssim两种算法来评估两张图像的类似度,便于理解与实践。
做为人类,咱们一般很是善于发现图像中的差别。例如,常见的游戏——两张图像找不一样。如今让咱们玩下这个游戏吧,首先让咱们看看上面的图像,三十秒内看看是否可以从中找出有什么不一样的地方。python
答案:水果、冰淇淋和饮料的颜色发生了明显改变,窗帘、太阳也发生了改变,这是否是很简单呢?若是有补充的答案,请在留言处给出哦!算法
这类问题对于人类来讲看起来是一件垂手可得的事情,可是,对于计算机来讲,这可不是一件容易的事儿。这是因为计算机只能从咱们训练它的模型中学习,才最终具备这类能力。目前有不少很好的模型能够对批量图像进行分类,好比TensorFlow和Keras等开源工具。less
借助于这类开源工具库,计算机视觉领域的研究得以高发展。如今咱们也能够借助于这类工具箱建立很是复杂的模型以及解决比较复杂的问题,例如kaggle:Animals-10,该数据集包含数十种不一样类型动物的图像以及非动物图像。所要作的就是建立一个模型来预测图片是哪一种类型的动物。机器学习
然而,上述任务较为简单,好比常见的手写体数字识别MNIST等,通常也都能取得很高的精度。在这里,我想增长一点难度,建立一个图像分类器,以分辨出两个图像的类似程度。而且,不依赖任何复杂的工具库,如TensorFlow、Keras等。本文采用传统的机器学习方法,这里从中选取两种方法,用于查找图像是否与另外一个图像类似。这两种方法分别为均方偏差(MSE)、结构类似度指数(SSIM)。函数
上述公式看起来很是复杂,但不要惧怕。借助于NumPy,能够至关容易地计算出MSE;另外,因为SSIM是Sci-Kit图像库的内置方法的一部分,所以也能够很容易地计算出SSIM。工具
在进行编码以前,这里先对这两种方法予以简单的说明。MSE将计算正在比较的两个图像的每一个像素之间的均方偏差。而SSIM作的事情与MSE刚好相反,寻找像素值的类似之处。 也就是,若是两个图像中的像素排列类似或具备类似的像素密度值。MSE方法遇到的一个的问题是其结果每每具备任意大的值,所以很难给出标准的评判标准。通常而言,MSE越高,代表两张图像的类似程度越低。若是图像之间的MSE值是随机值,则很难说明两者是否类似。另外一方面,SSIM将全部内容归一化到-1~1
的范围内(很可贵到小于0的分数)。得分为1表示两者很是类似,得分为-1表示两者很是不一样。基于此,SSIM相较于MSE而言是一个更好的衡量指标。性能
如今使用代码实现上述想法:学习
加载必要的库:测试
本文使用常见的图像处理工具箱OpenCV实现图像的读取和编辑。若是你对其它图像处理工具箱熟悉,你也可使用本身熟悉的工具箱完成此类操做,好比matplotlibden。编码
编写MSE公式:
使用Numpy操做起来很简单吧!
因为SSIM已经经过skimage导入,所以无需进行手动编码。如今建立一个比较函数,该函数的输入为两个图像,分别计算两者的MSE和SSIM,并展现计算结果。
下面的三个步骤可使用for循环一次完成,可是为了更容易地理解,这里不使用for循环编写代码,将其分解为三个部分:
首先,加载保存在目录中的图像。其次,必须确保它们的大小相同,不然会出现尺寸不匹配的错误。问题是对其进行尺寸变换操做会致使图像失真,因此在找到比较合适的尺寸数字以前,能够尝试快速搜索方法,尺寸大小按照必定的规律设置,不断实验以找到最终比较合适的尺寸。接下来咱们再实现一个功能,以便于看到测试图像是什么样子的。
如今经过比较两个同样的图像来测试并查看MSE和SSIM是否正常工做。若是它有效,那么咱们应该获得MSE值为0和SSIM值为1的结果。
从中能够看到,代码正确,结果与猜测的一致!
如今计算机就能够判断比较的两张图像是否相同了。为简单起见,我将三张狗的图像与本身以及三张猫的图像进行比较。
下面看看两种算法的性能比较。正如所看到的那样,MSE的值变化很大,所以该值很难说明其表达的意思是什么。但从SSIM的结果看出,能够看到狗2和狗3相对于其余狗的图像最为类似。从视觉上来说,我赞成这个结果,由于两只狗的耳朵很是像。但我还会认为狗1和狗3会有更高的SSIM值,由于两者的姿式也很类似。实际上,在图像没有进行灰度处理以前,狗2和狗3在鼻子区域周围有相似的白色毛皮,而狗1没有。这极可能是狗2和3具备比狗1更高的SSIM值的缘由。对于猫来讲,这就有点困难。猫1和猫2具备类似的形状,而且图像是从类似的距离拍摄的,但猫2和猫3具备类似的皮毛颜色。
这里我想进行的测试只有两个:一个是狗和猫的类似性,第二个是每一个动物与原始源代码附带的门图的类似性。
正如所预料的那样,狗和猫是类似的,这点与与无生命的物体相比呈鲜明的对比,如侏罗纪公园入口门。狗和猫对门的图像具备较高的SSIM值,惟一缘由在于图像都通过了尺寸缩放和灰度处理。
在调整图像大小和从新配置时,OpenCV并非最好的。通常而言,TensorFlow是最好的,TensorFlow也最适合批量图像。
以后,我也将使用TensorFlow处理kaggle Animal-10数据集,来实现一个完整的图像分类器。
本文为云栖社区原创内容,未经容许不得转载。