发新帖

基于OpenCV的椭圆曲线拟合

[复制链接]
3099 5
程序首先发现图像轮廓,然后用椭圆逼近它
效果图:
QQ截图20150509193446.jpg
[C++] 纯文本查看 复制代码
还是用ps的魔棒工具感觉更好。
源代码:
#include "cv.h"
#include "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*)"2.jpg";
    
    // 读入图像,强制为灰度图像
    if( (image03 = cvLoadImage(filename, 0)) == 0 )
        return -1;
    // Create the destination images
    image02 = cvCloneImage( image03 );
    image04 = cvCloneImage( image03 );
    // Create windows.
    cvNamedWindow("Source", 1);
    cvNamedWindow("Result", 1);
    // Show the image.
    cvShowImage("Source", image03);
    // Create toolbars. HighGUI use.
    cvCreateTrackbar( "Threshold", "Result", &slider_pos, 255, process_image );
    process_image(0);
    // Wait for a key stroke; the same function arranges events processing                
    cvWaitKey(0);
    cvReleaseImage(&image02);
    cvReleaseImage(&image03);
    cvDestroyWindow("Source");
    cvDestroyWindow("Result");
    return 0;
}
// Define trackbar callback functon. This function find contours,
// draw it and approximate it by ellipses.
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));
    
    // Clear images. IPL use.
    cvZero(image02);
    cvZero(image04);
    
    // 本循环绘制所有轮廓并用椭圆拟合.
    for(;cont;cont = cont->h_next)
    {   
        int i; // Indicator of cycle.
        int count = cont->total; // This is number point in contour
        CvPoint center;
        CvSize size;
        
        // Number point must be more than or equal to 6 (for cvFitEllipse_32f).        
        if( count < 6 )
            continue;
        
        // Alloc memory for contour point set.    
        PointArray = (CvPoint*)malloc( count*sizeof(CvPoint) );
        PointArray2D32f= (CvPoint2D32f*)malloc( count*sizeof(CvPoint2D32f) );
        
        // Alloc memory for ellipse data.
        box = (CvBox2D32f*)malloc(sizeof(CvBox2D32f));
        
        // Get contour point set.
        cvCvtSeqToArray(cont, PointArray, CV_WHOLE_SEQ);
        
        // Convert CvPoint set to CvBox2D32f set.
        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));
        
        // Convert ellipse data from float to integer representation.
        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;
        
        // Draw ellipse.
        cvEllipse(image04, center, size,
                  box->angle, 0, 360,
                  CV_RGB(0,0,255), 1, CV_AA, 0);
        
        // Free memory.          
        free(PointArray);
        free(PointArray2D32f);
        free(box);
    }
    
    // Show image. HighGUI use.
    cvShowImage( "Result", image04 );
}



举报 使用道具

回复

精彩评论5

58421604  注册会员  发表于 2015-8-17 18:55:25 | 显示全部楼层
很不错

举报 使用道具

回复 支持 反对
jhc  注册会员  发表于 2015-8-17 18:43:14 | 显示全部楼层
真心顶

举报 使用道具

回复 支持 反对
菜菜龙  注册会员  发表于 2015-8-17 19:20:51 | 显示全部楼层
说的非常好

举报 使用道具

回复 支持 反对
姜自好  注册会员  发表于 2015-8-17 19:02:15 | 显示全部楼层
不错不错

举报 使用道具

回复 支持 反对
58421604  注册会员  发表于 2015-8-17 19:15:44 | 显示全部楼层
LZ真是人才

举报 使用道具

回复 支持 反对
*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

更多

关注我们

QQ:448109455 周一至周日8:30-20:30
快速回复 返回顶部 返回列表