语音模块摄像头模块阿里云结合,实现垃圾的智能识别

语音模块&摄像头模块&阿里云结合

文章目录

  • 语音模块&摄像头模块&阿里云结合
    • 1、实现的功能
    • 2、配置
      • 2.1 软件环境
      • 2.2 硬件配置
    • 3、程序介绍
      • 3.1 程序概况
      • 3.2 语言模块SDK配置介绍
      • 3.3 程序文件
        • 3.3.1 开启摄像头的程序
        • 3.3.2 云端识别函数( `Py ==> C` ) & 串口程序
        • 3.3.3 结合 `main.c`
      • 3.4 程序运行结果

1、实现的功能

  • 可以通过语音模块使摄像头在抓拍垃圾图片,程序自动将垃圾传到云端识别,判断出是什么垃圾类型(干垃圾、湿垃圾、可回收垃圾、有害垃圾)(无法识别) 最后由语音模块输出相关信息

2、配置

2.1 软件环境

  • VS Code
  • MobaXterm

2.2 硬件配置

  • 全志H616

  • SU-03T LD3320

    • 语言模块要配置SDK,大家可以到网上搜一下,很简单的;我用的是智能公元的语音模块;我把我用的分享给大家;

    • 语言模块SDK:链接: https://pan.baidu.com/s/1CjgIhW0AWQjXdEhXZiBIzw?pwd=2222 提取码: 2222 复制这段内容后打开百度网盘手机App,操作更方便哦

      烧入工具:链接: https://pan.baidu.com/s/1JF2K_TbS_lg74YInBCCI2g?pwd=2222 提取码: 2222 复制这段内容后打开百度网盘手机App,操作更方便哦

在这里插入图片描述

  • USB摄像头模块

在某宝随便每个USB摄像头模块就ok。

3、程序介绍

3.1 程序概况

garbage.py //云端提供的py程序,不用自己编写,改改参数,看得懂就ok
garbage.c & garbage.h  //利用C语言调用py文件,并且进行了封装,方便main函数调用
>>> https://blog.csdn.net/Super_Fisher_man/article/details/137055641
uartTool.c & uartTool.h //串口通信程序
>>> https://blog.csdn.net/Super_Fisher_man/article/details/136662787main.c //主函数,将两者结合

garbage.c & uartTool.c 在前面的文章都已经介绍过了,这边就不多加赘述

3.2 语言模块SDK配置介绍

在这里插入图片描述
在这里插入图片描述

3.3 程序文件

3.3.1 开启摄像头的程序
  • 可以看看之前的blog

基于香橙派 调用USB摄像头 的两种方法(命令&脚本)-CSDN博客

# start.sh
# /home/orangepi/mjpg-streamer/mjpg-streamer-experimental
export LD_LIBRARY_PATH="$(pwd)"
#./mjpg_streamer -i "input_uvc.so --help"./mjpg_streamer -i "./input_uvc.so -d /dev/video0 -u -f 30" -o "./output_http.so -w ./www"
# mjpg.sh
# /home/orangepi
#!/bin/bashcd /home/orangepi/mjpg-streamer/mjpg-streamer-experimental
./start.sh 
  • 在清除了mjpg进程的前提下命令

  • >>> ps ax | grep mjpg
    >>> kill -9 ×××
    >>> ./mjpg.sh
    
3.3.2 云端识别函数( Py ==> C ) & 串口程序
  • 云端调用的程序,只需改 #场景二 就ok
