Search code examples
pythonopencvsobel

OpenCV in python complains when i try to use 64F in Sobel blur


I am trying to make an object detection tool (given a sample) using Contours.

I have had some progress however when the object is in front of another object with a complicated structure (a hand or a face for example), or the object and its background merge in colors, it stops detecting the edges and thus doesnt give a good contour.

After reading through the algorithms documentation, I discovered that it works on the basis that the edges are detected by difference in color intensity - for example if the object is black and the background is black it will not detect it.

So now i am trying to apply some effects and blurs to try and make it work.

I am currently trying to get a combined Sobel blur (in both axis) with hopes that given enough light it will define the edges - since the product will be used by phones who have flash.

So when i tried to do it:

frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
frame = cv2.GaussianBlur(frame, (5, 5), 10)
frameX = cv2.Sobel(frame, cv2.CV_64F, 1, 0)
frameY = cv2.Sobel(frame, cv2.CV_64F, 0, 1)
frame = cv2.bitwise_or(frameX, frameY)

I get an error saying the cv2.findContours supports only CV_8UC1 images when the mode is not CV_RETR_FLOODFILL.

Here is the line that triggers the error:

counturs, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

I started messing around with this thing only 1 week ago and im surprised how easy it is to get results but some of the error messages are ridiculous.

Edit: I did try to swap the mode to be CV_RETR_FLOODFILL but that did not fix the problem, then it didnt work at all.


Solution

  • The reason is that findContours function expects a binary image (an image consists of 0's and 1's) whose type is 8 bit integer (uint8). The developers might have done this to reduce the memory usage since there is no point in storing binary values with 64 bits instead of 8 bits. Convert frame into uint8 type by just using

    frame = np.uint8(frame)