如何尽可能麻烦的通过open cv控制一个小灯
来源:互联网 发布:php bbs论坛源码 编辑:程序博客网 时间:2024/06/05 22:41
自从在去年入坑学习open cv之后一直没有做出几个有折腾精神的东西,作为我在CSDN的第一篇文章我就以最近暑假的一个闲的无聊小项目来小小的冒个泡吧顺便温习一下以前的陈芝麻和最近学习的stm32还有一不小心抢到的30天的云服务器。
好的废话不多说,那么我来介绍一下这个闲的无聊的项目的目的。其实很简单就是在本地电脑和树莓派上各运行一个客户端通过TCP连接运行与云服务器上的一个服务端。然后通过电脑运行的open cv程序识别使用者手势,当出现拳头时通过TCP发送1至云服务器当出现手掌时通过TCP发送0至云服务器云服务器将数据转发到树莓派,然后树莓派将TCP接收到的数据写入串口发送给stm32开发板实现小灯的开关操作。好的,是不是感觉有种绕地球一圈又回到原点的感觉?哈哈哈,没错,可以用一个开关完成的操作,我们偏偏绕了一大圈因为我们的目标是“没有蛀牙。。。。”呃,不对,不对,应该是“用最麻烦的方法,完成最简单的事”。有了折腾的目标就有了作死的动力哈哈。
那么我们下面来介绍一下我们的电脑端的open cv程序本程序将首先连接地址为xxx.xxx.xxxx端口为9909的云服务器然后加载.xml格式的Haar级联特征文件用于识别人脸拳头和手掌,当检测到人脸时才会进行拳头和手掌的识别以降低识别误差。然后将检测到拳头和手掌对应的指令发送到云服务器。
import socketimport cv2import numpy as npsock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)sock.connect(("xxx,xxx,xxxx",9909))cv2.namedWindow("test")cap=cv2.VideoCapture(0)success, frame = cap.read()color = (0,255,0)classfier=cv2.CascadeClassifier("fist.xml")classfier2=cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")classfier1=cv2.CascadeClassifier("palm.xml")while success: success, frame = cap.read() image = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) fistRects = classfier.detectMultiScale(image, 1.3, 5) plams = classfier1.detectMultiScale(image, 1.3, 5) face = classfier2.detectMultiScale(image, 1.3, 5) if len(face)>0: print("captured") if len(fistRects)>0: for fistRect in fistRects: x, y, w, h = fistRect cv2.rectangle(frame, (x, y), (x+w, y+h), color) print("detect fist send data 1") pi = 1 sock.sendall(str(pi)) if len(plams)>0: for plam in plams: x, y, w, h = plam cv2.rectangle(frame, (x, y), (x+w, y+h), color) print("detect plam send data 2") p = 0 sock.sendall(str(p)) cv2.imshow("test", frame) key=cv2.waitKey(10) c = chr(key & 255) if c in ['q', 'Q', chr(27)]: breakcv2.destroyWindow("test")cap.release()sock.close()好的下面是我们的云端程序它将监听9909端口并接受两个连接之后将先连接那个客服端作为命令端之后的为接收端就是把命令端的数据转发到接收端
import socket, timeprint "socket server by tom"sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)sock.bind(("xxx.xxx.xxxx",9909))sock.listen(2)while True: src,src_addr=sock.accept() print "Source Connected by",src_addr dst,dst_addr=sock.accept() print"Destination Connected by",dst_addr while True: msg=src.recv(1024) if not msg: break try: print msg dst.sendall(msg) except Exception as ex: dst,dst_addr=sock.accept() print"Destination Connected Again By",dst_addr except KeyboardInterrupt: print "Interrupted" breaksrc.close()dst.close()sock.close()
接下来是咱们的树莓派客户端运行的程序它将连接云端的服务器并将socket接收到的指令写入串口其中与单片机的通讯速率为115200
值得一提的是在运行Linux的计算机上所有硬件都是以文件的形式存放的所有操作硬件就是读写文件所有我们的串口的读写就是操作/dev/ttyACM0
import serialimport socketimport timeimport sysport = "/dev/ttyACM0"serial = serial.Serial(port,115200)sock = socket.socket()sock.connect(("xxx.xxx.xxxx",9909))while True: data=sock.recv(1024) if not data: break else: st = data #re.split('p',data) #print st serial.write(st) serial.flushInput() if serial.isOpen() == False: serial.open()sock.close()serial.close()
然后是我们的stm32上的几个重要的程序首先是led初始化的配置程序
#include "led.h" void LED_Init(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//操作gpio口当然要先使能f组的时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//设置为普通输出模式 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//设置gpio为推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//速度为100mhz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//端口上拉 GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化结构体 GPIO_SetBits(GPIOF,GPIO_Pin_9);//pf9口初始高电平 GPIO_ResetBits(GPIOF,GPIO_Pin_10);//pf10口初始低电平,外接的led灯没有上拉所有与开发板上的极性相反}
接着是我们的主函数main.c
#include "sys.h"#include "delay.h"#include "usart.h"#include "led.h"#include "beep.h"int main(void){ u8 t;u8 len;u8 k;u16 times=0; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组为2delay_init(168);// 初始化168m的时钟uart_init(115200);//设置串口通讯速率为115200LED_Init();//初始化led // while(1){if(USART_RX_STA&0x8000){ len=USART_RX_STA&0x3fff;//for(t=0;t<len;t++){ k = USART_RX_BUF[t];//接受串口数据}USART_RX_STA=0;//将接受完毕的标志位清零}else{times++; if(times%30==0)LED0=!LED0;//if(k == '1') LED1= 1;//串口接受为1打开ledif (k == '0')LED1 = 0;//串口接受为0关闭leddelay_ms(10); }}}
下面是我实现的几张图片
1.检测手掌
2.检测拳头
3.通过串口控制stm32
至此本项目就已经基本实现了,当然还有很多很多的隐藏技能没有被唤醒。
我依然记得一句话“The only limit is your imagination”所以发挥你的想象力一切皆有可能。
- 如何尽可能麻烦的通过open cv控制一个小灯
- Open CV小细节
- 如何用VC、MFC开发一个尽可能小的程序???
- 单件模式带来的一个小麻烦
- Open CV
- open cv
- 看似简单的小麻烦
- 用OPEN CV SVM 的例子程序
- Open CV + VS配置的四步走
- iOS 基于Open CV的边缘检测
- python3.5open cv的安装
- 一个馒头引发的麻烦
- 小麻烦
- 如何通过js全局屏蔽回车键 以解决一些不必要的麻烦
- 【Open CV基础】使用Open CV操作图像的像素通道值
- 二分一个数组,使二者之差尽可能小
- 如何通过一个毫不相关的进程去控制另一进程窗口中数据
- 如何通过dll文件生成对应的lib文件(开发人员的一个小技巧)
- Android MVP 详解(上)
- [HDU-2612] Find a Way
- caffe 参数的详解solver文件<一>
- C#中如何使用水晶报表
- Windows 7下用VMware Workstation 10虚拟机安装 Ubuntu 14.04
- 如何尽可能麻烦的通过open cv控制一个小灯
- java 驼峰字符和下划线字符相互转换工具类
- java中的native方法
- 网络的概念 2
- 马尔科夫链的一个应用实例
- bzoj2187 fraction 类欧几里得算法
- 找不到 main 方法,
- TensorFlow1.0 运行之前版本代码报错解决
- node.js安装(转载)