1

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.

3
  • you should show the code that caused the error. the code you show can't cause this error. please review How to Ask and minimal reproducible example. -- you don't need threshold. findContours assumes anything nonzero to be foreground. Commented Mar 15, 2022 at 13:39
  • 1
    Well I am sorry but whenever I just copy and paste the sample of code I put on my question in my Python console, I get the exact message error I gave. I am not sure to understand the downvote Commented Mar 16, 2022 at 8:25
  • Also, my question is not only about the message error I get when using the OpenCV function but as you should have read, at the end of my message I explain exactly what kind of questions I am facing. I don't think your edit on my question is valuable @Christoph Rackwitz Commented Mar 16, 2022 at 8:28

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your answer and you are right, I thought it would give me the coordinates of all the cells around the shape but no … do you know a function that would help in that way ?
I don't know any package that will do that out of the box (it doesn't mean it doesn't exist). You could go through the points of your polygon and try to interpolate with integer values but it may not be reliable for successive points when x and y vary.
findContours does precisely what you ask for. you just have to use it. -- the type issue is at the core of this question however, and this answer given by Ssayan is the answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.