OpenCV Smoother contour

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:

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

def time_calculation_start():

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

def render_png(filename):
    original_image = cv2.imread(str(filename), cv2.IMREAD_UNCHANGED)
    copy = original_image.copy() # Saved for imagecreation

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

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

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

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

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

Stack overflow would not let me include these links due to “code formatting issues”

Last link:

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.

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

I sent you a private DM for some further details

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

this can be done manually with not too much effort

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

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)

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.