Note that there are some explanatory texts on larger screens.

plurals
  1. POOpenCV, how to use arrays of points for smoothing and sampling contours?
    primarykey
    data
    text
    <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>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload