交互贝塞尔曲线
#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; }