[SOLVED] Contour detection of a numpy array

Issue

I am new in computer vision and I am currently working on a numpy array of 0 and 1 on python as follow :

Snapshot of the numpy array

I am trying to find the contour of the shape formed by the cells that are equal to 1, this is what the result should look like :

Snapshot of the expected result

I would like to be able to get the position of each element highlighted in green following a certain order (counter clockwise for exemple).
I tried to use the findContours function of OpenCV in python by following some examples I found on the web but I didn’t make it work :

# Import
import numpy as np
import cv2
# Find contours
tableau_poche = np.array([[1., 1., 1., 1., 1., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [1., 1., 1., 1., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [1., 1., 1., 1., 1., 0., 0., 1., 1., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 1., 1., 1., 1., 1., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
    0.]])
tableau_poche = np.int8(tableau_poche)
contours, hierarchy = cv2.findContours(tableau_poche, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

I get the following message :

error: OpenCV(4.0.1) C:\ci\opencv-suite_1573470242804\work\modules\imgproc\src\thresh.cpp:1492: error: (-210:Unsupported format or combination of formats) in function ‘cv::threshold’

Actually, I don’t know if I am supposed to use this OpenCV function (maybe the "matplotlib.pyplot.contour()" function can solve my problem too …) or if it’s possible to use it on the numpy array I have. In a near future, I might be interested by the convexityDefects function of OpenCV on my numpy array.

Solution

You have a type issue. This OpenCV function works only with unsigned integer uint8. Your array uses signed integer int8.

simply replace:
tableau_poche = np.int8(tableau_poche)
by
tableau_poche = tableau_poche.astype(np.uint8)

and the findContour() will work.

As pointed out in comments, you can get what you want (or very close) by changing the attributes of the findContour(). By using cv2.CHAIN_APPROX_NONE instead of cv2.CHAIN_APPROX_SIMPLE, it will give you all the points of the contour. However, it works vertically, horizontally and diagonally for any pixel of distance 1. So it is not 100% what you had on your question as it "cuts" the corners.
See documentation here for more info on options ContourApproximationModes

Answered By – Ssayan

Answer Checked By – Katrina (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *