How to Use 'Cv2.Findcontours' in Different Opencv Versions

How to use `cv2.findContours` in different OpenCV versions?

An alternative to work with 2.x 、3.x、4.x is:

cnts, hiers = cv2.findContours(...)[-2:]

Notice:

cv2.findContours has changed since OpenCV 3.x, but in OpenCV 4.0 it changes back!!!

In OpenCV 3.4:

findContours(image, mode, method[, contours[, hierarchy[, offset]]]) -> image, contours, hierarchy

Sample Image

In OpenCV 4.0:

findContours(image, mode, method[, contours[, hierarchy[, offset]]]) -> contours, hierarchy

Sample Image

Contours tuple must have length 2 or 3, otherwise OpenCV changed their cv2.findContours return signature yet again- find contour in a specific area

You are using imutils.grab_contours wrong.

If you do the destructuring yourself, with (cnts, *_) = cv.findContours(...), then you don't need imutils at all.

If you want to use imutils anyway, you need to pass it the entire tuple (2-tuple or 3-tuple) returned by cv.findContours, like so: cnts = imutils.grab_contours(cv.findContours(...))

OpenCV version 4.1.0 drawContours error: (-215:Assertion failed) npoints 0 in function 'drawContours'

Depending on the OpenCV version, cv2.findContours() has varying return signatures.

In OpenCV 3.4.X, cv2.findContours() returns 3 items

image, contours, hierarchy = cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]])

In OpenCV 4.1.X, cv2.findContours() returns 2 items

contours, hierarchy = cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]])

You can easily obtain the contours regardless of the version like this:

cnts = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

Since the last two values are always the same, we can further condense it into a single line using [-2:] to extract the contours from the tuple returned by cv2.findContours()

cnts, _ = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2:]

Use cv2.findContours output as plt.contour input

Here is a minimal example with plot. Please keep in mind that the y-coordinate of opencv and matplotlib have different directions:

import cv2
from matplotlib import pyplot as plt

im = cv2.imread("img.png", cv2.IMREAD_GRAYSCALE)
_, thresh = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY)
contours, _ = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
contour = contours[0]

M = cv2.moments(contour)
x = int(M["m10"] / M["m00"])
y = int(M["m01"] / M["m00"])

xs = [v[0][0] - x for v in contour]
ys = [-(v[0][1] - y) for v in contour]

plt.plot(xs, ys)
plt.grid()
plt.show()

Sample Image

And here is another example with a closed polygon patch:

import cv2
from matplotlib import pyplot as plt
from matplotlib.patches import Polygon

im = cv2.imread("img.png", cv2.IMREAD_GRAYSCALE)
_, thresh = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY)
contours, _ = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
contour = contours[0]

M = cv2.moments(contour)
x = int(M["m10"] / M["m00"])
y = int(M["m01"] / M["m00"])

p = Polygon([(v[0][0] - x, y - v[0][1]) for v in contour], closed=True)

fig, ax = plt.subplots()
ax.add_patch(p)
ax.set_xlim([-80, 80])
ax.set_ylim([-80, 80])
plt.grid()
plt.show()

Sample Image

cv2.findContours function is not working in both versions

This is due to a change in openCV. Since version 4.0 findContours returns only 2 values: the contours and the hierarchy. Before, in version 3.x, it returned 3 values. You can use the documentation to compare the different versions.

The second code snippet should work when you change your code to:

# find contours
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

Why the first snippet picks a different openCV version can't be determined from the information given.

OpenCV Contours - need more than 2 values to unpack

In OpenCV 2, findContours returns just two values, contours and hierarchy. The error occurs when python tries to assign those two values to the three names given on left in this statement:

image, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

findContours and drawContours errors in opencv 3 beta/python

opencv 3 has a slightly changed syntax here, the return values differ:

cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]]) → image, contours, hierarchy


Related Topics



Leave a reply



Submit