【OpenCV学习】绘制贝赛尔曲线

简介: 作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ // TrainingTools.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.

作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/

// TrainingTools.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <string.h>
#include <cxcore.h>
#include <cv.h>
#include <highgui.h>
#include <fstream>

using namespace std;

const int WW_MAX_MARK_COUNT = 40; //最大40个控制点
int mark_count =4;
int conner_pt_index =-1;
CvPoint3D32f Control_pts[WW_MAX_MARK_COUNT];
IplImage *image = 0 ; //原始图像
bool is_showControlLines = true;


// 两个向量相加,p=p+q
CvPoint3D32f pointAdd(CvPoint3D32f p, CvPoint3D32f q) {
    p.x += q.x;        p.y += q.y;        p.z += q.z;
    return p;
}

// 向量和标量相乘p=c*p
CvPoint3D32f pointTimes(float c, CvPoint3D32f p) {
    p.x *= c;    p.y *= c;    p.z *= c;
    return p;
}

// 计算贝塞尔方程的值
// 变量u的范围在0-1之间
//P1*t^3 + P2*3*t^2*(1-t) + P3*3*t*(1-t)^2 + P4*(1-t)^3 = Pnew 
CvPoint3D32f Bernstein(float u, CvPoint3D32f *p) {
    CvPoint3D32f    a, b, c, d, r;

    a = pointTimes(pow(u,3), p[0]);
    b = pointTimes(3*pow(u,2)*(1-u), p[1]);
    c = pointTimes(3*u*pow((1-u),2), p[2]);
    d = pointTimes(pow((1-u),3), p[3]);

    r = pointAdd(pointAdd(a, b), pointAdd(c, d));

    return r;
}

//画控制线
void DrawControlLine(CvPoint3D32f *p) {
    
    CvPoint pc[4];
    for(int i=0;i<4;i++)
    {
        pc[i].x = (int)p[i].x;
        pc[i].y = (int)p[i].y;
    }

    cvLine(image,pc[0],pc[1],CV_RGB(0,0,255),1,CV_AA,0);
    cvLine(image,pc[2],pc[3],CV_RGB(0,0,255),1,CV_AA,0);    
}

//得到最近Control_pts的index
int getNearPointIndex(CvPoint mouse_pt)
{
    CvPoint pt;
    for(int i =0; i<mark_count;i++)
    {
        pt.x= mouse_pt.x - (int)Control_pts[i].x;
        pt.y= mouse_pt.y - (int)Control_pts[i].y;
        float distance = sqrt ((float)( pt.x*pt.x + pt.y*pt.y ));
        if(distance<10) return i;
        
    }
    return -1;
}