//garbage.py
# -*- coding: utf-8 -*-
# 引入依赖包
# pip install alibabacloud_imagerecog20190930import os
import io
from urllib.request import urlopen
from alibabacloud_imagerecog20190930.client import Client
from alibabacloud_imagerecog20190930.models import ClassifyingRubbishAdvanceRequest
from alibabacloud_tea_openapi.models import Config
from alibabacloud_tea_util.models import RuntimeOptionsconfig = Config(# 创建AccessKey ID和AccessKey Secret,请参考https://help.aliyun.com/document_detail/175144.html。# 如果您用的是RAM用户的AccessKey,还需要为RAM用户授予权限AliyunVIAPIFullAccess,请参考https://help.aliyun.com/document_detail/145025.html# 从环境变量读取配置的AccessKey ID和AccessKey Secret。运行代码示例前必须先配置环境变量。access_key_id=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID'),access_key_secret=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),# 访问的域名endpoint='imagerecog.cn-shanghai.aliyuncs.com',# 访问的域名对应的regionregion_id='cn-shanghai'
)def alibaba_garbage(): # 封装成一个函数,方便其他文件调用#场景一:文件在本地# img = open(r'/home/orangepi/garbage/lj/test2.jpg','rb')img = open(r'/tmp/garbage.jpg','rb')#场景二:使用任意可访问的url# url = 'https://viapi-test-bj.oss-cn-beijing.aliyuncs.com/viapi-3.0domepic/imagerecog/ClassifyingRubbish/ClassifyingRubbish1.jpg'# img = io.BytesIO(urlopen(url).read())classifying_rubbish_request = ClassifyingRubbishAdvanceRequest()classifying_rubbish_request.image_urlobject = imgruntime = RuntimeOptions()try:# 初始化Clientclient = Client(config)response = client.classifying_rubbish_advance(classifying_rubbish_request, runtime)# 获取整体结果# print(response.body) # 默认# print(response.body.to_map()) # 打印出body的类型print(response.body.to_map()['Data']['Elements'][0]['Category']) # 打印出body的类型return response.body.to_map()['Data']['Elements'][0]['Category']# 提供调用方便except Exception as error:# 获取整体报错信息# print(error)# 获取单个字段# print(error.code)return '获取失败'if __name__== "__main__":alibaba_garbage()
  • Py ==> c
