交互贝塞尔曲线

#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/opencv.hpp>
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=a;i<=b;++i)

using namespace cv;
using namespace std;

int n,cnt;
vector<Point2f>a,b;

Mat src;
Mat dst;
Point2f pre_pt ,fir_pt;
Point2f cur_pt ;
double xmin,xmax,ymin,ymax,k;
int flag;

Point2f recursive_bezier(float t) 
{
    int n=(int)a.size();
    vector<Point2f> k(n);
    vector<Point2f> w(n);
    for(int i=0;i<n;i++) w[i]=a[i];
    while(w.size()>1){
         k.clear();
         n=(int)w.size();
         for(int i=0;i<n-1;i++){
             k.push_back((w[i])*(1-t)+w[i+1]*(t));
         }
         w.clear();
         n=(int)k.size();
         for(int i=0;i<n;i++){
             w.push_back(k[i]);
         }
    }
    return w[0];
}


void bezier(){
    for (double t = 0.0; t <= 1.0; t += 0.0001)
    {
        auto point = recursive_bezier(t);
        //window.at<Vec3b>(point.y, point.x)[1] = 255;//绿色
        circle(src, Point2f(point.x,point.y), 1, Scalar(255,255,255), FILLED, 0);
    }
    imshow("bezier_curve", src);
}

void on_mouse(int event, int x, int y, int flags, void* ustc){
    if (event == EVENT_LBUTTONDOWN){
        cnt++;
        a.push_back(Point(x,y));
        if(cnt==1){
            pre_pt=Point(x,y);
            fir_pt=pre_pt;
            circle(src, fir_pt, 4, Scalar(255,255,255), FILLED, 0);
            imshow("bezier_curve", src);
        }
        if(cnt>1&&cnt<=n){
            cur_pt=Point(x,y);
            circle(src, cur_pt, 4, Scalar(255,255,255), FILLED, 0);
            line(src, pre_pt, cur_pt, Scalar(0, 255,0), 2, 4, 0);
            pre_pt=cur_pt;
            imshow("bezier_curve", src);
        }
        if(cnt==n){
            bezier();
            return;
        }
    }
}

void add(int event, int x, int y, int flags, void* ustc){
    if (event == EVENT_LBUTTONDOWN){
        a.push_back(Point(x,y));
        dst.copyTo(src);
        cnt=0;
        for(auto i:a){
            if(++cnt==1){
                circle(src, i, 4, Scalar(255,255,255), FILLED, 0);
            }
            else{
                circle(src, i, 4, Scalar(255,255,255), FILLED, 0);
                line(src, pre_pt, i, Scalar(0, 255,0), 2, 4, 0);
            }
            pre_pt=i;
        }
        bezier();
        return ;
    }
}


void init(){
    while(1){
        cin>>flag;
        switch (flag){
            case 1:{ //从0开始搭建贝塞尔曲线
                cout<<"请输入控制顶点的个数"<<endl;
                cin>>n;
                while(n<3){
                    cout<<"个数不能小于3呀😁,请重新输入"<<endl;
                    cin>>n;
                }
                imshow("bezier_curve", src);
                cnt=0;
                setMouseCallback("bezier_curve", on_mouse, 0);
                int kikk=-1;
                while(kikk != 27){
                    kikk=waitKey(0);
                    cout<<kikk<<endl;
                    if(kikk==27){
                        
                        break;
                    }
                }
               // if(waitKey(0)=='q') break;
                break;
            }
            case 2:{ //删除最后一个点..
                if(n==3){
                    cout<<"不能再删除啦,再删除都快没了..."<<endl;
                }
                else{
                    a.pop_back();
                    dst.copyTo(src);
                    cnt=0;
                    for(auto i:a){
                        if(++cnt==1){
                            circle(src, i, 4, Scalar(255,255,255), FILLED, 0);
                        }
                        else{
                            circle(src, i, 4, Scalar(255,255,255), FILLED, 0);
                            line(src, pre_pt, i, Scalar(0, 255,0), 2, 4, 0);
                        }
                        pre_pt=i;
                    }
                    imshow("bezier_curve", src);
                    bezier();
                }
                break;
            }
            case 3:{ //在最后添加一个点
                imshow("bezier_curve", src);
                setMouseCallback("bezier_curve", add, 0);
            }
        }
    }
}

int main(){
    namedWindow("bezier_curve", WINDOW_AUTOSIZE);
    src=Mat(1000, 1000, CV_8UC3, Scalar(0));
    src.copyTo(dst);
    init();
    //setMouseCallback("bezier_curve", on_mouse, 0);
    imshow("bezier_curve", src);
    waitKey(0);
    return 0;
}

 

posted @ 2020-09-06 10:55  WeiAR  阅读(191)  评论(0编辑  收藏  举报