2.EMD直方图度量相似性

2.EMD度量相似性

根据输入的图像计算色相饱和度(hue-saturation)直方图,然后利用该直方图创建EMD接口参数signature,最后利用EMD来度量两个分布之间的相似性,程序中src1与src2已经过处理,有40的亮度值偏移,具体代码如下:


相关代码
#include <cv.h>
#include <highgui.h>  
#include <stdlib.h>  
#include <stdio.h> 
#include <math.h>

using namespace std;

int main(int argc, char* argv[])
{
    IplImage* src1,*src2,*Imask,*hsv1,*hsv2;                //源图像 HSV格式图像

    if (!(src1 = cvLoadImage("D:\\Template\\OpenCV\\Template47_hue-saturation_EMD\\Debug\\hand1.jpg")))
        return -1;
    if (!(src2 = cvLoadImage("D:\\Template\\OpenCV\\Template47_hue-saturation_EMD\\Debug\\hand3.jpg")))
        return -2;
    if (!(Imask = cvLoadImage("D:\\Template\\OpenCV\\Template47_hue-saturation_EMD\\Debug\\Imask.jpg", CV_LOAD_IMAGE_GRAYSCALE)))
        return -3;

    hsv1 = cvCreateImage(cvGetSize(src1), src1->depth, src1->nChannels);
    hsv2 = cvCreateImage(cvGetSize(src2), src2->depth, src2->nChannels);

    cvCvtColor(src1, hsv1, CV_BGR2HSV); //源图像->HSV格式图像
    cvCvtColor(src2, hsv2, CV_BGR2HSV); //源图像->HSV格式图像

    //色调(hue) 饱和度(saturation) 明度(value)
    IplImage *h_plane_1 = cvCreateImage(cvSize(hsv1->width, hsv1->height), IPL_DEPTH_8U, 1);
    IplImage *s_plane_1 = cvCreateImage(cvSize(hsv1->width, hsv1->height), IPL_DEPTH_8U, 1);
    IplImage *v_plane_1 = cvCreateImage(cvSize(hsv1->width, hsv1->height), IPL_DEPTH_8U, 1);

    IplImage *h_plane_2 = cvCreateImage(cvSize(hsv2->width, hsv2->height), IPL_DEPTH_8U, 1);
    IplImage *s_plane_2 = cvCreateImage(cvSize(hsv2->width, hsv2->height), IPL_DEPTH_8U, 1);
    IplImage *v_plane_2 = cvCreateImage(cvSize(hsv2->width, hsv2->height), IPL_DEPTH_8U, 1);

    IplImage *planes1[] = { h_plane_1, s_plane_1 };                     //色相饱和度数组
    IplImage *planes2[] = { h_plane_2, s_plane_2 };                     //色相饱和度数组

    cvCvtPixToPlane(hsv1, h_plane_1, s_plane_1, v_plane_1, NULL);       //图像分割
    cvCvtPixToPlane(hsv2, h_plane_2, s_plane_2, v_plane_2, NULL);       //图像分割
    //cvSplit(hsv, h_plane, s_plane, v_plane, NULL);

    int h_bins = 30, s_bins = 32;                               

    //建立直方图
    CvHistogram *hist1,*hist2;

    int hist_size[] = { h_bins, s_bins };       //对应维数包含bins个数的数组
    float h_ranges[] = { 0, 180 };              //H通道划分范围 饱和度0-180
    float s_ranges[] = { 0, 255 };              //S通道划分范围
    float* ranges[] = { h_ranges, s_ranges };   //划分范围数对, ****均匀bin,range只要最大最小边界
    //创建直方图 (维数,对应维数bins个数,密集矩阵方式存储,划分范围数对,均匀直方图)
    hist1 = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1);
    hist2 = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1);

    cvCalcHist(planes1, hist1, 0, 0);       //计算直方图(图像,直方图结构,不累加,掩码)
    cvCalcHist(planes2, hist2, 0, 0);       //计算直方图(图像,直方图结构,不累加,掩码)

    //cvCalcHist(planes1, hist1, 0, Imask);     //计算直方图(图像,直方图结构,不累加,掩码)
    //cvCalcHist(planes2, hist2, 0, Imask);     //计算直方图(图像,直方图结构,不累加,掩码)

    cvNormalizeHist(hist1, 1.0);            //直方图归一化
    cvNormalizeHist(hist2, 1.0);            //直方图归一化

    CvMat *sig1, *sig2;
    int numrows = h_bins*s_bins;

    sig1 = cvCreateMat(numrows, 3, CV_32FC1);   //numrows行 3列 矩阵
    sig2 = cvCreateMat(numrows, 3, CV_32FC1);

    for (int h = 0; h < h_bins; h++)
    {
        for (int s = 0; s < s_bins; s++)
        {
            float bin_val = cvQueryHistValue_2D(hist1, h, s);
            //h:行数 s_bins:总列数(行长度)s:列数  h*s_bins+s 当前bin对应的sig行数   
            cvSet2D(sig1, h*s_bins + s, 0, cvScalar(bin_val));  
            cvSet2D(sig1, h*s_bins + s, 1, cvScalar(h));
            cvSet2D(sig1, h*s_bins + s, 2, cvScalar(s));

            bin_val = cvQueryHistValue_2D(hist2, h, s);
            cvSet2D(sig2, h*s_bins + s, 0, cvScalar(bin_val));
            cvSet2D(sig2, h*s_bins + s, 1, cvScalar(h));
            cvSet2D(sig2, h*s_bins + s, 2, cvScalar(s));
        }
    }

    float emd = cvCalcEMD2(sig1, sig2, CV_DIST_L2);
    printf("EMD距离:%f; ", emd);

    cvNamedWindow("SRC1",1);
    cvNamedWindow("SRC2",2);

    cvShowImage("SRC1", src1);
    cvShowImage("SRC2", src2);

    cvWaitKey(0);
    //system("pause");

    cvReleaseMat(&sig1);
    cvReleaseMat(&sig2);

    cvReleaseHist(&hist1);
    cvReleaseHist(&hist2);

    cvReleaseImage(&src1);
    cvReleaseImage(&src2);
    cvReleaseImage(&Imask);
    cvReleaseImage(&hsv1);
    cvReleaseImage(&hsv2);
    cvReleaseImage(&h_plane_1);
    cvReleaseImage(&s_plane_1);
    cvReleaseImage(&v_plane_1);
    cvReleaseImage(&h_plane_2);
    cvReleaseImage(&s_plane_2);
    cvReleaseImage(&v_plane_2);

    cvDestroyAllWindows();
}

最终结果

这里写图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值