//garbage.h
#ifndef __GARBAGE__H
#define __GARBAGE__H
void garbage_init(void);//第一步做初始化,初始python的编译器包括导入当前路劲到sys.path里面
void garbage_final(void);
char *garbage_category(char *category);//127.0.0.1
//通常被称为"本地回环地址"或"localhost";
//这个地址经常用于测试网络应用程序和诊断网络问题
//因为它确保数据能够在同一台计算机上进行循环传输,而无需真正通过网络传输。#define WGET_CMD "wget http://127.0.0.1:8080/?action=snapshot -O /tmp/garbage.jpg" //抓拍命令
#define GARBAGE_FILE "/tmp/garbage.jpg"#endif
// C语言引用Python文件
#if 0
1、包含Python.h头文件,以便使用Python API。
2、使用void Py_Initialize()初始化Python解释器,
3、使用PyObject *PyImport_ImportModule(const char *name)和PyObject
*PyObject_GetAttrString(PyObject *o, const char *attr_name)获取sys.path对象,并利用
int PyList_Append(PyObject *list, PyObject *item)将当前路径.添加到sys.path中,以便加载
当前的Python模块(Python文件即python模块)4、使用PyObject *PyImport_ImportModule(const char *name)函数导入Python模块,并检查是否
有错误。
5、使用PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)函数获取
Python函数对象,并检查是否可调用。
+6、使用PyObject *Py_BuildValue(const char *format, ...)函数将C类型的数据结构转换成
Python对象,作为Python函数的参数,没有参数不需要调用
7、使用PyObject *PyObject_CallObject(PyObject *callable, PyObject *args)函数调用
Python函数,并获取返回值。
+8、使用int PyArg_Parse(PyObject *args, const char *format, ...)函数将返回值转换为C类
型,并检查是否有错误,没有返回值时不需要调用。
9、使用void Py_DECREF(PyObject *o)函数释放所有引用的Python对象。
10、结束时调用void Py_Finalize()函数关闭Python解释器。
相关的函数参数说明参考网站(网站左上角输入函数名即可开始搜索):
https://docs.python.org/zh-cn/3/c-api/import.html
#endif#include <Python.h>
#include "garbage.h"void garbage_init(void)
{Py_Initialize();// 将当前路径添加到sys.path中PyObject *sys = PyImport_ImportModule("sys");//初始化python解释器PyObject *path = PyObject_GetAttrString(sys, "path");PyList_Append(path, PyUnicode_FromString("."));
}void garbage_final(void)
{//释放所有引用的Python对象Py_Finalize();
}
char *garbage_category(char *category)
{// 导入para模块PyObject *pModule = PyImport_ImportModule("garbage");//引用的是本目录底下的garbage.py文件if (!pModule){PyErr_Print();printf("Error: failed to load para.py\n");goto FAILED_MODULE;}//获取 alibaba_garbage 函数对象PyObject *pFunc = PyObject_GetAttrString(pModule, "alibaba_garbage");//garbage.py文件里的这个函数 alibaba_garbageif (!pFunc){PyErr_Print();printf("Error: failed to load say_funny\n");goto FAILED_FUNC;}//调用alibaba_garbage函数并获取返回值PyObject *pValue = PyObject_CallObject(pFunc, NULL);if (!pValue){PyErr_Print();printf("Error: function call failed\n");goto FAILED_VALUE;} //将返回值转换为C类型char *result = NULL;  //pValue(py) --> result(c)if (!PyArg_Parse(pValue, "s", &result))//PyArg_Parse根据指定的格式字符串将 Python 对象转换为 C 变量{PyErr_Print();printf("Error: parse failed\n");goto FAILED_RESULT;}//打印返回值//printf("pValue=%s\n", result);category = (char*)malloc(sizeof(char)*(strlen(result)+1));//要留一个字节给 \0memset(category, 0, (strlen(result)+1));strncpy(category, result,(strlen(result)+1));//复制字符串//会用来标识某个测试案例、任务或计划未能通过或达到预期的标准或目标;失败后跳转
FAILED_RESULT:Py_DECREF(pValue);
FAILED_VALUE:Py_DECREF(pFunc);
FAILED_FUNC:Py_DECREF(pModule);
FAILED_MODULE:return category;
}
  • 串口函数
