以图搜图实现之均值哈希

本文介绍了均值哈希算法在实现图像搜索中的应用,包括基本思路和C#实现。通过缩小尺寸、简化色彩、计算平均值、比较像素灰度和计算hash值来生成图片指纹。汉明距离用于衡量图片相似度,当汉明距离小于5时,表示图片相近。该算法适用于缩略图查找原图,不适合人相匹配。
摘要由CSDN通过智能技术生成

前言

最近在逛淘宝时发现了淘宝的图片搜索功能,可能是我太Low了这个技术点已经实现很长时间了。想想自己能不能实现这个功能,起初我是这么想的,对两张图片从左上角的第一个像素点一直比较到右下角的最后一个像素点,并在比较时记录它们的相似度,可能是我太天真了(主要还是知识限制了想象),这样做有很多问题,比如说两张图片大小不一致、核心要素点的位置不同等…最终只得借助网络了,找到了一种叫做均值哈希的算法(Average hash algorithm),接下来具体阐述它的基本思路以及适用场景。

均值哈希的基本思路

1、缩小尺寸:

去除图片的高频和细节的最快方法是缩小图片,将图片缩小至8x8的尺寸共计64个像素。无需保持长宽比,只需将其变成8乘8的正方形。这样就可以比较任意大小的图片,摒弃不同尺寸、比例带来的图片差异。

2、简化色彩:

将8乘8的小图片转换成灰度图像。

3、计算平均值:

计算所有64个像素的灰度平均值。

4、比较像素的灰度:

将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。

5、计算hash值:

将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。

如果图片放大或缩小,或改变纵横比,结果值也不会改变。增加或减少亮度或对比度,或改变颜色,对hash值都不会太大的影响。最大的优点:计算速度快!

那么完成了以上步骤,一张图片就相当于有了自己的"指纹"了,然后就是计算不同位的个数,也就是汉明距离(例如1010001与1011101的汉明举例就是2,也就是不同的个数)。

如果汉明距离小于5,则表示有些不同,但比较相近,如果汉明距离大于10则表明完全不同的图片。

以上就是均值哈希的基本实现思路,总体来说是比较简单的。

C#实现

public class ImageHashHelper
{
   
    /// <summary>
    /// 获取缩略图
    /// </summary>
    /// <returns></returns>
    private static Bitmap GetThumbImage(Image image, int w, int h)
    {
   
        Bitmap bitmap = new Bitmap(w, h);
        Graphics g = Graphics.FromImage(bitmap);
        g.DrawImage(image,
            new Rectangle(0, 0, bitmap
Java中实现图像搜索(也称为图像检索或相似度匹配)通常涉及到计算机视觉和机器学习技术,特别是使用深度学习模型如卷积神经网络(CNN)。这里我们不直接给出完整的代码,但可以提供一个基本框架和技术要点: 1. 图像预处理:首先,你需要将图片转换为一维向量,这通常是通过使用特征提取工具(例如`OpenCV`库)进行的。常用的预处理步骤包括缩放、裁剪、归一化等。 ```java import org.opencv.core.Core; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; Mat image = Imgcodecs.imread("image.jpg"); // Resize, crop, and normalize the image ``` 2. 特征提取:使用深度学习库(如`TensorFlow`, `Keras`, 或者`Dlib`的`face_recognition`模块)提取图片的特征向量。对于CNN,这些向量代表了图片的主要内容。 ```java FeatureExtractor featureExtractor = new FeatureExtractor(); MatOfFloat featureVector = featureExtractor.extract(image); ``` 3. 建立索引:将提取到的特征向量存储在一个数据结构中,比如FLANN(Fast Library for Approximate Nearest Neighbors)或Annoy(Approximate Nearest Neighbors Oh Yeah),用于快速查询相似图片。 ```java Indexer indexer = new Indexer(); indexer.add(featureVector); // When searching, use indexer.search(queryFeatureVector, k) to find top-k similar images. ``` 4. 查询阶段:对新来的图像执行同样的特征提取,并使用索引来查找最相似的图像。 ```java Mat queryImage = Imgcodecs.imread("query.jpg"); MatOfFloat queryFeatureVector = featureExtractor.extract(queryImage); TopKNearest neighbors = indexer.search(queryFeatureVector, k); // k表示想要找到的最接近的图片数量 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值