Get the contour (outline) findContours from a png image with the correct edges

asked 2020-10-01 13:25:24 -0500

gcmartijn gravatar image

I asked this question stackoverflow But this is a better place I hope.

I have multiple png files and I'm trying to get the polygon contour coordinates. That is the simplified coordinates, only each outer corner (not a convex hull polygon).

The program that will do this at the moment is python and opencv. But another program is oke I did try to fix this using npm packages, imagemagick, potrace, Lua. It will be uses as a shell command in a 'build polygons from images' process.

This was the last test under python.

The problem now is the that some edges are 'not' correct in the example below.

I did the following steps:

  • Convert the alpha to black and white
  • Trace the contour Get the coordinates
  • The original png file contains black lines (keep them).
  1. The original png file contains black lines (keep them).

image description

  1. Converted black and white image.

    ret, mask = cv2.threshold(img[:, :, 3], 0, 255, cv2.THRESH_BINARY)

image description

  1. Traced contour outline (not the output I want)

    contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

image description

The problem are the two holes, the 1 pixel left and 1 pixel right is missing

image description

When I use that contour data inside a other program you get this:

image description

I want this contour outline polygon data, so the external program show this:

image description

# https://opensource.com/article/19/5/python-3-default-mac#what-to-do
# https://solarianprogrammer.com/2019/10/21/install-opencv-python-macos/
# https://docs.opencv.org/master/d4/d73/tutorial_py_contours_begin.html
# https://stackoverflow.com/questions/25733694/process-image-to-find-external-contour
# https://docs.opencv.org/3.4/dd/d49/tutorial_py_contour_features.html
# https://stackoverflow.com/questions/39823221/imagemagick-find-coordinates-of-outline-of-transparent-png-not-border

import numpy as np
import cv2

img = cv2.imread('../temp/bord.png', cv2.IMREAD_UNCHANGED)

# make black and white
ret, mask = cv2.threshold(img[:, :, 3], 0, 255, cv2.THRESH_BINARY)

# find the external contour
contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# at this point I want to have the correct contours to process them inside a other program
# print(contours)

# start debugging
#save image
cv2.imwrite('../temp/bord_converted.png',mask) 

#create an empty image for contours
img_contours = np.zeros(img.shape)
# draw the contours on the empty image
cv2.drawContours(img_contours, contours, -1, (0,255,0), 1)
cv2.imwrite('../temp/bord_contour.jpg',img_contours)
edit retag flag offensive close merge delete