title: OpenCV, how to use arrays of points for smoothing and sampling contours?
body: <p>I have a problem to get my head around smoothing and sampling contours in OpenCV (C++ API).
  Lets say I have got  sequence of points retrieved from <code>cv::findContours</code> (for instance applied on this this image:</p>
  
  <p><img src="https://i.stack.imgur.com/u9phq.png" alt="enter image description here"></p>
  
  <p>Ultimately, I want </p>
  
  <ol>
  <li>To smooth a sequence of points using different kernels.</li>
  <li>To resize the sequence using different types of interpolations.</li>
  </ol>
  
  <p>After smoothing, I hope to have a result like :</p>
  
  <p><img src="https://i.stack.imgur.com/l5zqM.png" alt="enter image description here"></p>
  
  <p>I also considered drawing my contour in a <code>cv::Mat</code>, filtering the Mat (using blur or morphological operations) and re-finding the contours, but is slow and suboptimal. So, ideally, I could do the job using exclusively the point sequence.</p>
  
  <p>I read a few posts on it and naively thought that I could simply convert a <code>std::vector</code>(of <code>cv::Point</code>) to a <code>cv::Mat</code> and then OpenCV functions like blur/resize would do the job for me... but they did not.</p>
  
  <p>Here is what I tried:</p>
  
  <pre><code>int main( int argc, char** argv ){
  
      cv::Mat conv,ori;
      ori=cv::imread(argv[1]);
      ori.copyTo(conv);
      cv::cvtColor(ori,ori,CV_BGR2GRAY);
  
      std::vector&lt;std::vector&lt;cv::Point&gt; &gt; contours;
      std::vector&lt;cv::Vec4i &gt; hierarchy;
  
      cv::findContours(ori, contours,hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);
  
      for(int k=0;k&lt;100;k += 2){
          cv::Mat smoothCont;
  
          smoothCont = cv::Mat(contours[0]);
          std::cout&lt;&lt;smoothCont.rows&lt;&lt;"\t"&lt;&lt;smoothCont.cols&lt;&lt;std::endl;
          /* Try smoothing: no modification of the array*/
  //        cv::GaussianBlur(smoothCont, smoothCont, cv::Size(k+1,1),k);
          /* Try sampling: "Assertion failed (func != 0) in resize"*/
  //        cv::resize(smoothCont,smoothCont,cv::Size(0,0),1,1);
          std::vector&lt;std::vector&lt;cv::Point&gt; &gt; v(1);
          smoothCont.copyTo(v[0]);
          cv::drawContours(conv,v,0,cv::Scalar(255,0,0),2,CV_AA);
          std::cout&lt;&lt;k&lt;&lt;std::endl;
          cv::imshow("conv", conv);
          cv::waitKey();
      }
      return 1;
  }
  </code></pre>
  
  <p>Could anyone explain how to do this ?</p>
  
  <p>In addition, since I am likely to work with much smaller contours, I was wondering how this approach would deal with border effect (e.g.  when smoothing, since contours are circular, the last elements of a sequence must be used to calculate the new value of the first elements...)</p>
  
  <p>Thank you very much for your advices,</p>
  
  <p><strong>Edit:</strong></p>
  
  <p>I also tried <code>cv::approxPolyDP()</code> but, as you can see, it tends to preserve extremal points (which I want to remove):</p>
  
  <p>Epsilon=0</p>
  
  <p><img src="https://i.stack.imgur.com/FjWRq.png" alt="enter image description here"></p>
  
  <p>Epsilon=6</p>
  
  <p><img src="https://i.stack.imgur.com/RWjMP.png" alt="enter image description here"></p>
  
  <p>Epsilon=12</p>
  
  <p><img src="https://i.stack.imgur.com/AcEcs.png" alt="enter image description here"></p>
  
  <p>Epsilon=24</p>
  
  <p><img src="https://i.stack.imgur.com/XIgk1.png" alt="enter image description here"></p>
  
  <p><strong>Edit 2:</strong>
  As suggested by Ben, it seems that <code>cv::GaussianBlur()</code> is not supported but <code>cv::blur()</code> is. It looks very much closer to my expectation. Here are my results using it:</p>
  
  <p>k=13</p>
  
  <p><img src="https://i.stack.imgur.com/zHwLE.png" alt="enter image description here"></p>
  
  <p>k=53</p>
  
  <p><img src="https://i.stack.imgur.com/ipifp.png" alt="enter image description here"></p>
  
  <p>k=103</p>
  
  <p><img src="https://i.stack.imgur.com/1jVbW.png" alt="enter image description here"></p>
  
  <p>To get around the border effect, I did:</p>
  
  <pre><code>    cv::copyMakeBorder(smoothCont,smoothCont, (k-1)/2,(k-1)/2 ,0, 0, cv::BORDER_WRAP);
      cv::blur(smoothCont, result, cv::Size(1,k),cv::Point(-1,-1));
      result.rowRange(cv::Range((k-1)/2,1+result.rows-(k-1)/2)).copyTo(v[0]);
  </code></pre>
  
  <p>I am still looking for solutions to interpolate/sample my contour.</p>