使用图像处理和PID平衡板上的球

    xiaoxiao2022-07-04  127

    今天在github上找了一天终于找到了一个关于opencv和pid控制的程序,运气不错,竟然这么快找到了分享给大家: 这是python文件 detectBall.py Python的串口通信(pyserial)使用方法: 详解: https://www.cnblogs.com/dongxiaodong/p/9992083.html import cv2 import numpy as np import imutils from collections import deque import serial #导入串口通信模块 import time import struct #定义“绿色”的下限和上限 #在HSV色彩空间球 colorLower = (15*180/240, 140 , 150)#HSV colorUpper = (40*180/240, 255 , 255)#HSV ser = serial.Serial("com9", 9600) time.sleep(2) # 从网络摄像头捕获视频 camera = cv2.VideoCapture(0) while(True): ##s= time.time() #逐帧捕获 ret, frame = camera.read() #帧= cv2.flip(帧,1) #调整框架大小,模糊它,并将其转换为HSV frame = imutils.resize(frame, width=600) ##height, width = frame.shape[:2] #过滤器 frame = cv2.GaussianBlur(frame, (11, 11), 0) frame = cv2.medianBlur(frame,5) #从RGB到HSV hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) mask = cv2.inRange(hsv, colorLower, colorUpper) mask = cv2.erode(mask, None, iterations=2) mask = cv2.dilate(mask, None, iterations=2) cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2] #中心=无 #仅在找到至少一个轮廓时才进行 if len(cnts) > 0: #找到面具中最大的轮廓,然后使用 #它计算最小的封闭圆和 #重心 c = max(cnts, key=cv2.contourArea) ((x, y), radius) = cv2.minEnclosingCircle(c) M = cv2.moments(c) center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"])) #仅在半径满足最小尺寸时才进行 if radius > 10: #画出框架上的圆圈和质心, #然后更新跟踪点列表 cv2.circle(frame, (int(x), int(y)), int(radius),(0, 255, 255), 2) cv2.circle(frame, center, 5, (0, 0, 255), -1) ## print(“x =”,int(x),“y =”,int(y)) #框架宽度= 600和高度= 450 #映射到0-180 dx=int(x/600*180) dy=int(y/450*180) print ("x=",int(dx),"y=",int(dy)) ser.write(struct.pack('>BB',dx,dy)); #显示结果帧 cv2.imshow('frame1',hsv) cv2.imshow('frame2',mask) cv2.imshow('Result',frame) if cv2.waitKey(1) & 0xFF == ord('q'): break ##e= time.time() ##print (s-e) #完成所有操作后,释放捕获 ser.close() camera.release() cv2.destroyAllWindows()

    下面这是plate.ino的代码:

    #include <PID_v1.h> #include <Servo.h> Servo servoX; Servo servoY; double inputX, inputY, outputX, outputY; double setPointX=(300/600*90); double setPointY=(225/450*90) ; PID myPID(&inputX, &outputX, &setPointX, 1, 0.2, 0.4, DIRECT); PID myPID2(&inputY, &outputY, &setPointY, 1, 0.3, 0.1, DIRECT); void setup() { Serial.begin(9600); pinMode(13,OUTPUT); servoX.attach(5); servoY.attach(6); myPID.SetMode(AUTOMATIC); myPID2.SetMode(AUTOMATIC); } void loop() { if (Serial.available() >= 2){ inputX = Serial.read(); inputY = Serial.read(); myPID.Compute(); myPID2.Compute(); servoX.write(inputX); servoY.write(inputY); digitalWrite(13,HIGH); delay(inputX*4); digitalWrite(13,LOW); delay(inputY*4); } }

    代码来自: 转自:https://github.com/Mostafa3zazi/balancing_plate

    最新回复(0)