How to use Skimage contours in opencv?

Viewed 928

I am using skimage to watershed processing since it gives better results. But once finding contours, contour properties are found far more easily with opencv.

I use this to find the contours from skimage watershed:

contours = measure.find_contours(watershed(-distance, markers, mask=th4), 0.8)

to draw contours I use this:

cv2.drawContours(rimg6, [A.astype(np.int32)], -1, (0,255,0), 4)

As skimage gives real numbers and opencv only works with intagers I use this to turn the contours into integers:

A = np.floor(contours[0])
A = A.astype(int)

contour drawing does nothing with [A.astype(np.int32)], and when I use A.astype(np.int32) (without brackets I mean) I get this error:

OpenCV(4.1.2) /io/opencv/modules/imgproc/src/drawing.cpp:2509: error: (-215:Assertion failed) npoints > 0 in function 'drawContours'

What should I do?

1 Answers

OpenCV contours have an extra set of brackets around each point (no clue why, it's always been like that).

Here's a short demo script showing a way to convert from skimage contours to OpenCV contours.

import cv2
import numpy as np
from skimage import measure

# create empty image
blank = np.zeros((100,100), np.uint8);

# ------------The following lines of code were taken from here-----------
# https://scikit-image.org/docs/dev/auto_examples/edges/plot_contours.html#sphx-glr-auto-examples-edges-plot-contours-py

# Construct some test data
x, y = np.ogrid[-np.pi:np.pi:100j, -np.pi:np.pi:100j]
r = np.sin(np.exp((np.sin(x)**3 + np.cos(y)**2)))

# Find contours at a constant value of 0.8
contours = measure.find_contours(r, 0.8)

# ----------end of code copying--------------

# convert to opencv contour and draw
for con in contours:
    cv_contour = [];
    for point in con:
        intify = [int(point[0]), int(point[1])];
        cv_contour.append([intify]); # extra pair of brackets because ¯\_(ツ)_/¯ it's OpenCV

    # convert to numpy and draw
    cv_contour = np.array(cv_contour);
    cv2.drawContours(blank, [cv_contour.astype(int)], -1, (255), -1);

# resize bigger
blank = cv2.resize(blank, (300,300));
cv2.imshow("Blank", blank);
cv2.waitKey(0);
Related