//uartTool.h
#ifndef __UARTTOOL_H
#define __UARTTOOL_H
int myserialOpen (const char *device, const int baud);
void serialSendstring (const int fd, unsigned const char *s, int len); //写数据
int serialGetstring (const int fd, unsigned char *buffer); //读数据#define SERIAL_DEV "/dev/ttyS5" // 可代替设备节点
#define BAUD 115200             // 代替波特率#endif
//防止头文件中的声明反复区声明
//uartTool.c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "uartTool.h"//先到当前文件夹查看
#include "wiringSerial.h"int myserialOpen (const char *device, const int baud)
{struct termios options ;//这个结构体speed_t myBaud ;int status, fd ;switch (baud){case    9600:	myBaud =    B9600 ; break ;case  115200:	myBaud =  B115200 ; break ;default:}if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)return -1 ;fcntl (fd, F_SETFL, O_RDWR) ;// Get and modify current options:tcgetattr (fd, &options) ;//get//标准化的操作 一般都是固定的cfmakeraw   (&options) ;cfsetispeed (&options, myBaud) ;cfsetospeed (&options, myBaud) ;//波特率的设置 options.c_cflag |= (CLOCAL | CREAD) ;options.c_cflag &= ~PARENB ;//奇偶校验位 options.c_cflag &= ~CSTOPB ;//ͣ停止位 一般都是一位的options.c_cflag &= ~CSIZE ;options.c_cflag |= CS8 ;//数据位 基本都是八位的options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;options.c_oflag &= ~OPOST ;options.c_cc [VMIN]  =   0 ;options.c_cc [VTIME] = 100 ;	// Ten seconds (100 deciseconds)//标准化的操作tcsetattr (fd, TCSANOW, &options) ;//写入内核ioctl (fd, TIOCMGET, &status);//获得整型控制字TIOCMGET get出来status |= TIOCM_DTR ;status |= TIOCM_RTS ;//控制字加上标志位ioctl (fd, TIOCMSET, &status);//写入内核usleep (10000) ;	// 10mSreturn fd ;
}//0XAA 0X55 0X46 0X00 0X55 0XAA
void serialSendstring (const int fd, const unsigned char *s, int len)//去写数据
{int ret;ret = write (fd, s, len);if (ret < 0)printf("Serial Putchar Error\n");
}int serialGetstring (const int fd, unsigned char *buffer)
{int n_read;n_read = read(fd,buffer,6);// printf("%d\n",fd); return n_read;
}
3.3.3 结合 main.c
//main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>#include "uartTool.h"
#include "garbage.h"int main(int argc, char *argv[])
{int serial_fd = -1;int len = 0;char *category = NULL;unsigned char buffer[6] = {0xAA,0x55,0x00,0x00,0x55,0xAA};//AA 55 ** 00 55 AA//初始化garbage_init();//打开设备serial_fd = myserialOpen(SERIAL_DEV,BAUD);//可代替设备节点 & 波特率   返回值fdif(serial_fd == -1)//是否打开成功{goto END;    }while(1){//获取(读)传过来的数据len = serialGetstring(serial_fd,buffer); //P8 & P10 ==> TXD.5 & RXD.5 if(len>0 && buffer[2]==0x46) //0x46命令:识别垃圾类型{buffer[2]==0x00;//define WGET_CMD "wget http://127.0.0.1:8080/?action=snapshot -O /tmp/garbage.jpg" //抓拍命令system(WGET_CMD);//宏定义:拍照命令,garbage.h 文件中// access函数是一个用于测试文件访问权限的函数,它通常用于检查某个文件是否可以被当前用户读取、写入或执行。// 包括F_OK(检查文件是否存在)、R_OK(检查读权限)、W_OK(检查写权限)和X_OK(检查执行权限)// 该函数返回值为0表示有权限,-1表示无权限或发生错误。if(0 == access(GARBAGE_FILE, F_OK))//GARBAGE_FILE 宏定义 识别到的垃圾图片是否存在{category = garbage_category(category);//调用阿里云接口判断垃圾类型if(strstr(category,"干垃圾")){buffer[2] = 0x41;//赋值}else if(strstr(category,"湿垃圾")){buffer[2] = 0x42;}else if(strstr(category,"可回收垃圾")){buffer[2] = 0x43;}else if(strstr(category,"有害垃圾")){buffer[2] = 0x44;}else{buffer[2] = 0x45;// 未识别成功}}else{buffer[2] = 0x45;}serialSendstring(serial_fd,buffer,6);//写数据,回传给语音模块buffer[2]=0x00;//将buffer[2]清零remove(GARBAGE_FILE);//garbage.h 的宏定义 把识别到的垃圾的图片清除掉}}END:garbage_final; //释放所有引用的Python对象return 0;  
}

3.4 程序运行结果

  • 先杀进程

在这里插入图片描述

  • 打开摄像头

在这里插入图片描述

  • 显示视频内容、抓拍
    在这里插入图片描述
    在这里插入图片描述

  • 执行结果

在这里插入图片描述

语言会自动回复,该垃圾是什么类型



欢迎大家一起交流讨论

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/777799.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot 防护 XSS + SQL 注入攻击

XSS跨站脚本攻击 ① XSS漏洞介绍 跨站脚本攻击XSS是指攻击者往Web页面里插入恶意Script代码&#xff0c;当用户浏览该页之时&#xff0c;嵌入其中Web里面的Script代码会被解析执行&#xff0c;从而达到恶意攻击用户的目的。XSS攻击针对的是用户层面的攻击&#xff01; ② XSS…

