Distance Transform in OpenCV Python automatically converting CV_8UC3 to CV_32SC1 creating an assertion error

Anindita Bhowmik picture Anindita Bhowmik · Jul 7, 2016 · Viewed 13.1k times · Source

I am trying to apply the WaterShed algorithm to an image as per the tutorial: OpenCv WaterShed Docs . I have earlier applied Otsu's thresholding after Gaussian filtering and Morpholigical Transformations on a greyscale image to improve Image quality as per the code:

img = cv2.imread('Results\Feb_16-0.jpg',0)
kernel = np.ones((1,1),np.uint8)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
blur = cv2.GaussianBlur(opening,(1,1),0)
ret3,th4 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

Applying the distance transform as the first stage of the watershed algorithm as per the code:

# sure background area
sure_bg = cv2.dilate(opening,kernel,iterations=1)
# Finding sure foreground area
dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,3)

creates the error:

error: (-215) src.type() == CV_8UC3 && dst.type() == CV_32SC1 in function cv::watershed

wherein the 8bit 3 channel image is being attempted to be converted to a 32bit single channel image. How do I prevent this and yet work with the Distance Transform?

Answer

gtcoder picture gtcoder · Dec 18, 2017

This error arises when your input array into cv2.distanceTransform is not formatted properly. It should be a 2D array of type np.uint8 (not int8).

For example

import cv2 as cv
import numpy as np

testim = np.zeros((11,11), dtype = uint8)
testim[2:6,1:6] = 255
testim[3,3] = 0
print(testim)
dist = cv.distanceTransform(testim, cv.DIST_L2, 5)
print(testim)

If you are reading an image that is not in the right format, you must first convert it to gray (only one channel) and make sure it is in the uint8 format. This can be done with imagename.astype(np.uint8)

This was tested in opencv version 3.3.1, python 3.5.