c++ - OpenCV - Fit a curve to a set of points -


this follows post here: opencv - remove "white" artifacts image , fit curve

i removed extraneous white points in image looking points across diagonal @ given location. result looks this:

remove diag

now, fit curve remaining points in image. have been looking through previous posts in opencv have suggested approxpolydp. there simpler way of fitting curve , displaying in opencv?

the idea here using hough curves little elaborate me since image binary: http://homepages.inf.ed.ac.uk/rbf/books/bandb/lib/bandb4_3.pdf

the final image (0-255) grayscale image of w256 x h1024.

edit

i connected points in image using line segments. however, connect points fitting smooth curve of them. have searched such method , not find way.

connect

i think catmul-rom spline choice task.

you can find implementation here: http://www.codeproject.com/articles/30838/overhauser-catmull-rom-splines-for-camera-animatio

answer ahf's comment (put here qix advice):

this code sketch allows edit spline mouse uses files this link (attach project: overhauser.cpp overhauser.hpp , vec3.hpp):

left mouse button adds/moves point, right removes.

the code not difficult, i've made 1-channel modification (for compactness).

i guess you'll catch idea.

enter image description here

#include <iostream> #include <vector> #include <stdio.h> #include <functional> #include <algorithm> #include <numeric> #include <cstddef> #include "opencv2/opencv.hpp" #include <iostream> #include <fstream> #include "overhauser.hpp"  using namespace std; using namespace cv;  mat result; mat img;  vector<cv::point2f> pts; mat curvesimg; int selectedpt=-1; crspline* spline = 0;  unsigned char lut_red[256];  // case-insensitive comparison function: bool mycomp (point2f p1, point2f p2) {     return p1.x<p2.x; }  float dist(point2f p1,point2f p2) {     return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); }  int findnearestpt(point2f pt, float maxdist) {     float mindist=flt_max;     int ind=-1;     for(int i=0;i<pts.size();++i)     {         float d=dist(pt,pts[i]);         if(mindist>d)         {             ind=i;             mindist=d;         }     }     if(mindist>maxdist)     {         ind=-1;     }     return ind; }  float f(float t,float x) {   vec3 rv = spline->getinterpolatedsplinepoint(t);   return x-rv.x; }  float solveforx(float x) {     float a=0,b=1.0,c,e=1e-5;     c=(a+b)/2;     while( (fabs(b-a)>e) && (f(c,x)!=0) )     {         if (f(a,x)*f(c,x)<0)         {             b=c;         }         else         {             a=c;         }         c=(a+b)/2;     } return c; }   int ind=-1;  void mousehandler(int event, int x, int y, int flags, void* param) {     point2f m;     m.x=x;     m.y=y;     curvesimg=scalar(0,0,0);      switch (event)     {     case cv::event_rbuttondown:         ind=findnearestpt(m,5);         if (ind==-1)         {          }else         {             pts.erase(pts.begin()+ind);             ind=-1;         }         break;     case cv::event_lbuttondown:         ind=findnearestpt(m,5);         if (ind==-1)         {             pts.push_back(m);             selectedpt=pts.size()-1;         }else         {             selectedpt=ind;         }         break;     case cv::event_mousemove:         if(ind!=-1)         {             pts[selectedpt].x=m.x;             pts[selectedpt].y=m.y;         }         break;     case cv::event_lbuttonup:         ind=-1;         break;     }      std::sort(pts.begin(),pts.end(),mycomp);     if(pts.size()>0)     {         pts[pts.size()-1].x=curvesimg.cols;         pts[0].x=0;     }      for(int i=0;i<pts.size();++i)     {         circle(curvesimg,pts[i],5,scalar(0,255,255),-1,cv_aa);     }      if (spline) {delete spline;}     spline = new crspline();      (int i=0;i<pts.size();++i)     {         vec3 v(pts[i].x,pts[i].y,0);         spline->addsplinepoint(v);     }      vec3 rv_last(0,0,0);     if(pts.size()>2)     {         for(int i=0;i<256;++i)         {             float t=solveforx(i);             vec3 rv = spline->getinterpolatedsplinepoint(t);             unsigned char i=(unsigned char)(rv.y);             lut_red[i]=255-i;             if(i>1)             {                 line(curvesimg,point(rv.x,rv.y),point(rv_last.x,rv_last.y),scalar(0,0,255),1);             }             rv_last=rv;         }     }      line(curvesimg,point(0,m.y),point(curvesimg.cols,m.y),scalar(0,255,0),1);     line(curvesimg,point(m.x,0),point(m.x,curvesimg.rows),scalar(0,255,0),1);      imshow("result",curvesimg);       vector<mat> ch;     cv::split(img,ch);      lut(ch[2],mat(256,1,cv_8uc1,lut_red),ch[2]);      cv::merge(ch,result);      imshow("transformed",result);    } // --------------------------------- //  // --------------------------------- //==============================================================================  int main( int argc, char** argv ) {      (int i=0;i<256;++i)     {         lut_red[i]=i;     }      namedwindow("image",cv::window_normal);     namedwindow("result");     namedwindow("transformed");      img=imread("d:\\imagesfortest\\lena.jpg",1);      imshow("image",img);      curvesimg=mat::zeros(256,256,cv_8uc3);     setmousecallback("result", mousehandler, null);     waitkey(0);      getchar(); } 

Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -