# OpenCV Smoother contour

**URL:** <https://forum.opencv.org/t/opencv-smoother-contour/2305>\
**Category:** Python\
**Tags:** imgproc\
**Created:** [March 22, 2021, 8:03pm UTC](https://forum.opencv.org/t/opencv-smoother-contour/2305 "2021-03-22T20:03:33Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![martin\_o](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/martin_o/32/1486_2.png) [@martin\_o](https://forum.opencv.org/u/martin_o)\
**Post date:** [March 22, 2021, 8:03pm UTC](https://forum.opencv.org/t/opencv-smoother-contour/2305/1 "2021-03-22T20:03:33Z")

</div>

I am trying to solve the issue of creating paths around logos with OpenCV.  
I have attached two images, _tekst.png_ and _tekst2.png_. I have also attached an image _comparison.png_ that shows the wanted result (created manually) and the result I currently am getting with my program.

If anyone has any tips for me, I’d appreciate it a lot!

Short description of wanted solution:

- Returns one outer contour that is as close as possible to the logo.
- I can use the contour mentioned in the last sentence to scale it up to make padding in between the logo and the contour.
- Some kind of algorithm to smooth out the finished contour

The code I currently have:

```python

def current_milli_time():
    return round(time.time() * 1000)

def time_calculation_start():
    timing.append(current_milli_time())

def time_calculation_end(string):
    timing.append(current_milli_time())
    print(str(string) + ": ", timing[1] - timing[0], "ms")
    timing.clear()

def render_png(filename):
    print(filename)
    time_calculation_start()
    original_image = cv2.imread(str(filename), cv2.IMREAD_UNCHANGED)
    copy = original_image.copy() # Saved for imagecreation
    time_calculation_end("Setup")

    time_calculation_start()
    if(original_image.shape[2] == 4):
        b,g,r,mask = cv2.split(original_image)
    time_calculation_end("Mask")
    

    # Reduce outer turdss
    time_calculation_start()
    kernel = np.ones((3,3), np.uint8)
    dilation = cv2.dilate(mask,kernel,iterations = 2)
    dilation = cv2.erode(dilation,kernel,iterations = 1)
    time_calculation_end("Dialtion")
    time_calculation_start()
    gaublur = cv2.GaussianBlur(dilation,(16,16),0)
    time_calculation_end("Gaussian blur")

    #Find contours
    time_calculation_start()
    contours, hierarchy = cv2.findContours(gaublur, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    time_calculation_end("Find contours")
    
    print("\tContour layers: ", len(contours))

    # Draw contours
    time_calculation_start()
    cv2.drawContours(copy, contours, -1, (0, 255, 0, 255),1) 
    time_calculation_end("Draw contours")
    print("\n")

    cv2.imwrite(str(render_path) + str(filename), copy)

```

Stack overflow would not let me include these links due to “code formatting issues”  
[Tekst](https://i.imgur.com/cWVeBWS.png)  
[Comparison](https://i.stack.imgur.com/Wtmyt.jpg)

---

<div class="post-metadata">

**Author:** ![martin\_o](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/martin_o/32/1486_2.png) [@martin\_o](https://forum.opencv.org/u/martin_o)\
**Post date:** [March 22, 2021, 8:04pm UTC](https://forum.opencv.org/t/opencv-smoother-contour/2305/2 "2021-03-22T20:04:29Z")

</div>

Last link:  
[Tekst2](https://i.stack.imgur.com/4LEKH.png)

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [March 22, 2021, 8:34pm UTC](https://forum.opencv.org/t/opencv-smoother-contour/2305/3 "2021-03-22T20:34:22Z")

</div>

contours won’t solve this. too complex to achieve the same result as…

morphology operations. take the alpha channel (opacity mask), threshold it so any non-zero value becomes true/255, then dilate. structuring element (“kernel”) ought to be a nice big circle/ellipse.

first compose the picture onto white background, then apply the dilated mask to that.

I see that you already dilate the alpha channel… so you’re on the right track already. I don’t see why you’d involve contours then.

---

<div class="post-metadata">

**Author:** ![martin\_o](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/martin_o/32/1486_2.png) [@martin\_o](https://forum.opencv.org/u/martin_o)\
**Post date:** [March 22, 2021, 8:46pm UTC](https://forum.opencv.org/t/opencv-smoother-contour/2305/4 "2021-03-22T20:46:24Z")

</div>

The reason I have been using contours is so that I can export a vector path ( which is the intended output of this program)

---

<div class="post-metadata">

**Author:** ![martin\_o](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/martin_o/32/1486_2.png) [@martin\_o](https://forum.opencv.org/u/martin_o)\
**Post date:** [March 22, 2021, 10:52pm UTC](https://forum.opencv.org/t/opencv-smoother-contour/2305/5 "2021-03-22T22:52:02Z")

</div>

I sent you a private DM for some further details

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [March 23, 2021, 5:20pm UTC](https://forum.opencv.org/t/opencv-smoother-contour/2305/6 "2021-03-23T17:20:00Z")

</div>

since you need a vector path, OpenCV is the wrong tool for the job.

this can be done manually with not too much effort

- [https://creativecloud.adobe.com/discover/article/make-a-die-cut-sticker-with-adobe-illustrator](https://creativecloud.adobe.com/discover/article/make-a-die-cut-sticker-with-adobe-illustrator)
- [https://community.adobe.com/t5/illustrator/creating-a-die-cut-line-from-a-png-in-ai/m-p/9349500](https://community.adobe.com/t5/illustrator/creating-a-die-cut-line-from-a-png-in-ai/m-p/9349500)
- [How to create a sticker cut line in Illustrator | Blog | Sticker Mule](https://www.stickermule.com/blog/how-to-create-a-sticker-cut-line)

if you need this automated, I’m wondering

- _why not_ just do it by hand, when the physical stickers have to be handled by humans anyway
- what the economic value of automating it could be vs. offering 100 bucks or so on upwork

---

<div class="post-metadata">

**Author:** ![mike](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/mike/32/4250_2.png) [@mike](https://forum.opencv.org/u/mike)\
**Post date:** [March 23, 2021, 6:12pm UTC](https://forum.opencv.org/t/opencv-smoother-contour/2305/7 "2021-03-23T18:12:47Z")

</div>

Well, it’s quit hard to manage your code, bc it has lots of useless code spam which makes it more complicated to understand the main idea. Could you please share the code without all that functions related to the time and other staff? (Actually, this is a good way to get answer more quickly on any forums to share only the part of code, where you have problem)

---

<div class="post-metadata">

**Author:** ![StringTheory](https://avatars.discourse-cdn.com/v4/letter/s/aeb1de/32.png) [@StringTheory](https://forum.opencv.org/u/StringTheory)\
**Post date:** [March 29, 2021, 1:25am UTC](https://forum.opencv.org/t/opencv-smoother-contour/2305/8 "2021-03-29T01:25:37Z")

</div>

There are some papers that cover this from the viewpoint of smoothing handwriting, or smoothing cell contours in microscope images, etc.

This is useful:  
“An Efficient Algorithm for Smoothing Binary Image Contours”  
by Donggang Yu and Hong Yan.

This has a nice illustration of a working algorithm near the top:  
“A multiple point boundary smoothing algorithm [1998]”  
by Jianming Hu, Donggang Yu, Hong Yan

“Structural Boundary Feature Extraction for Printed Character Recognition [1998]”  
by the same authors.

You should be able to find those papers fairly easily, and bootstrap to others from the references within those papers.
