现在的位置: 首页 > 综合 > 正文

OpenCV:椭圆拟合

2018年05月14日 ⁄ 综合 ⁄ 共 2075字 ⁄ 字号 评论关闭
<span style="font-size:14px;">#include <opencv\cv.h>
#include <opencv\highgui.h>

int slider_pos = 70;

IplImage *image02 = 0, *image03 = 0, *image04 = 0;
void process_image(int h);

int main( int argc, char** argv ){

    const char* filename = argc == 2 ? argv[1] : (char*)"rice.png";

    if( (image03 = cvLoadImage(filename, 0)) == 0 )
        return -1;

    image02 = cvCloneImage( image03 );
    image04 = cvCloneImage( image03 );

    cvNamedWindow("Source", 1);
    cvNamedWindow("Result", 1);

    cvShowImage("Source", image03);

    //创建滑块
    cvCreateTrackbar( "Threshold", "Result", &slider_pos, 255, process_image );

    process_image(0);

    cvWaitKey(0);
    cvReleaseImage(&image02);
    cvReleaseImage(&image03);

    cvDestroyWindow("Source");
    cvDestroyWindow("Result");

    return 0;
}

void process_image(int h){

    CvMemStorage* stor;
    CvSeq* cont;
    CvBox2D32f* box;
    CvPoint* PointArray;
    CvPoint2D32f* PointArray2D32f;

    stor = cvCreateMemStorage(0);
    cont = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , stor);

    // 二值化图像
    cvThreshold( image03, image02, slider_pos, 255, CV_THRESH_BINARY );

    // 查找所有轮廓
    cvFindContours( image02, stor, &cont, sizeof(CvContour),
                    CV_RETR_LIST, CV_CHAIN_APPROX_NONE, cvPoint(0,0));

    cvZero(image02);
    cvZero(image04);

    // 绘制所有轮廓并使用椭圆拟合
    for(;cont;cont = cont->h_next){

        int i;
        int count = cont->total;
        CvPoint center;
        CvSize size;

        if( count < 6 )
            continue;

        // 为轮廓点分配内存
        PointArray = (CvPoint*)malloc( count*sizeof(CvPoint) );
        PointArray2D32f= (CvPoint2D32f*)malloc( count*sizeof(CvPoint2D32f) );

        // 为椭圆分配内存
        box = (CvBox2D32f*)malloc(sizeof(CvBox2D32f));

        // 获取轮廓点集合
        cvCvtSeqToArray(cont, PointArray, CV_WHOLE_SEQ);

        // 转换CvPoint点集合为CvBox2D32f集合.
        for(i=0; i<count; i++){

            PointArray2D32f[i].x = (float)PointArray[i].x;
            PointArray2D32f[i].y = (float)PointArray[i].y;
        }

        // 椭圆拟合当前轮廓
        cvFitEllipse(PointArray2D32f, count, box);

        // 绘制当前轮廓
        cvDrawContours(image04,cont,CV_RGB(255,255,255),
                       CV_RGB(255,255,255),0,1,8,cvPoint(0,0));

        // 将椭圆数据从float转换为int类型
        center.x = cvRound(box->center.x);
        center.y = cvRound(box->center.y);
        size.width = cvRound(box->size.width*0.5);
        size.height = cvRound(box->size.height*0.5);
        box->angle = -box->angle;

        // 绘制椭圆
        cvEllipse(image04, center, size,
                  box->angle, 0, 360,
                  CV_RGB(0,0,255), 1, CV_AA, 0);

        // 释放内存
        free(PointArray);
        free(PointArray2D32f);
        free(box);
    }

    cvShowImage( "Result", image04 );
}
</span>

运行结果截图:

抱歉!评论已关闭.