1、目标识别:通过树莓派上的摄像头模块(Pi Cam)进行颜色识别,如果发现绿色的圆,即发现目标,则显示发现目标。
2、完成与STM32的串口通信。
本项目的树莓派图像识别我只是进行了简单的识别绿色圆,如果有需要请自行进行修改。
在总项目文件中有介绍文档:总项目文件下载链接
也可参考本人文章:树莓派3b+系统(镜像)烧录
图像识别方面我采用了OpenCV相关的库,所有需要在树莓派中先安装OpenCV环境,这也是我在做本项目最恶心的地方,在安装OpenCV环境时总是出一些奇奇怪怪的错误。下面是我安装成功的参考:
在总项目文件中有介绍文档:总项目文件下载链接
也可参考本人文章:树莓派3b+的OpenCV环境安装
在总项目文件中有介绍文档:总项目文件下载链接
也可参考本人文章:串口通信(树莓派3b+)
在总项目文件中有介绍文档:总项目文件下载链接
也可参考本人文章:树莓派摄像头模块(Pi Cam)的安装使用
# Function: Color recognition
# return: 1 red 2 blue 3 green
def color_demo(cl_img):
# 常数设置和初始化
area_red = 0 # 颜色框面积
area_blue = 0
area_green = 0
len_const = 3000 # 限定颜色框面积大小的常数
judge_const = 0 # 判断常数。0为没发现目标物,大于0为发现目标物
frame3 = cl_img # 传入照片(相当于函数参数)
while True:
hsv = cv.cvtColor(frame3, cv.COLOR_BGR2HSV)# 转换颜色空间 BGR 到 HSV
# 定义HSV中蓝色的范围
lower_red = np.array([0, 100, 80]) # 红色阈值下界
higher_red = np.array([10, 255, 255]) # 红色阈值上界
lower_blue = np.array([100, 43, 46])
higher_blue = np.array([124, 255, 255])
lower_green = np.array([35, 43, 46])
higher_green = np.array([77, 255, 255])
#mask = cv.inRange(hsv, lower_blue, upper_blue)# 设置HSV的阈值使得只取蓝色
mask_red = cv2.inRange(hsv, lower_red, higher_red) # 可以认为是过滤出红色部分,获得红色的掩膜
mask_green = cv2.inRange(hsv, lower_green, higher_green) # 获得绿色部分掩膜
mask_blue = cv2.inRange(hsv, lower_blue, higher_blue) # 获得蓝色部分掩膜
mask_green = cv2.medianBlur(mask_green, 7) # 中值滤波
mask_red = cv2.medianBlur(mask_red, 7) # 中值滤波
mask_blue = cv2.medianBlur(mask_blue, 7) # 中值滤波
# 将掩膜和图像逐像素相加
# res = cv.bitwise_and(frame, frame, mask=mask)
# mask = cv2.bitwise_or(mask_green, mask_red, mask_blue) # 三部分掩膜进行按位或运算
# cnts3, hierarchy3 = cv2.findContours(mask_green, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # 轮廓检测 #绿色
_,cnts1,hierarchy1 = cv2.findContours(mask_red, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
_,cnts2,hierarchy2 = cv2.findContours(mask_blue, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
_,cnts3,hierarchy3 = cv2.findContours(mask_green, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# while(cv2.waitKey(1) & 0xFF == ord('q')):
for cnt in cnts1:
(x, y, w, h) = cv2.boundingRect(cnt) # 该函数返回矩阵四个点
if (w * h) > len_const:
cv2.rectangle(frame3, (x, y), (x + w, y + h), (0, 0, 255), 2) # 将检测到的颜色框起来
cv2.putText(frame3, 'red', (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
area_red = area_red + (w * h)
for cnt in cnts2:
(x, y, w, h) = cv2.boundingRect(cnt)
if (w * h) > len_const:
cv2.rectangle(frame3, (x, y), (x + w, y + h), (255, 0, 0), 2)
cv2.putText(frame3, 'blue', (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)
area_blue = area_blue + (w * h)
for cnt in cnts3:
(x, y, w, h) = cv2.boundingRect(cnt)
if (w * h) > len_const:
cv2.rectangle(frame3, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(frame3, 'green', (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
area_green = area_green + (w * h)
if area_red > area_blue:#1 red 2 blue 3 green
if area_blue > area_green:
judge_const = 1
print("max:red-{}".format(area_red))
elif area_blue < area_green:
if area_red > area_green:
judge_const = 1
print("max:red-{}".format(area_red))
elif area_red < area_green:
judge_const = 3
print("max:green-{}".format(area_green))
elif area_red < area_blue:
if area_red > area_green:
judge_const = 2
print("max:blue-{}".format(area_blue))
elif area_red < area_green:
if area_green > area_blue:
judge_const = 3
print("max:green-{}".format(area_green))
elif area_green < area_blue:
judge_const = 2
print("max:blue-{}".format(area_blue))
# 判断追踪到的目标颜色
if judge_const == 1 and cv.waitKey(500) & 0xFF:
print("target color:red")
return 1
elif judge_const == 2 and cv.waitKey(500) & 0xFF:
print("target color:blue")
return 2
elif judge_const == 3 and cv.waitKey(500) & 0xFF:
print("target color:green")
return 3
# areas = area_green + area_blue + area_red
cv2.imshow('frame3', frame3)
print("No target color")
return 0
import cv2
import time
import numpy as np
#设定蓝色阈值,HSV空间
blueLower = np.array([80, 100, 100])
blueUpper = np.array([100, 255, 255])
#打开摄像头
camera = cv2.VideoCapture(0)
#创建一个xianshifangfa
def ceju_xianshi():
while True:
# 读取帧
(ret, frame) = camera.read()
frame = cv2.flip(frame, 1, dst=None) # 水平翻转镜像
# 判断是否成功打开摄像头
if not ret:
print('No Camera')
break
# 转到HSV空间
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# 根据阈值构建掩膜
mask = cv2.inRange(hsv, blueLower, blueUpper)
# 腐蚀操作
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, w, h = cv2.boundingRect(c)
#计算目标距离
juli = (1029.006/w)*2.54
juli1 = str(juli)
# 输出距离
print("juli",juli1)
print("shijikuandu",w)
# 显示矩形框
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv2.putText(frame, juli1, (30, 300), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)#shipin_zhong,xinshi_juli
cv2.imshow('Frame', frame)
cv2.waitKey(1)
# 摄像头释放
if __name__ == '__main__':
ceju_xianshi()
import cv2
import math,serial,numpy,time
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
# Function: Color recognition
# return: 1 red 2 blue 3 green
def color_demo(cl_img):
area_red = 0
area_blue = 0
area_green = 0
len_const = 3000
judge_const = 0
frame3 = cl_img
while True:
hsv = cv.cvtColor(frame3, cv.COLOR_BGR2HSV)
lower_red = np.array([0, 100, 80])
higher_red = np.array([10, 255, 255])
lower_blue = np.array([100, 43, 46])
higher_blue = np.array([124, 255, 255])
lower_green = np.array([35, 43, 46])
higher_green = np.array([77, 255, 255])
# mask = cv.inRange(hsv, lower_blue, upper_blue)
mask_red = cv2.inRange(hsv, lower_red, higher_red)
mask_green = cv2.inRange(hsv, lower_green, higher_green)
mask_blue = cv2.inRange(hsv, lower_blue, higher_blue)
mask_green = cv2.medianBlur(mask_green, 7)
mask_red = cv2.medianBlur(mask_red, 7)
mask_blue = cv2.medianBlur(mask_blue, 7)
# res = cv.bitwise_and(frame, frame, mask=mask)
# mask = cv2.bitwise_or(mask_green, mask_red, mask_blue)
# cnts3, hierarchy3 = cv2.findContours(mask_green, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
_,cnts1,hierarchy1 = cv2.findContours(mask_red, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
_,cnts2,hierarchy2 = cv2.findContours(mask_blue, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
_,cnts3,hierarchy3 = cv2.findContours(mask_green, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# while(cv2.waitKey(1) & 0xFF == ord('q')):
for cnt in cnts1:
(x, y, w, h) = cv2.boundingRect(cnt)
if (w * h) > len_const:
cv2.rectangle(frame3, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv2.putText(frame3, 'red', (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
area_red = area_red + (w * h)
for cnt in cnts2:
(x, y, w, h) = cv2.boundingRect(cnt)
if (w * h) > len_const:
cv2.rectangle(frame3, (x, y), (x + w, y + h), (255, 0, 0), 2)
cv2.putText(frame3, 'blue', (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)
area_blue = area_blue + (w * h)
for cnt in cnts3:
(x, y, w, h) = cv2.boundingRect(cnt)
if (w * h) > len_const:
cv2.rectangle(frame3, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(frame3, 'green', (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
area_green = area_green + (w * h)
if area_red > area_blue:#1 red 2 blue 3 green
if area_blue > area_green:
judge_const = 1
print("max:red-{}".format(area_red))
elif area_blue < area_green:
if area_red > area_green:
judge_const = 1
print("max:red-{}".format(area_red))
elif area_red < area_green:
judge_const = 3
print("max:green-{}".format(area_green))
elif area_red < area_blue:
if area_red > area_green:
judge_const = 2
print("max:blue-{}".format(area_blue))
elif area_red < area_green:
if area_green > area_blue:
judge_const = 3
print("max:green-{}".format(area_green))
elif area_green < area_blue:
judge_const = 2
print("max:blue-{}".format(area_blue))
if judge_const == 1 and cv.waitKey(500) & 0xFF:
print("target color:red")
return 1
elif judge_const == 2 and cv.waitKey(500) & 0xFF:
print("target color:blue")
return 2
elif judge_const == 3 and cv.waitKey(500) & 0xFF:
print("target color:green")
return 3
# areas = area_green + area_blue + area_red
cv2.imshow('frame3', frame3)
print("No target color")
return 0
# Function: Test distance
#
def ceju_xianshi():
while True:
(ret, frame) = cap.read()
frame = cv2.flip(frame, -1, dst=None)
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, blueLower, blueUpper)
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, w, h = cv2.boundingRect(c)
juli = (1029.006/w)*2.54
juli1 = str(juli)
print("juli",juli1)
print("shijikuandu",w)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv2.putText(frame, juli1, (30, 300), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)#shipin_zhong,xinshi_juli
cv2.imshow('Frame', frame)
cv2.waitKey(1)
break
if __name__ == '__main__':
ser = serial.Serial('/dev/ttyAMA0', 9600)
cap = cv.VideoCapture(0)
if not cap.isOpened():
print("NO PI")
exit()
try:
while True:
size = ser.inWaiting()
if size != 0:
response = ser.read(size)
print(response)
while response==b'B': #begin pi work
print("flagPi = 1 ")
rets, frame = cap.read()
color_img = cv.imread('/home/pi/Desktop/WindowsLogo.jpg')
k = color_demo(frame) #1 red 2 blue 3 green
if k==3:
print("STM32_work")
ser.write(b'F\r\n') #found target
ser.flushInput()
response = b'E' #end pi work
break
cv2.destroyAllWindows()
except KeyboardInterrupt:
ser.close()
总项目文件:下载链接
上一篇文章:循迹识别小车:(二)STM32部分
下一篇文章:循迹识别小车:(四)OpenMV4部分