圖像和輪廓的匹配(hu矩)

圖像和輪廓的匹配(hu矩) (轉自:http://blog.csdn.net/lu597203933 

(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)

代碼:

  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矩相似程度:

  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最相似的圖片。

代碼:

  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. }  

發佈了4 篇原創文章 · 獲贊 4 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章