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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值