python - 如何将 Python IDE 中的串行输出数据转换为 C 中的整数?
问题描述
所以我想在python中使用来自面部扫描的位置数据,然后将数据转换为两个伺服电机(x和y)的旋转指令我基本上已经设置好了我只需要知道如何让Arduino将字节与串行分离到2 个整数读数。这是我到目前为止所拥有的
Python
import numpy as np
import serial
import time
import sys
import cv2
face_cascade = cv2.CascadeClassifier('cascades/data/haarcascade_frontalface_alt2.xml')
serialcomm = serial.Serial('COM5', 9600)
serialcomm.timeout = 1
cap = cv2.VideoCapture(0)
#
while(True):
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.5, 5)
for(x, y , w , h) in faces:
# print(x,y,w,h)
roi_gray = gray[y:y+h, x:x+w]
roi_color = frame[y:y+h, x:x+w]
# stringx = str(y) +'\n'
#serialcomm.write(stringx.encode())
color = (255, 0, 0)
stroke = 2
end_cord_x= x+w
end_cord_y = y + h
cv2.rectangle(frame, (x,y),(end_cord_x,end_cord_y), color, stroke)
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:d}Y{1:d}Z".format(x,y)
print ("output = '" +data+ "'")
print(data.encode())
#serialcomm.write(data.encode())
cv2.imshow('frame',frame)
if cv2.waitKey(20) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
阿杜诺
#include<Servo.h>
Servo servoVer; //Vertical Servo
Servo servoHor; //Horizontal Servo
int x;
int y;
int prevX;
int prevY;
int ledgreen = 7;
int ledred = 8;
void setup()
{
Serial.begin(9600);
servoVer.attach(9); //Attach Vertical Servo to Pin 9
servoHor.attach(8); //Attach Horizontal Servo to Pin 8
servoVer.write(90);
servoHor.write(90);
pinMode(ledgreen, OUTPUT);
pinMode(ledred, INPUT);
}
void Pos()
{
if(prevX != x || prevY != y)
{
int servoX = map(x, 0, 400, 70, 130);
int servoY = map(y, 0, 400, 95,130);
servoX = max(servoX, 130);
servoX = min(servoX, 70);
servoY = max(servoY, 130);
servoY = min(servoY, 95);
servoHor.write(servoX);
servoVer.write(servoY);
}
}
void loop()
{
if(Serial.available() > 0)
{
if(Serial.read() == 'X')
{
x = Serial.parseInt();
digitalWrite(ledred, HIGH);
}
if(Serial.read() == 'Y')
{
y = Serial.parseInt();
Pos();
digitalWrite(ledgreen, HIGH);
}
}
while(Serial.available() > 0)
{
Serial.read();
}
}
}
基本上我无法从 COM5 端口打开终端,因为它已经被 Arduino 和 Python 代码占用,因此我不知道我是否建立了正确的协议来读取代码。但是,我希望输出是一个看起来像X223Y156Z
但我不知道如何确定我是否完全正确的字符串。当我运行代码时,伺服系统会响应但动作不稳定,所以我假设问题出在代码中
解决方案
我认为问题的出现是因为您没有给出角度的相对变化,而是给出了绝对值。
//Variables for keeping track of the current servo positions.
char servoTiltPosition = 90;
char servoPanPosition = 90;
//The pan/tilt servo ids for the Arduino serial command interface.
char tiltChannel = 0;
char panChannel = 1;
//These variables hold the x and y location for the middle of the detected face.
int midFaceY=0;
int midFaceX=0;
//The variables correspond to the middle of the screen, and will be compared to the midFace values
int midScreenY = (height/2);
int midScreenX = (width/2);
int midScreenWindow = 10; //This is the acceptable 'error' for the center of the screen.
//The degree of change that will be applied to the servo each time we update the position.
int stepSize=1;
如果找到任何面,则首先计算面的中点:
midFaceY = faces[0].y + (faces[0].height/2);
midFaceX = faces[0].x + (faces[0].width/2);
//Find out if the Y component of the face is below the middle of the screen.
if(midFaceY < (midScreenY - midScreenWindow)){
if(servoTiltPosition >= 5)servoTiltPosition -= stepSize; //If it is below the middle of the screen, update the tilt position variable to lower the tilt servo.
}
//Find out if the Y component of the face is above the middle of the screen.
else if(midFaceY > (midScreenY + midScreenWindow)){
if(servoTiltPosition <= 175)servoTiltPosition +=stepSize; //Update the tilt position variable to raise the tilt servo.
}
//Find out if the X component of the face is to the left of the middle of the screen.
if(midFaceX < (midScreenX - midScreenWindow)){
if(servoPanPosition >= 5)servoPanPosition -= stepSize; //Update the pan position variable to move the servo to the left.
}
//Find out if the X component of the face is to the right of the middle of the screen.
else if(midFaceX > midScreenX + midScreenWindow){
if(servoPanPosition <= 175)servoPanPosition +=stepSize; //Update the pan position variable to move the servo to the right.
}
发送数据
ser.write(tiltChannel); //Send the tilt servo ID
ser.write(servoTiltPosition); //Send the updated tilt position.
ser.write(panChannel); //Send the Pan servo ID
ser.write(servoPanPosition); //Send the updated pan position.
delay(1);
推荐阅读
- javascript - 当 JavaScript 中的 Copytoclipboard 时工具提示不起作用
- sqlite - 如何使用 Count 进行复杂的 SQLite 连接
- oracle - 设置从 Oracle 到 Sybase 的数据库链接
- r - 如何在观星者表中包含来自面板回归 (plm) 的组数
- javascript - Nodejs文件在发送响应之前被删除(res.send)
- angular - Redux - 如何在大型应用程序中组织存储
- r - 尽管数据在 r 中没有这样做,但误差线在图上继续(可能)无限?
- javascript - 谷歌身份验证 - 使其从 2 个按钮与 cakephp 上的 1 个按钮一起工作
- javascript - 标识符如何既已声明又未定义?
- python - 在 Python 中获取组间的累积平均值