Home > Software engineering >  Using Webcam with Yolov5 Models
Using Webcam with Yolov5 Models

Time:06-14

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.

  1. 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.

  1. 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.

  1. 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 - 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()
  • Related