我是靠谱客的博主 高大麦片,最近开发中收集的这篇文章主要介绍图片相似度计算,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

今天自己写了一个简单的计算图相似度的算法,借鉴了哈希算法思想进行编写,在此分享给大家!

总体思路 :

(借鉴了相似图像搜素的关键技术——哈希算法)将每一张图片人为转换具有0或1规律表达的图像,即将图像按照某个阈值生成对应的指纹字符串。我们最终是通过比较不同图片转后对应位置的指纹字符串,其结果越是趋向于1越相似。

主要实现的步骤如下:
Step 1. 输入图像
Step 2. 进行灰度化 (如果是需要更高精度的图像相似度计算,可以考虑利用原始图)
Step 3. 将输入的图像进行归一化到指定尺寸 例如9*9
Step 4. 等比降低灰度值 (grayValue/N 其中N是正整数,也可以省略)
Step 5. 计算图像平均灰度值average
Step 6. 生成指纹图,将归一化的图像每个位置Img(i,j)与平均灰度值average进行比较,若 Img(I,j)> average,则Img(i,j)=1,否则Img(I,j)=0;
Step 7. 按照一定排列顺序进行两幅图像比较,获得相似度similarity
我设定初始值similarity = 1。


接下来直接上代码:

//第一个函数:计算图片的指纹信息
string CalImgHashValue(IplImage* src)
{
    int N = 5; //简化常数,人为设定
    int graySum;
    string resStr(81,'');
    uchar* pData;
    IplImage* image =  cvCreateImage(cvGetSize(src),src->depth,1);

    //step2 : 灰度化
    if(src->nChannels == 3) 
         cvCvtColor(src,image,CV_BGR2GRAY);
    else  
        cvCopy(src,image);

    //step 3 : 缩小尺寸 9*9
    IplImage* temp = cvCreateImage(cvSize(9,9),image->depth,1);
    cvResize(image,temp);

    //step 4 : 简化计算量
    for(int i=0; i<temp->height; i++)
    {
        pData =(uchar* )(temp->imageData+i*temp->widthStep);
        for(int j=0; j<temp->width;j++)
            pData[j]= pData[j]/N;
    }
    //step 5 : 计算平均灰度值

    int count = 0;
    for (int row = 0; row< src->iHeight; row++)
    {
        for (int col = 0; col<= src->iWidth; col++)
        {
            graySum = graySum + (uchar)ImgGray->imageData[row*src->widthStep + col];
            count++;
        }
    }
    int average = graySum/count;

    //step 6 : 计算哈希值
    int index = 0;
    for(int i=0; i<temp->height; i++)
    {
        pData =(uchar* )(temp->imageData+i*temp->widthStep);
        for(int j=0; j<temp->width;j++)
        {
            if(pData[j]>=average)
                resStr[index++]='1';
            else 
                resStr[index++]='0';
        }
    }
        return resStr;
    }

//第二个函数:计算两幅图像的相似度
void GetImgSimilarity(string &str1,string &str2,double* similarity)
{
     *similarity = 1.0;
    for(int i=0;i<64;i++)
    {
        char c1 = str1[i];
        char c2 = str2[i];
        if(c1!=c2)
        *similarity = *similarity -1.0/64;
    }
}

//声明
string CalImgHashValue(IplImage* src);               //计算图片的指纹信息
void GetImgSimilarity(string &str1,string &str2);  //根据指纹信息计算两幅图像的相似度

//测试程序
#include <opencv2/opencv.hpp>

using namespace std;


int main()
{
    IplImage* img1 = cvLoadImage("hanshanbuleng1.jpg",1);
    IplImage* img2 = cvLoadImage("hanshanbuleng2.jpg",1);
    cvShowImage("img1 ",img1 );
    cvShowImage("img2 ",img2 );

    string imgPrint1 = ImageHashValue(image1);
    string imgPrint2 = ImageHashValue(image2);
    double similarity = 0; 

    ImageSimilarity(imgPrint1,imgPrint2,&similarity);

    cout<<"The similarity of two img is "<<similarity*100<<"%"<<endl;
    if(similarity>=0.9)
        cout<<"The two img are extremely similar."<<endl;
    else if(similarity>=0.8&&similarity<0.9)
        cout<<"The two imag are pretty similar."<<endl;
    else if(similarity>=0.7&&similarity<0.8)
        cout<<"The two imag are a little similar."<<endl;
    else if(similarity<0.7)
        cout<<"The two img are not similar."<<endl;
    cout<<endl;
    cvWaitKey(0);
}

最后

以上就是高大麦片为你收集整理的图片相似度计算的全部内容,希望文章能够帮你解决图片相似度计算所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(38)

评论列表共有 0 条评论

立即
投稿
返回
顶部