图像和轮廓匹配(hu矩)

图像和轮廓的匹配(hu矩)
(1)hu矩的概念,我也总结了但是我不过多的阐述,因为我也不是太理解,只知道它具有平移,旋转,尺度不变性,详细见别人的这篇blog:http://blog.csdn.net/wrj19860202/article/details/6327094
(2)OpenCV 的实现——计算hu矩
<1>普通矩和中心矩的计算
Void cvMoments(const CvArr*arr,CvMoments*moments, int binary = 0)
arr:图像(1-通道或3通道,有COI设置)或者多边形(点的CvSeq或一族点的向量)
moments:返回矩阵态度接口的指针
binary(仅对图像)如果标识为非0,则所有零像素点被当成零,其它的被看成1.
Double cvGetSpatialMoment(&moment, p, q); //得到普通矩
Double cvGetCentralMoment(&moment, p, q); // 得到中心矩
<2>计算hu矩
Void cvGetHuMoment(CvMoments *moment,CvHuMoments *humoment)
代码:

IplImage *src = cvCreateImage(cvSize(10,10), 8, 1);  
    cvZero(src);  
    for(int yy = 0; yy < 5; yy++)  
    {  
        for(int xx = 0; xx < 5; xx++)  
        {  
            cvSetReal2D(src, yy, xx, 255);  
        }  
    }  
    double m00, m10, m01;  
    CvMoments moment;  
    cvMoments(src, &moment, 2);   //第三个像素点非0,则所有的0像素点被当做0,非0像素点被当做1  
    m00 = cvGetSpatialMoment(&moment, 0, 0); // 得到普通矩  
    m10 = cvGetSpatialMoment(&moment, 1, 0);  
    m01 = cvGetSpatialMoment(&moment, 0, 1);  
    double u20;  
    u20 = cvGetCentralMoment(&moment, 2, 0);  //得到中心矩  
    CvHuMoments humoment;  
    cvGetHuMoments(&moment, &humoment);  
    double hu1 = humoment.hu1;    // 得到hu矩  
    cout << hu1 << endl;  

<3>OPENCV还提供了输入图像直接进行hu矩匹配的函数,返回的是两个图像或轮廓之间hu矩的相似度:
double cvMatchShapes(const void*object1,const void*object2,int method,doubleparameter=0);
计算两个轮廓之间hu矩相似程度:

#include <iostream>  
#include "cv.h"  
#include "cxcore.h"  
#include "highgui.h"  
using namespace std;  

CvSeq *getImageContours(CvArr *src)  
{  
    cvThreshold(src, src, 100, 255, CV_THRESH_BINARY);  
    CvMemStorage * storage = cvCreateMemStorage(0);  
    CvSeq * contours;  
    cvFindContours(src, storage, &contours);  
    return contours;  
}  
int main()  
{  
    IplImage *src1 = cvLoadImage("", 0);  
    CvSeq *contours1 = getImageContours(src1);  // 得到src1的轮廓  
    IplImage *src2 = cvLoadImage("", 0);  
    CvSeq *contours2 = getImageContours(src2);  
    double result = cvMatchShapes(contours1, contours2, 1);   // 根据输入的图像或轮廓来计算它们的hu矩的相似度  
    cout << result << endl;  
    cvReleaseMemStorage(&contours1->storage);  
    cvReleaseMemStorage(&contours1->storage);  
    cvReleaseImage(&src1);  
    cvReleaseImage(&src2);  
    return 0;  
}  

(3)案例:给出了10副图片,其中2.jpg和11.jpg非常相似,我们代码是要实现的在3~11.jgp找到与2.jpg最相似的图片。
代码:

#include <iostream>  
#include <string>  
#include <sstream>  
#include "cv.h"  
#include "cxcore.h"  
#include "highgui.h"  
using namespace std;  

int main()  
{  
    IplImage *srcColor = cvLoadImage("E:\\study_opencv_video\\lesson15_3\\2.jpg", 1);  
    IplImage *src = cvCreateImage(cvGetSize(srcColor), 8, 1);  
    cvCvtColor(srcColor, src, CV_BGR2GRAY);  
    if(!src)  
    {  
        cout << "No Image Load" << endl;  
    }  
    int i;  
    stringstream ss;  
    string path;  
    string str;  
    IplImage *dst = NULL, *dstColor;  
    char c[256];  
    double result, maxResult= 1000 * 256 *256;  
    IplImage *resultMap = NULL;  
    for (i = 3; i < 12; i ++)  
    {  
        path = "E:\\study_opencv_video\\lesson15_3\\";  
        ss.clear();  
        ss << i;  
        ss >> str;  
        str += ".jpg";  
        path += str;  
        ss.clear();  
        ss << path;  
        ss >> c;  
        dstColor = cvLoadImage(c,1);  
        dst = cvCreateImage(cvGetSize(dstColor), 8, 1);  
        cvCvtColor(dstColor, dst, CV_BGR2GRAY);  
        result = cvMatchShapes(src, dst, 1);  
        if(maxResult > result)  
        {  
            resultMap = cvCreateImage(cvGetSize(dstColor), 8, 3);  
            maxResult = result;  
            cvCopy(dstColor, resultMap);  
        }  
    }  
    cvNamedWindow("srcColor", 0);  
    cvNamedWindow("resultMap",0);  
    cvShowImage("resultMap", resultMap);  
    cvShowImage("srcColor", srcColor);  
    cvWaitKey(0);  
    cvReleaseImage(&src);  
    cvReleaseImage(&srcColor);  
    cvReleaseImage(&dst);  
    cvReleaseImage(&dstColor);  
    cvReleaseImage(&resultMap);  
    cvDestroyWindow("srcColor");  
    cvDestroyWindow("resultMap");  
    return 0;  
}  
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值