I tried to run the example infer-simple.py, but I can't succeed, because the code is returning a None value when the command line (image = cv2.imdecode(image, cv2.IMREAD_COLOR)) is executed.
def infer():
# Get the current image from the webcam
ret, img = video.read()
# Resize (while maintaining the aspect ratio) to improve speed and save bandwidth
height, width, channels = img.shape
scale = ROBOFLOW_SIZE / max(height, width)
img = cv2.resize(img, (round(scale * width), round(scale * height)))
# Encode image to base64 string
retval, buffer = cv2.imencode('.jpg', img)
img_str = base64.b64encode(buffer)
# Get prediction from Roboflow Infer API
resp = requests.post(upload_url, data=img_str, headers={
"Content-Type": "application/x-www-form-urlencoded"
}, stream=True).raw
# Parse result image
image = np.asarray(bytearray(resp.read()), dtype="uint8")
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
return image
Always before the imdecode image is array not None, bellow is displayed one debug example.
resp: <urllib3.response.HTTPResponse object at 0x0000015055DE7070>
image: array([ 11, 214, 13, ..., 170, 1, 3], dtype=uint8)
However, when I run cv2.imdecode(image, cv2.IMREAD_COLOR)) I get a none value for image.
3.Error
Exception has occurred: error OpenCV(4.6.0) D:\a\opencv-python\opencv-python\opencv\modules\imgcodecs\src\loadsave.cpp:816:
error: (-215:Assertion failed) !buf.empty() in function 'cv::imdecode_'
File "C:\Users\diego\codes\Webcam\infer-simple.py", line 48, in infer
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
File "C:\Users\diego\codes\Webcam\infer-simple.py", line 63, in <module>
image = infer()
I did it all step by step according to https://blog.roboflow.com/python-webcam.
I applied solutions found on the Internet and also reinstalled all necessary packages but nothing worked.
Problem is not when you get image from camera but when you get image from server.
You have to create project on roboflow.com and gets model's name and api key - and use all this to create correct url.
I created project and trained model with name chess-sample-cpuhx/1
and got API KEY like tE7xxxxxxxxx
so I have full url
https://detect.roboflow.com/chess-sample-cpuhx/1?format=image&stroke=5&api_key=tE7xxxxxxxxx
My code with few changes.
I check
200
and if status is different then display message from server - like b'{"message":"Not Found"}'
or b'{"message":"Forbidden"}'
# all `import` at the beginning
import json
import base64
import cv2
import numpy as np
import requests
import time
# --- constants ---
ROBOFLOW_API_KEY = 'tE7xxxxxxxxx'
ROBOFLOW_MODEL = 'chess-sample-cpuhx/1'
ROBOFLOW_SIZE = 400
# --- functions ---
params = {
"api_key": ROBOFLOW_API_KEY,
"format": "image",
"stroke": "5"
}
headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
url = f"https://detect.roboflow.com/{ROBOFLOW_MODEL}"
def infer(img):
# Resize (while maintaining the aspect ratio) to improve speed and save bandwidth
height, width, channels = img.shape
scale = ROBOFLOW_SIZE / max(height, width)
img = cv2.resize(img, (round(scale * width), round(scale * height)))
# Encode image to base64 string
retval, buffer = cv2.imencode('.jpg', img)
img_str = base64.b64encode(buffer)
# Get prediction from Roboflow Infer API
response = requests.post(url, params=params, data=img_str, headers=headers, stream=True)
data = response.raw.read()
#print(response.request.url)
if not response.ok:
print('status:', response.status_code)
print('data:', data)
return
# Parse result image
image = np.asarray(bytearray(data), dtype="uint8")
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
return image
# --- main ---
video = cv2.VideoCapture(0)
while True:
start = time.time()
ret, img = video.read()
if ret:
image = infer(img)
if image is not None:
cv2.imshow('image', image)
if cv2.waitKey(1) == ord('q'): # `waitKey` should be after `imshow()` - to update image in window and to get key from window
break
end = time.time()
print( 1/(end-start), "fps") # print() automatically add space between elements - you don't need space in "fps"
# - end -
video.release()
cv2.destroyAllWindows()