opencv学习_10 (图像和轮廓的匹配(hu矩))

来源:互联网 发布:把ubuntu安装到u盘上 编辑:程序博客网 时间:2024/05/16 10:15

图像和轮廓的匹配(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)

代码:

[cpp] view plain copy
 print?
  1. IplImage *src = cvCreateImage(cvSize(10,10), 8, 1);  
  2.     cvZero(src);  
  3.     for(int yy = 0; yy < 5; yy++)  
  4.     {  
  5.         for(int xx = 0; xx < 5; xx++)  
  6.         {  
  7.             cvSetReal2D(src, yy, xx, 255);  
  8.         }  
  9.     }  
  10.     double m00, m10, m01;  
  11.     CvMoments moment;  
  12.     cvMoments(src, &moment, 2);   //第三个像素点非0,则所有的0像素点被当做0,非0像素点被当做1  
  13.     m00 = cvGetSpatialMoment(&moment, 0, 0); // 得到普通矩  
  14.     m10 = cvGetSpatialMoment(&moment, 1, 0);  
  15.     m01 = cvGetSpatialMoment(&moment, 0, 1);  
  16.     double u20;  
  17.     u20 = cvGetCentralMoment(&moment, 2, 0);  //得到中心矩  
  18.     CvHuMoments humoment;  
  19.     cvGetHuMoments(&moment, &humoment);  
  20.     double hu1 = humoment.hu1;    // 得到hu矩  
  21.     cout << hu1 << endl;  

<3>OPENCV还提供了输入图像直接进行hu矩匹配的函数,返回的是两个图像或轮廓之间hu矩的相似度:

double cvMatchShapes(const void*object1,const void*object2,int method,doubleparameter=0);

计算两个轮廓之间hu矩相似程度:

[cpp] view plain copy
 print?
  1. #include <iostream>  
  2. #include "cv.h"  
  3. #include "cxcore.h"  
  4. #include "highgui.h"  
  5. using namespace std;  
  6.   
  7. CvSeq *getImageContours(CvArr *src)  
  8. {  
  9.     cvThreshold(src, src, 100, 255, CV_THRESH_BINARY);  
  10.     CvMemStorage * storage = cvCreateMemStorage(0);  
  11.     CvSeq * contours;  
  12.     cvFindContours(src, storage, &contours);  
  13.     return contours;  
  14. }  
  15. int main()  
  16. {  
  17.     IplImage *src1 = cvLoadImage("", 0);  
  18.     CvSeq *contours1 = getImageContours(src1);  // 得到src1的轮廓  
  19.     IplImage *src2 = cvLoadImage("", 0);  
  20.     CvSeq *contours2 = getImageContours(src2);  
  21.     double result = cvMatchShapes(contours1, contours2, 1);   // 根据输入的图像或轮廓来计算它们的hu矩的相似度  
  22.     cout << result << endl;  
  23.     cvReleaseMemStorage(&contours1->storage);  
  24.     cvReleaseMemStorage(&contours1->storage);  
  25.     cvReleaseImage(&src1);  
  26.     cvReleaseImage(&src2);  
  27.     return 0;  
  28. }  

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

代码:

[cpp] view plain copy
 print?
  1. #include <iostream>  
  2. #include <string>  
  3. #include <sstream>  
  4. #include "cv.h"  
  5. #include "cxcore.h"  
  6. #include "highgui.h"  
  7. using namespace std;  
  8.   
  9. int main()  
  10. {  
  11.     IplImage *srcColor = cvLoadImage("E:\\study_opencv_video\\lesson15_3\\2.jpg", 1);  
  12.     IplImage *src = cvCreateImage(cvGetSize(srcColor), 8, 1);  
  13.     cvCvtColor(srcColor, src, CV_BGR2GRAY);  
  14.     if(!src)  
  15.     {  
  16.         cout << "No Image Load" << endl;  
  17.     }  
  18.     int i;  
  19.     stringstream ss;  
  20.     string path;  
  21.     string str;  
  22.     IplImage *dst = NULL, *dstColor;  
  23.     char c[256];  
  24.     double result, maxResult= 1000 * 256 *256;  
  25.     IplImage *resultMap = NULL;  
  26.     for (i = 3; i < 12; i ++)  
  27.     {  
  28.         path = "E:\\study_opencv_video\\lesson15_3\\";  
  29.         ss.clear();  
  30.         ss << i;  
  31.         ss >> str;  
  32.         str += ".jpg";  
  33.         path += str;  
  34.         ss.clear();  
  35.         ss << path;  
  36.         ss >> c;  
  37.         dstColor = cvLoadImage(c,1);  
  38.         dst = cvCreateImage(cvGetSize(dstColor), 8, 1);  
  39.         cvCvtColor(dstColor, dst, CV_BGR2GRAY);  
  40.         result = cvMatchShapes(src, dst, 1);  
  41.         if(maxResult > result)  
  42.         {  
  43.             resultMap = cvCreateImage(cvGetSize(dstColor), 8, 3);  
  44.             maxResult = result;  
  45.             cvCopy(dstColor, resultMap);  
  46.         }  
  47.     }  
  48.     cvNamedWindow("srcColor", 0);  
  49.     cvNamedWindow("resultMap",0);  
  50.     cvShowImage("resultMap", resultMap);  
  51.     cvShowImage("srcColor", srcColor);  
  52.     cvWaitKey(0);  
  53.     cvReleaseImage(&src);  
  54.     cvReleaseImage(&srcColor);  
  55.     cvReleaseImage(&dst);  
  56.     cvReleaseImage(&dstColor);  
  57.     cvReleaseImage(&resultMap);  
  58.     cvDestroyWindow("srcColor");  
  59.     cvDestroyWindow("resultMap");  
  60.     return 0;  
  61. }  

作者:小村长  出处:http://blog.csdn.net/lu597203933 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:小村长zack, 欢迎交流!)
0 0
原创粉丝点击