【 MyBatis 】| 关于多表联查返回 List 集合只查到一条的 BUG

目录 一. &#x1f981; 写在前面二. &#x1f981; 探索过程2.1 开端 —— 开始写 bug2.2 发展 —— bug 完成2.3 高潮 —— bug探究2.4 结局 —— 效果展示 三. &#x1f981; 写在最后 一. &#x1f981; 写在前面 今天又是 BUG 气满满的一天&#xff0c;一个 xxxMapper.xm…

spark核心概念

DAG 所谓DAG就是有向无环图&#xff0c;其实就是个无环的流程&#xff0c;Spark的核心是根据RDD来实现的&#xff0c;Spark Scheduler!则为Spark核心实现的重要一环&#xff0c;其作用就是任务调度。Spark的任务调度就是如何组织任务去处理RDD中每个分区的数据&#xff0c;根据…

Day53:WEB攻防-XSS跨站SVGPDFFlashMXSSUXSS配合上传文件添加脚本

目录 MXSS UXSS&#xff1a;Universal Cross-Site Scripting HTML&SVG&PDF&SWF-XSS&上传&反编译(有几率碰到) SVG-XSS PDF-XSS Python生成XSS Flash-XSS 知识点&#xff1a; 1、XSS跨站-MXSS&UXSS 2、XSS跨站-SVG制作&配合上传 3、XSS跨站-…

Docker进阶:使用Docker部署Harbor私有镜像仓库

Docker进阶&#xff1a;使用Docker部署Harbor私有镜像仓库 1、安装Docker和Docker Compose1、安装Docker、Docker Compose2、验证Docker和Docker Compose是否成功安装3、先启动运行docker服务 2、下载并配置Harbor1、下载最新版本的Harbor离线安装包2、配置Harbor的主机名和管理…

京东云搭建幻兽帕鲁Palworld多人游戏联机服务器教程,1分钟开服

使用京东云服务器搭建幻兽帕鲁Palworld游戏联机服务器教程&#xff0c;非常简单&#xff0c;京东云推出幻兽帕鲁镜像系统&#xff0c;镜像直接选择幻兽帕鲁镜像即可一键自动部署&#xff0c;不需要手动操作&#xff0c;真正的新手0基础部署幻兽帕鲁&#xff0c;阿腾云atengyun.…

uni-app(使用阿里图标)

1.注册阿里矢量图标库 注册阿里图标库账号并登录&#xff0c;https://www.iconfont.cn/ 2.加入购物车 搜索适合自己的图标&#xff0c;加入购物车&#xff0c;如下图&#xff1a; 3.加入项目 我的->资源管理->我的项目->创建项目&#xff0c;然后返回购物车&#…

中国信通院 X StarRocks金融用户社区正式成立

在国家战略的推动下&#xff0c;开源技术正逐渐成为金融行业创新发展的重要驱动力。2024 年 3 月 26 日&#xff0c;中国信息通信研究院 X StarRocks 金融用户社区&#xff08;以下简称“社区”&#xff09;正式成立&#xff0c;这一举措旨在深化国内金融领域的开源生态建设&am…

粗略总结AI大模型学习需要了解的要点

目录 一、概念简介 二、兴起原因 三、相关要点 四、不足之处 五、总结 一、概念简介 AI大模型学习是指利用大规模数据集和强大计算能力进行深度学习模型的训练。随着数据的爆炸式增长和计算资源的提升&#xff0c;AI大模型学习成为了现代人工智能研究的重要方向。 二、兴起…

使用pytorch构建一个初级的无监督的GAN网络模型

在这个系列中将系统的构建GAN及其相关的一些变种模型&#xff0c;来了解GAN的基本原理。本片为此系列的第一篇&#xff0c;实现起来很简单&#xff0c;所以不要期待有很好的效果出来。 第一篇我们搭建一个无监督的可以生成数字 (0-9) 手写图像的 GAN&#xff0c;使用MINIST数据…

