opencv轮廓逼近的精度参数与周长cvContourPerimeter的汇总

1)CV_Assert():若括号中的表达式值为false,则返回一个错误信息。

函数原型是:#define CV_Assert( expr ) if((expr)) ; else cv::error

( cv::Exception(CV_StsAssert, #expr, "", __FILE__, __LINE__) )


2)cvContourPerimeter:函数作用于一个轮廓并返回其长度。事实上,

这个函数是一个调用通用函数cvArcLength的宏。
double cvArcLength(const void *curve,CvSlice slice =CV_WHOLE_SEQ,
int is_closed=-1);

curve:第一个参数是轮廓,其形式可以是点的序列(CvContour *或CvSeq *)

或任一n*2的点的数组。
slice:表面是否将轮廓视为闭合的一个布尔类型(例如,是否将轮廓的

最后一个点视为和第一个点有连接)。
slice可以让我们只选择曲线(curve)上的点的部分集合。

#define cvContourPerimeter(contour)  

cvArcLength(contour,CV_WHOLE_SEQ,1)


代码:

#include<string>
#include <cv.h>
#include <highgui.h>
#include <iostream>
#include<math.h>
#include <opencv2/legacy/legacy.hpp>
using namespace cv;
using namespace std;
int main()
{
cvNamedWindow("ff",1);
    string file_full_name = "D:\\VC98\\C++项目\\opencv\\cvContourPerimeter\\cvContourPerimeter\\a4.png";
    IplImage * image_source = cvLoadImage(file_full_name.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
    CV_Assert(image_source);//若括号中的表达式值为false,则返回一个错误信息。
    IplImage * image_binary = cvCloneImage(image_source);
    cvZero(image_binary);
//在二值化图像的过程中,阀值很关键,将决定黑白化的效果。
    cvThreshold(image_source, image_binary, 205, 255, CV_THRESH_BINARY);//二值化
cvShowImage("ff",image_binary);

    CvMemStorage *storage = cvCreateMemStorage();
    CvSeq* first_contour=NULL;
    int contour_num;
    contour_num = cvFindContours(image_binary, storage, &first_contour, sizeof(CvContour), CV_RETR_LIST);//轮廓获取

    cout << "轮廓数为:" << contour_num << endl; 
    double contour_length;
    //for (CvSeq * c = first_contour; c != NULL; c = c->h_next)
    //{
    //    contour_length = cvContourPerimeter(c);
    //    cout << "周长" << contour_length << endl;
    //}
    contour_length = cvContourPerimeter(first_contour);//计算轮廓长度
    cout << "周长为:";
cout<< contour_length << endl;

    double perimeter = 126.7;//轮廓精度
    double parameters[4] = { 126.7 / 90, 126.7 / 66, 126.7 / 11, 126.7 / 10 };
    CvMemStorage* storage_approx = cvCreateMemStorage();
    IplImage *image_approx = cvCloneImage(image_binary);
    cvZero(image_approx);
    CvSeq *seq_approx=NULL;
    
    string window_name = "Approx窗口";
    for (int i = 0; i < 4; ++i)
    {   //分别用4中精度来进行多边形逼近轮廓,是一个轮廓
        seq_approx = cvApproxPoly(first_contour, sizeof(CvContour), storage_approx, CV_POLY_APPROX_DP, parameters[i], 0);
        contour_length = cvContourPerimeter(seq_approx);//每一次都计算出逼近轮廓的长度,也是一个轮廓
        cout << i<<":"<<contour_length << endl;
        window_name = window_name + "1";//区别4个窗口
        cvDrawContours(image_approx, seq_approx, cvScalar(255), cvScalar(125), 0);//画出轮廓
        cvShowImage(window_name.c_str(), image_approx);
if(i==0) 
cvSaveImage("result.jpg",image_approx);
if(i==1) 
cvSaveImage("result1.jpg",image_approx);
if(i==2) 
cvSaveImage("result2.jpg",image_approx);
if(i==3) 
cvSaveImage("result3.jpg",image_approx);
    }  
    cvWaitKey(0);
    cvReleaseImage(&image_source);
    cvReleaseImage(&image_binary);
    cvReleaseImage(&image_approx);
    cvDestroyAllWindows();
    return 0;
}

结果:输入一个椭圆图:

opencv轮廓逼近的精度参数与周长cvContourPerimeter的汇总_第1张图片

一下图的精度参数分别对应: 126.7 / 90,126.7 / 66, 126.7 / 11, 126.7 / 10 

opencv轮廓逼近的精度参数与周长cvContourPerimeter的汇总_第2张图片 图1

opencv轮廓逼近的精度参数与周长cvContourPerimeter的汇总_第3张图片图2,

opencv轮廓逼近的精度参数与周长cvContourPerimeter的汇总_第4张图片图3

opencv轮廓逼近的精度参数与周长cvContourPerimeter的汇总_第5张图片图4,

opencv轮廓逼近的精度参数与周长cvContourPerimeter的汇总_第6张图片

椭圆内部的折线就是多边形逼近轮廓的过程。不难发现,parameters精度参数值越小,

精度要求越大,多边形逼近越接近实际轮廓。



你可能感兴趣的:(opencv,图像处理)