I am using a program to track peoples faces through my webcam and move servo motors in the direction the person is. Source. But when running the software, and the camera detects a face it crashes and gives this error:
Connection to arduino...
{72: 327, 379: 634}
X :379
Y :72
x+w :634
y+h :327
506.5
199.5
Center of Rectangle is : (506.5, 199.5)
output = 'X506.500000Y199.500000Z'
Traceback (most recent call last):
File "C:UsersJaxonDesktopFace Trackingservoface.py", line 51, in <module>
arduino.write(data)
File "C:UsersJaxonAppDataLocalPackagesPythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0LocalCachelocal-packagesPython39site-packagesserialserialwin32.py", line 310, in write
data = to_bytes(data)
File "C:UsersJaxonAppDataLocalPackagesPythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0LocalCachelocal-packagesPython39site-packagesserialserialutil.py", line 65, in to_bytes
raise TypeError('unicode strings are not supported, please encode to bytes: {!r}'.format(seq))
TypeError: unicode strings are not supported, please encode to bytes: 'X506.500000Y199.500000Z'
Full Code:
import numpy as np
import serial
import time
import sys
import cv2
arduino = serial.Serial('COM5', 9600)
time.sleep(2)
print("Connection to arduino...")
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
cap = cv2.VideoCapture(0)
while 1:
ret, img = cap.read()
if ret == True:
cv2.namedWindow("img", cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 500, 500)
cv2.line(img, (500, 250), (0, 250), (0, 255, 0), 1)
cv2.line(img, (250, 0), (250, 500), (0, 255, 0), 1)
cv2.circle(img, (250, 250), 5, (255, 255, 255), -1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3)
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 5)
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
arr = {y: y+h, x: x+w}
print(arr)
print('X :' + str(x))
print('Y :'+str(y))
print('x+w :' + str(x+w))
print('y+h :' + str(y+h))
xx = int(x+(x+h))/2
yy = int(y+(y+w))/2
print(xx)
print(yy)
center = (xx, yy)
print("Center of Rectangle is :", center)
data = "X{0:f}Y{1:f}Z".format(xx, yy)
print("output = '" + data + "'")
arduino.write(data)
cv2.imshow('img', img)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
else:
break
Im stuck and have looked over answers on the error but cannot find a fix.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You use pyserial to send data to an arduino, and pyserial complains:
TypeError: unicode strings are not supported, please encode to bytes
Pyserial wants to be given bytes, not (unicode) strings. Do it like this:
arduino.write(data.encode('utf-8'))
Assuming data is of type str (unicode), this turns it into a binary representation using UTF-8. you could also use ascii if you don’t have any weird characters in the string.
Method 2
Edit: My apologized. See print. Change this:
data = "X{0:f}Y{1:f}Z".format(xx, yy)
to:
data = "X{0:d}Y{1:d}Z".format( int(xx), int(yy))
The output : output =’X328Y323Z’
Used F-string:
print("output = '" + data + "'")
to
print(f'output = {data } ')
Edit: I fix for print
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0