入门指南|营销中人工智能生成内容的主要类型 [新数据、示例和技巧]

由于人工智能技术的进步&#xff0c;内容生成不再是一项令人头疼的任务。随着人工智能越来越多地接管手动内容制作任务&#xff0c;营销人员明智的做法是了解现有的不同类型的人工智能生成内容&#xff0c;以及哪些内容从中受益最多。这些工具可以帮助我们制作对您的受众和品牌…

Synchronized锁、公平锁、悲观锁乐观锁、死锁等

悲观锁 认为自己在使用数据的时候一定会有别的线程来修改数据,所以在获取数据前会加锁,确保不会有别的线程来修改 如: Synchronized和Lock锁 适合写操作多的场景 乐观锁 适合读操作多的场景 总结: 线程8锁🔐 调用 声明 结果:先打印发送短信,后打印发送邮件 结论…

机器学习(三)

神经网络: 神经网络是由具有适应性的简单单元组成的广泛并行互连的网络&#xff0c;它的组织能够模拟生物神经系统对真实世界物体所作出的交互反应。 f为激活(响应)函数: 理想激活函数是阶跃函数&#xff0c;0表示抑制神经元而1表示激活神经元。 多层前馈网络结构: BP(误差逆…

OpenPLC_Editor 在Ubuntu 虚拟机安装记录

1. OpenPLC_Editor在虚拟机上费劲的装了一遍&#xff0c;有些东西已经忘了&#xff0c;主要还是python3 的缺失库版本对应问题&#xff0c;OpenPLC_Editor使用python3编译的&#xff0c;虚拟机的Ubuntu 18.4 有2.7和3.6两个版本&#xff0c;所以需要注意。 2. OpenPLC_Editor …

Svg Flow Editor 原生svg流程图编辑器(四)

系列文章 Svg Flow Editor 原生svg流程图编辑器&#xff08;一&#xff09; Svg Flow Editor 原生svg流程图编辑器&#xff08;二&#xff09; Svg Flow Editor 原生svg流程图编辑器&#xff08;三&#xff09; Svg Flow Editor 原生svg流程图编辑器&#xff08;四&#xf…

贪心算法--最大数

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 本题链接https://leetcode.cn/problems/largest-number/description/ class Solution { public:bool static compare(int a, int b){return (to_string(a) to_string(b)) > (to_string(b) to_string(a));}bool operato…

探索 2024 年 Web 开发最佳前端框架

前端框架通过简化和结构化的网站开发过程改变了 Web 开发人员设计和实现用户界面的方法。随着 Web 应用程序变得越来越复杂&#xff0c;交互和动画功能越来越多&#xff0c;这是开发前端框架的初衷之一。 在网络的早期&#xff0c;网页相当简单。它们主要以静态 HTML 为特色&a…

数据库---PDO

以pikachu数据库为例&#xff0c;数据库名&#xff1a; pikachu 1.连接数据库 <?php $dsn mysql:hostlocalhost; port3306; dbnamepikachu; // 这里的空格比较敏感 $username root; $password root; try { $pdo new PDO($dsn, $username, $password); var_dump($pdo)…

【管理咨询宝藏59】某大型汽车物流战略咨询报告

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏59】某大型汽车物流战略咨询报告 【格式】PDF 【关键词】HR调研、商业分析、管理咨询 【核心观点】 - 重新评估和调整商业模式&#xff0c;开拓…

如何开始定制你自己的大型语言模型

2023年的大型语言模型领域经历了许多快速的发展和创新&#xff0c;发展出了更大的模型规模并且获得了更好的性能&#xff0c;那么我们普通用户是否可以定制我们需要的大型语言模型呢&#xff1f; 首先你需要有硬件的资源&#xff0c;对于硬件来说有2个路径可以选。高性能和低性…