void on_mouse( int event, int x, int y, int flags, void *param )
{
    if( event == CV_EVENT_LBUTTONDOWN )
    {
        CvPoint pt = cvPoint(x,y);        
        //cout<<x<<","<<y<<endl;
        
        if(conner_pt_index >-1)
            conner_pt_index = -1;
        else
        {
            conner_pt_index = getNearPointIndex(pt);    
            //添加新的控制点
            if(conner_pt_index==-1)
            {
                if(mark_count<=(WW_MAX_MARK_COUNT-1))
                {
                    Control_pts[mark_count].x = (float)pt.x;
                    Control_pts[mark_count].y = (float)pt.y;
                    Control_pts[mark_count].z = 0;
                    mark_count++;
                }
            }
        }
    } 
     else if ( event == CV_EVENT_MOUSEMOVE ) //修改控制点坐标
     {
        if(conner_pt_index >-1)
        {
            Control_pts[conner_pt_index].x = (float)x;
            Control_pts[conner_pt_index].y = (float)y;
        }
     }

};


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

    CvSize image_sz = cvSize( 1000,1000); 
    image = cvCreateImage(image_sz , 8, 3 );
    cvNamedWindow("Win",0);
    cvSetMouseCallback( "Win", on_mouse, 0 );
    cvResizeWindow("Win",500,500);

    cout<<"==============   Bezier curve DEMO  =============="<<endl;
    cout<<" "<<endl;
    cout<<"1.use mouse to click control point (red) to select a control point"<<endl;
    cout<<"2.use mouse to modify control point"<<endl;
    cout<<"3.click mouse on somewhere to add a control point,add three points for add a new curve"<<endl;
    cout<<"4.use 'W','S' to add precision or reduce precision."<<endl;
    cout<<"5.press 'Z' to show control points."<<endl;
    cout<<"===press ESC to exit==="<<endl;

    //初始化四个控制点
    Control_pts[0].x = 200;
    Control_pts[0].y = 200;
    Control_pts[0].z = 0;

    Control_pts[1].x = 300;
    Control_pts[1].y = 500;
    Control_pts[1].z = 0;

    Control_pts[2].x = 400;
    Control_pts[2].y = 560;
    Control_pts[2].z = 0;

    Control_pts[3].x = 500;
    Control_pts[3].y = 100;
    Control_pts[3].z = 0;
    
    int divs = 50; //控制精细度

    for(;;)
    {    
        
        CvPoint pt_now,pt_pre;
        cvZero(image);


        //绘制控制点
        if(is_showControlLines)
        {
            for(int i =0;i<mark_count;i++)
            {
                CvPoint ptc;
                ptc.x = (int) Control_pts[i].x;
                ptc.y = (int) Control_pts[i].y;
                cvCircle( image, ptc, 4, CV_RGB(255,0,0), 1,CV_AA, 0);    
            }
        }

        //绘制Bezier曲线
        CvPoint3D32f *pControls = Control_pts;
        for(int j=0;j<mark_count-3;j+=3)
        {            
            for (int i=0;i<=divs;i++) 
            {
                float u  = (float)i/divs;
                CvPoint3D32f newPt = Bernstein(u,pControls);                

                pt_now.x = (int)newPt.x;
                pt_now.y = (int)newPt.y;

                if(i>0)    cvLine(image,pt_now,pt_pre,CV_RGB(230,255,0),2,CV_AA, 0 );
                pt_pre = pt_now;
            }

            //画控制线
            if(is_showControlLines)DrawControlLine(pControls);
            pControls+=3;
        }
        
        cvShowImage("Win",image);
        int keyCode = cvWaitKey(20);
        if (keyCode==27) break;
        if(keyCode=='w'||keyCode=='W') divs+=2; 
        if(keyCode=='s'||keyCode=='S') divs-=2; 
        if(keyCode=='z'||keyCode=='Z') is_showControlLines = is_showControlLines^1;
        
        //cout<<"precision : "<<divs<<endl;

    }
    return 0;
}


作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/


               作者:gnuhpc
               出处:http://www.cnblogs.com/gnuhpc/
               除非另有声明,本网站采用知识共享“署名 2.5 中国大陆”许可协议授权。


分享到:

目录
相关文章
|
7月前
|
机器学习/深度学习 存储 数据库
Python3 OpenCV4 计算机视觉学习手册:6~11(5)
Python3 OpenCV4 计算机视觉学习手册:6~11(5)
90 0
|
7月前
|
存储 资源调度 算法
Opencv(C++)系列学习---SIFT、SURF、ORB算子特征检测
Opencv(C++)系列学习---SIFT、SURF、ORB算子特征检测
370 0
|
7月前
|
机器学习/深度学习 算法 数据可视化
计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)-2
计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)
|
7月前
|
机器学习/深度学习 Ubuntu Linux
计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)-1
计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)
|
6月前
|
机器学习/深度学习 人工智能 自然语言处理
OpenCV与AI深度学习之常用AI名词解释学习
AGI:Artificial General Intelligence (通用人工智能):是指具备与人类同等或超越人类的智能,能够表现出正常人类所具有的所有智能行为。又被称为强人工智能。
136 2
|
7月前
|
机器学习/深度学习 算法 数据挖掘
Python3 OpenCV4 计算机视觉学习手册:6~11(2)
Python3 OpenCV4 计算机视觉学习手册:6~11(2)
133 0
|
5月前
|
计算机视觉 Python
opencv 处理图像去噪的几种方法学习
OpenCV 提供了多种图像去噪的方法,以下是一些常见的去噪技术以及相应的 Python 代码示例: 均值滤波:使用像素邻域的灰度均值代替该像素的值。
70 0
|
6月前
|
机器学习/深度学习 开发框架 TensorFlow
### 如何系统化学习OpenCV4
### 如何系统化学习OpenCV4
43 0
|
7月前
|
算法 计算机视觉 Python
【OpenCV】-算子(Sobel、Canny、Laplacian)学习
【OpenCV】-算子(Sobel、Canny、Laplacian)学习
213 2
|
7月前
|
存储 计算机视觉
OpenCV—学习基本绘图
OpenCV—学习基本绘图