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.
- code:
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.
- Debug
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. Except for putting the local host to compose the url, because when I put my local host I get an error.
- Example error:
NewConnectionError('<urllib3.connection.HTTPConnection object at 0x00000277283F1E80>:
Failed to establish a new connection: [WinError 10061]
I applied solutions found on the Internet and also reinstalled all necessary packages but nothing worked.
CodePudding user response:
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
- if webcam gives image
- if server send response status
200
and if status is different then display message from server - likeb'{"message":"Not Found"}'
orb'{"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()