mehmet_zmn
mehmet_zmn

Reputation: 31

Try to get convexity defects but getting an error

currently i am working on a final project. And i am using opencv library and python language. Studying on opencv with python, to understand how to use it i am making small projects. In this i try to find contours, hull and convexity defects on a hand photo. But when i run my code, i get this error:

Traceback (most recent call last):
  line 21, in <module>
    defects = cv.convexityDefects(cnt, hull)
TypeError: Expected Ptr<cv::UMat> for argument 'convexhull'

I am studying on some documents of opencv and took line of codes from there. I found contours and hull but when it comes to convexitydefects every time i get an error. I already tried other people codes on internet and implement it into mine, gives me same error. I am new at python programming and can not fix this. Can anyone help me? Thanks and sorry for my bad english.

import cv2 as cv
import numpy as np

img = cv.resize(cv.imread("hand.jpg"), (350, 700))

gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

ret, thresh = cv.threshold(gray, 230, 255, cv.THRESH_BINARY_INV)

contours, hierarchy = cv.findContours(thresh.copy(), cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

cnt = contours[0]

hull = []

for i in range(len(contours)):
    hull.append(cv.convexHull(contours[i], False))
    cv.drawContours(img, hull, i, (0, 0, 255), 2, 8)

if len(hull) > 0:
    defects = cv.convexityDefects(cnt, hull)
    for i in range(defects.shape[0]):
        s, e, f, d = defects[i, 0]
        start = tuple(cnt[s][0])
        end = tuple(cnt[e][0])
        far = tuple(cnt[f][0])
        cv.circle(img, far, 5, [0, 0, 255], -1)

cv.drawContours(img, contours, -1, (0, 255, 0), 3)

cv.imshow('Image', img)
cv.imshow('Thresh', thresh)

cv.waitKey(0)



Upvotes: 0

Views: 261

Answers (1)

Ritwik G
Ritwik G

Reputation: 416

The function cv.convexityDefects expects input of type Ptr<cv::UMat>. But you are clearly passing a list(hull).

I believe instead of checking if len(hull) > 0: you probably need to loop through each element in hull.

Check the code below for mentioned change.

import cv2 as cv
import numpy as np

img = cv.resize(cv.imread("hand.jpg"), (350, 700))

gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

ret, thresh = cv.threshold(gray, 230, 255, cv.THRESH_BINARY_INV)

contours, hierarchy = cv.findContours(
    thresh.copy(), cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

cnt = contours[0]

hull = []

for i in range(len(contours)):
    hull.append(cv.convexHull(contours[i], False))
    cv.drawContours(img, hull, i, (0, 0, 255), 2, 8)

for each in hull:
    defects = cv.convexityDefects(cnt, each)
    if not defects:
        continue
    for i in range(defects.shape[0]):
        s, e, f, d = defects[i, 0]
        start = tuple(cnt[s][0])
        end = tuple(cnt[e][0])
        far = tuple(cnt[f][0])
        cv.circle(img, far, 5, [0, 0, 255], -1)

cv.drawContours(img, contours, -1, (0, 255, 0), 3)

cv.imshow('Image', img)
cv.imshow('Thresh', thresh)

cv.waitKey(0)

Upvotes: 0

Related Questions