zoukankan      html  css  js  c++  java
  • 【练习8.10】直接使用cvFindContour的结果图片和cvDrawContour的方式提取Hu矩,观察在图片缩放或旋转时的稳定性

    页内索引
    题目要求 程序代码 结果图片 要言妙道 借鉴参考

      

    题目要求:

     旋转缩放图像

    a、使用《学习OpenCV》书中提到的技巧,先使用cvDrawContour绘制找到的轮廓在提取矩

    b、直接使用cvFindContour的结果图片提取矩

    程序代码:

      1 // OpenCVExerciseTesting.cpp : 定义控制台应用程序的入口点。
      2 //
      3 //    string file_full_name = "D:\Work\Work_Programming\Source\Image\OpenCVExerciseImage\第8章\r20.jpg";
      4 
      5 
      6 #include "stdafx.h"
      7 #include<string>
      8 #include <cv.h>
      9 #include <highgui.h>
     10 #include <iostream>
     11 #include<math.h>
     12 
     13 #include <opencv2/legacy/legacy.hpp>
     14 //#pragma comment(lib, "opencv_legacy2411.lib")
     15 
     16 using namespace cv;
     17 using namespace std;
     18 
     19 //函数声明-->--->-->--->-->--->-->--->//
     20 //void imRotate(IplImage *src, IplImage *dst, double angle, CvPoint2D32f center, double scale);
     21 
     22 IplImage * ImageZoomOrRotatopn(IplImage * image, double scale=1.0, double angle=0.0);
     23 void CalcHuMoments(IplImage * image_source, string window_name);
     24 void CalcHuMoments2(IplImage * image_source, string window_name);
     25 
     26 //<--<--<--<--<--<--<--<--<--函数声明//
     27 
     28 int _tmain(int argc, _TCHAR* argv[])
     29 {
     30     string file_full_name = "D:\Work\Work_Programming\Source\Image\OpenCVExerciseImage\第8章\字符A.jpg";
     31     IplImage * image_source = cvLoadImage(file_full_name.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
     32     CV_Assert(image_source);
     33     
     34     //原始图像
     35     string window_name = "字符A原始图像";
     36     CalcHuMoments(image_source, window_name);
     37 
     38 
     39     //旋转图像
     40     IplImage *image_1 = ImageZoomOrRotatopn(image_source, 1.0, 73);
     41     window_name = "字符A旋转73度图像";
     42     CalcHuMoments(image_1, window_name);
     43 
     44     //缩放图像
     45     IplImage *image_2 = ImageZoomOrRotatopn(image_source, 1.5, 0.0);
     46     window_name = "字符A放大1.5倍图像";
     47     CalcHuMoments(image_2, window_name);
     48 
     49 
     50     file_full_name = "D:\Work\Work_Programming\Source\Image\OpenCVExerciseImage\第8章\字符F.jpg";
     51     IplImage * image_other = cvLoadImage(file_full_name.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
     52     CV_Assert(image_other);
     53 
     54     //其它图像测试
     55     window_name = "其它图像";
     56     CalcHuMoments(image_other, window_name);
     57 
     58     //==============================================================================
     59 
     60     cout << endl << endl;
     61 
     62     //不使用cvDrawContour画的轮廓计算矩,直接使用cvFindContour的结果
     63     IplImage * image_temp = cvCloneImage(image_source);
     64     CalcHuMoments2(image_temp, window_name);
     65 
     66     CalcHuMoments2(image_1, window_name);
     67 
     68     CalcHuMoments2(image_2, window_name);
     69 
     70     CalcHuMoments2(image_other, window_name);
     71 
     72     //system("pause");
     73     cvWaitKey(0);
     74 
     75     //cvReleaseImage(&image_source);
     76     //cvReleaseImage(&image_source_2);
     77     cvDestroyAllWindows();
     78 
     79     return 0;
     80 }
     81 
     82 IplImage * ImageZoomOrRotatopn(IplImage * image, double scale, double angle)
     83 {
     84     IplImage * affinedImage = cvCloneImage(image);
     85     CvMat *rot_mat = cvCreateMat(2, 3, CV_32FC1);
     86     CvPoint2D32f center = cvPoint2D32f(image->width / 2, image->height / 2);
     87     cv2DRotationMatrix(center, angle, scale, rot_mat);
     88     cvWarpAffine(image, affinedImage, rot_mat);
     89     return affinedImage;
     90 }
     91 
     92 void CalcHuMoments(IplImage * image_source,string window_name)
     93 {
     94     CvMoments moments;
     95     CvHuMoments  Hu_moments;
     96     IplImage * image_contour = cvCloneImage(image_source);
     97     cvZero(image_contour);
     98 
     99     IplImage * image_binary = cvCloneImage(image_source);
    100     cvZero(image_binary);
    101     cvThreshold(image_source, image_binary, 100, 255, CV_THRESH_BINARY);//重要,调用从vFindContour前先二值化图像
    102 
    103     CvMemStorage *storage = cvCreateMemStorage();
    104     CvSeq * first_contour=NULL;
    105     int contour_num;
    106     contour_num = cvFindContours(image_binary, storage, &first_contour);// , sizeof(CvContour), CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
    107     cvDrawContours(image_contour, first_contour, cvScalar(255), cvScalar(255), 5);//重要,将轮廓绘制到图像,供下一步调用
    108 
    109     cvShowImage(window_name.c_str(), image_contour);
    110 
    111     cvMoments(image_contour, &moments, 1);
    112     cvGetHuMoments(&moments, &Hu_moments);
    113     cout << window_name<< "Hu矩结果:" << endl;
    114     cout << setiosflags(ios::scientific) << setprecision(4) << Hu_moments.hu1 << " ";
    115     cout << Hu_moments.hu2 << " ";
    116     cout << Hu_moments.hu3 << " ";
    117     cout << Hu_moments.hu4 << " ";
    118     cout << Hu_moments.hu5 << " ";
    119     cout << Hu_moments.hu6 << " ";
    120     cout << Hu_moments.hu7 << endl;
    121 
    122     //cout << "(" << setprecision(3) << dec <</* scalar <<*/ ")" << " ";
    123     //for (int i = 0; i<7; ++i){
    124     //    cout << setiosflags(ios::scientific) << setprecision(4) << ((double*)&Hu_moments)[i] << ' ';
    125     //}
    126     //cout << endl;
    127 
    128     cvReleaseImage(&image_contour);
    129     cvReleaseImage(&image_binary);
    130     cvClearSeq(first_contour);
    131     cvReleaseMemStorage(&storage);
    132 }
    133 
    134 void CalcHuMoments2(IplImage * image_source, string window_name)
    135 {
    136     CvMemStorage *storage = cvCreateMemStorage();
    137     CvSeq * contour = NULL;
    138 
    139     cvThreshold(image_source, image_source, 100, 255, CV_THRESH_BINARY);
    140 
    141     cvFindContours(image_source, storage, &contour);
    142     //cvShowImage(window_name.c_str(), image_source);
    143     CvMoments moments;
    144     CvHuMoments huMoments;
    145     cvMoments(image_source, &moments, 1);
    146     cvGetHuMoments(&moments, &huMoments);
    147 
    148     cout << "CalcHuMoments2输出" << endl;
    149     ////cout << "(" << setprecision(3) << dec << scalar << ")" << " ";
    150     //for (int i = 0; i<7; ++i){
    151     //    cout << setiosflags(ios::scientific) << setprecision(4) << ((double*)&huMoments)[i] << ' ';
    152     //}
    153     //cout << endl;
    154     cout << window_name << "Hu矩结果:" << endl;
    155     cout << setiosflags(ios::scientific) << setprecision(4) << huMoments.hu1 << " ";
    156     cout << huMoments.hu2 << " ";
    157     cout << huMoments.hu3 << " ";
    158     cout << huMoments.hu4 << " ";
    159     cout << huMoments.hu5 << " ";
    160     cout << huMoments.hu6 << " ";
    161     cout << huMoments.hu7 << endl;
    162 
    163     cvClearSeq(contour);
    164     cvReleaseMemStorage(&storage);
    165 }
    166 
    167 //void imRotate(IplImage *src, IplImage *dst, double angle, CvPoint2D32f center, double scale)
    168 //{
    169 //    assert(src->width == dst->width && src->height == dst->height &&src->depth == dst->depth &&src->nChannels == dst->nChannels);
    170 //    CvMat *mapMatrix = cvCreateMat(2, 3, CV_32FC1);
    171 //    cv2DRotationMatrix(center, angle, scale, mapMatrix); //旋转缩放为仿射变换,此处求变换矩阵
    172 //
    173 //    cvWarpAffine(src, dst, mapMatrix);
    174 //}

    结果图片:

    要言妙道:

     ①函数 cvFindContours 从二值图像寻找图像。此二值图像可以是从cvCanny函数得到的有边缘像素的图像,或者是从cvThreshold及cvAdaptiveThreshold得到的图像,这时的边缘是正合负区域之间的边界。如果在cvFindContours前没有二值化图像,会发现本练习第一个原始图像找轮廓后画出的轮廓没有结果,而且最后的hu矩完全无规律

    ② 一个有用的小技巧是:用从vDrawContour描绘一幅轮廓的图像后,调用一个矩的处理函数处理该图像

    ③再次强调 cvFindContour 的输入图像会直接被涂改

    借鉴参考:

  • 相关阅读:
    windowsCE常用编译参数 及编译器列表
    摘抄System Architecture for Native Device Drivers
    django+vue学习系列
    FreeTextBox的ToolbarButton整理
    FreeTextBox实现机制
    Server的Transfer和Response的Redirect
    FTB2.0和CuteEditor的一些问题
    ASP.NET跨应用程序进行登录的解决
    testFTB2.0
    Rainbow分页解决方案
  • 原文地址:https://www.cnblogs.com/tingshuixuan2012/p/4525696.html
Copyright © 2011-2022 走看看