I'm trying to add some feature to this code that i got from https://raw.githubusercontent.com/vipul-sharma20/gesture-opencv/master/gesture.py that i can capture any palm that i need and save it in folder, in first try its success,but the second is failure said:
Traceback (most recent call last):
File "home/pi/Downloads/palmdetect.py", line 97, in<module>
camera_capture = get_image()
File "home/pi/Downloads/palmdetect.py", line 11, in get_image
crop_image = img[100:450, 100:450]
TypeError: 'NoneType' object is not subscriptable
Code in palmdetect.py
:
import cv2
import numpy as np
import math
cap = cv2.VideoCapture(0)
def get_image():
# read image
ret, img = cap.read()
# get hand data from the rectangle sub window on the screen
cv2.rectangle(img, (300, 300), (100, 100), (0, 255, 0), 0)
crop_img = img[100:300, 100:300]
# convert to grayscale
grey = cv2.cvtColor(crop_img, cv2.COLOR_BGR2GRAY)
# applying gaussian blur
value = (35, 35)
blurred = cv2.GaussianBlur(grey, value, 0)
# thresholdin: Otsu's Binarization method
_, thresh1 = cv2.threshold(blurred, 127, 255,
cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
# show thresholded image
cv2.imshow('Thresholded', thresh1)
# check OpenCV version to avoid unpacking error
(version, _, _) = cv2.__version__.split('.')
if version == '3':
image, contours, hierarchy = cv2.findContours(
thresh1.copy(),
cv2.RETR_TREE,
cv2.CHAIN_APPROX_NONE
)
elif version == '2':
contours, hierarchy = cv2.findContours(
thresh1.copy(),
cv2.RETR_TREE,
cv2.CHAIN_APPROX_NONE
)
# find contour with max area
cnt = max(contours, key=lambda x: cv2.contourArea(x))
# create bounding rectangle around the contour (can skip below two lines)
x, y, w, h = cv2.boundingRect(cnt)
cv2.rectangle(crop_img, (x, y), (x+w, y+h), (0, 0, 255), 0)
# finding convex hull
hull = cv2.convexHull(cnt)
# drawing contours
drawing = np.zeros(crop_img.shape, np.uint8)
cv2.drawContours(drawing, [cnt], 0, (0, 255, 0), 0)
cv2.drawContours(drawing, [hull], 0, (0, 0, 255), 0)
# finding convex hull
hull = cv2.convexHull(cnt, returnPoints=False)
# finding convexity defects
defects = cv2.convexityDefects(cnt, hull)
count_defects = 0
cv2.drawContours(thresh1, contours, -1, (0, 255, 0), 3)
# applying Cosine Rule to find angle for all defects (between fingers)
# with angle > 90 degrees and ignore defects
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])
# find length of all sides of triangle
a = math.sqrt((end[0] - start[0])**2 + (end[1] - start[1])**2)
b = math.sqrt((far[0] - start[0])**2 + (far[1] - start[1])**2)
c = math.sqrt((end[0] - far[0])**2 + (end[1] - far[1])**2)
# apply cosine rule here
angle = math.acos((b**2 + c**2 - a**2)/(2*b*c)) * 57
# ignore angles > 90 and highlight rest with red dots
if angle <= 90:
count_defects += 1
cv2.circle(crop_img, far, 1, [0, 0, 255], -1)
# dist = cv2.pointPolygonTest(cnt,far,True)
# draw a line from start to end i.e. the convex points (finger tips)
# (can skip this part)
cv2.line(crop_img, start, end, [0, 255, 0], 2)
# cv2.circle(crop_img,far,5,[0,0,255],-1)
# show appropriate images in windows
cv2.imshow('Gesture', img)
all_img = np.hstack((drawing, crop_img))
return img
temp = get_image()
print("Taking Image...")
camera_capture = get_image()
file = "home/pi/Desktop/image.jpg"
cv2.imwrite(file, camera_capture)
del(camera)
anyone knows how to fix it and the threshold windows doesn't appear
The documentation says that VideoCapture.read()
combine VideoCapture::grab() and VideoCapture::retrieve() in one call
And VideoCapture::retrieve()
decode and return the just grabbed frame. If no frames has been grabbed (camera has been disconnected, or there are no more frames in video file), the methods return false and the functions return NULL pointer.
Translated in python you must expect retvar
and frame
where frame
is not None
only if retval
is True
.
In your code this line:
# read image
ret, img = cap.read()
Potentially give you img as None, so when you try to crop it here:
crop_img = img[100:300, 100:300]
You get your error:
"TypeError: 'NoneType' object is not subscriptable
You either need to test retval first:
retval, img = cap.read()
if retval:
# get hand data from the rectangle sub window on the screen
cv2.rectangle(img, (300, 300), (100, 100), (0, 255, 0), 0)
crop_img = img[100:300, 100:300]
...
Or test for img not at None first:
# Since we don't use the return value let's just forget it
_, img = cap.read()
if img is not None:
# get hand data from the rectangle sub window on the screen
cv2.rectangle(img, (300, 300), (100, 100), (0, 255, 0), 0)
crop_img = img[100:300, 100:300]
...
Then you'll have to handle the fact that your get_image function get no image (either return None or raise an Exception).
Sidenote: Your code still have two issue, you have a line all_img = np.hstack((drawing, crop_img))
at the end of your function but you never use all_img. At the end of the module you do a del(camera)
but camera is never defined. Finally if you have to share you code publicly please follow PEP8 (Install pylint or just flake8 in you editor or choice).