【阿里云】图像识别 智能分类识别 项目开发(一)

语音模块和阿里云图像识别结合
环境准备
代码实现
编译运行
写个shell脚本用于杀死运行的进程

语音模块和阿里云图像识别结合

使用语音模块和摄像头在香橙派上做垃圾智能分类识别
语音控制摄像下载上传阿里云解析功能点实现
在这里插入图片描述

环境准备

  1. 将语音模块接在UART5的位置
    请添加图片描述

  2. 在orange pi 3.0.6上确认已经配置开启了uart5:(overlays=uart5)

cat /boot/orangepiEnv.txt

在这里插入图片描述
3. 同时将USB摄像头接到香橙派上
4. 确认已经运行了mjpg-streamer服务

ps ax | grep mjpg_streamer | grep -v grep

在这里插入图片描述

代码实现

main.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>#include "uartTool.h"
#include "garbage.h"// 判断进程是否在运行
static int detect_process(const char * process_name)
{int n = -1;FILE *strm;char buf[128] = {0};// 构造命令字符串,通过ps命令查找进程sprintf(buf, "ps -ax | grep %s|grep -v grep", process_name);// 使用popen执行命令并读取输出if ((strm = popen(buf, "r")) != NULL) {if (fgets(buf, sizeof(buf), strm) != NULL) {n = atoi(buf); // 将进程ID字符串转换为整数}}else {return -1; // popen失败}	pclose(strm); // 关闭popen打开的文件流return n;
}int main(int argc, char *argv[])
{int serial_fd = -1;int ret = -1;unsigned char buffer[6] = {0xAA, 0X55, 0x00, 0x00, 0x55, 0xAA};int len = 0;char *category = NULL;// 初始化串口和垃圾分类模块garbage_init ();// 用于判断mjpg_streamer服务是否已经启动ret = detect_process ("mjpg_streamer");if (-1 == ret) {printf("detect process failed\n");goto END;}// 打开串口serial_fd = my_serialOpen (SERIAL_DEV, BAUD);if (-1 == serial_fd) {goto END;}while (1) {// 从串口读取数据len = my_serialGetstring (serial_fd, buffer);printf("lend = %d, buf[2] = 0x%x\n", len, buffer[2]);if (len > 0 && buffer[2] == 0x46) {buffer[2] = 0x00;// 在执行wget命令之前添加调试输出printf("Executing wget command...\n");// 使用系统命令拍照system(WGET_CMD);// 在执行wget命令之后添加调试输出printf("Wget command executed.\n");// 判断垃圾种类if (0 == access(GARBAGE_FILE, F_OK)) {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; //识别失败}// 发送分类结果到串口my_serialSendstring (serial_fd, buffer, 6);buffer[2] = 0x00;remove(GARBAGE_FILE); // 删除拍照文件}}
END:// 释放垃圾分类资源garbage_final();return 0;
}

garbage.py

# 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'/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()['Data']['Elements'][0]['Category'])return response.body.to_map()['Data']['Elements'][0]['Category']except Exception as error:# 获取整体报错信息# print(error)print(type('获取失败'))return '获取失败'# 获取单个字段# print(error.code)if __name__ == "__main__":alibaba_garbage()

garbage.h

#ifndef __GARBAGE__H
#define __GARBAGE__Hvoid garbage_init();
void garbage_final();
char *garbage_category(char *category);// 增加拍照指令和照片路径宏定义
#define WGET_CMD "wget http://127.0.0.1:8080/?action=snapshot -O /tmp/garbage.jpg"
#define GARBAGE_FILE "/tmp/garbage.jpg"#endif

garbage.c

#include <stdio.h>
#include <Python.h>
#include "garbage.h"void garbage_init()
{// 初始化Python解释器Py_Initialize();// 获取sys.path对象PyObject* sysPath = PySys_GetObject("path");// 将当前路径添加到sys.path中PyList_Append(sysPath, PyUnicode_DecodeFSDefault(".")); // PyUnicode_FromString将c字符串转换成Python字符串
}void garbage_final()
{// 关闭Python解释器Py_Finalize();
}char *garbage_category(char *category) 
{// 导入Python模块PyObject* pModule = PyImport_ImportModule("garbage");if (pModule != NULL) {// 获取Python函数对象PyObject* pFunction = PyObject_GetAttrString(pModule, "alibaba_garbage");if (pFunction != NULL && PyCallable_Check(pFunction)) {// 调用Python函数,这里是无参数调用PyObject* pArgs = PyTuple_New(0);  // 传递空参数元组PyObject* pResult = PyObject_CallObject(pFunction, pArgs);if (pResult != NULL) {// 将返回值转换为C类型char *result = NULL;if (!PyArg_Parse(pResult, "s", &result)) {PyErr_Print();printf("Error: parse failed\n");}// 打印返回值printf("pResult = %s\n", result);// 为垃圾分类信息分配内存,复制返回值category = (char *)malloc(sizeof(char) * (strlen(result) + 1));memset(category, 0, (strlen(result) + 1));strncpy(category, result, (strlen(result) + 1));Py_DECREF(pResult);} else {PyErr_Print(); // 打印Python错误信息}Py_DECREF(pFunction);Py_DECREF(pArgs);} else {PyErr_Print();}Py_DECREF(pModule);} else {PyErr_Print();}return category;
}

uartTool.h

#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 "wiringSerial.h"#ifndef __UARTTOOL_H
#define __UARTTOOL_Hint my_serialOpen (const char *device, const int baud) ;void my_serialSendstring (const int fd, const unsigned char *s, int len) ;int my_serialGetstring (const int fd, unsigned char *buffer) ;#define SERIAL_DEV "/dev/ttyS5"
#define BAUD 115200#endif

uartTool.c

#include "wiringSerial.h"
#include "uartTool.h"int my_serialOpen (const char *device, const int baud)
{struct termios options ;   // 创建一个termios结构体,用于串口参数设置speed_t myBaud ;   // 创建一个速度类型的变量 myBaud,用于保存波特率int status, fd ;   // 创建整数类型的变量 status 和 fd,用于保存状态和文件描述符switch (baud){   // 根据传入的波特率参数选择合适的波特率常数case   9600: myBaud =   B9600 ; break ; case 115200: myBaud = B115200 ; break ; }if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)   // 打开串口设备,设置打开选项return -1 ;   // 如果打开失败,返回错误代码 -1fcntl (fd, F_SETFL, O_RDWR) ;   // 设置文件状态标志// Get and modify current options: 获取并修改当前的串口参数:tcgetattr (fd, &options) ;   // 获取当前的串口参数cfmakeraw (&options) ;   // 初始化 termios 结构体为原始模式cfsetispeed (&options, myBaud) ;  // 设置输入波特率cfsetospeed (&options, myBaud) ;  // 设置输出波特率options.c_cflag |= (CLOCAL | CREAD) ;  // 本地连接和使能接收options.c_cflag &= ~PARENB ;  // 禁用奇偶校验options.c_cflag &= ~CSTOPB ;  // 1位停止位options.c_cflag &= ~CSIZE ;  // 用数据位掩码清空数据位设置options.c_cflag |= CS8 ;  // 设置8位数据位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) 超时等待时间(十分之一秒100ms)tcsetattr (fd, TCSANOW, &options) ;   // 设置新的串口参数ioctl (fd, TIOCMGET, &status);   // 获取串口控制模式状态status |= TIOCM_DTR ;   // 设置 DTR(数据终端就绪)位status |= TIOCM_RTS ;   // 设置 RTS(请求发送)位ioctl (fd, TIOCMSET, &status);   // 设置串口控制模式状态usleep (10000) ;  // 暂停 10 毫秒return fd ;   // 返回串口文件描述符
}void my_serialSendstring (const int fd, const unsigned char *s, int len)
{int ret ;ret = write (fd, s, len) ; if (ret < 0) printf ("Serial Sendstring Error\n") ;
}int my_serialGetstring (const int fd, unsigned char *buffer)
{int n_read ;n_read = read (fd, buffer, 32) ; return n_read ;
}

编译运行

编译 
gcc -o test *.c *.h -I /usr/include/python3.10 -l python3.10执行 
sudo -E ./test
sudo -E 命令用于在以超级用户权限运行命令的同时,保留环境变量查看进程 
ps -ax | grep mjpg_streamer | grep -v grep
ps -ax | grep ./test | grep -v grep
ps aux | grep './test' | grep -v grep | awk '{print $2}'杀死进程 
kill -9 pid (-9——-SIGKILL)

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

写个shell脚本用于杀死运行的进程

当你运行程序时,shell脚本可以使用ps命令查找到特定进程的PID并使用kill命令杀死该进程。
以下是一个简单的Shell脚本示例,假设你的程序名为test

#!/bin/bash# 查找进程PID
PID=$(ps aux | grep './test' | grep -v grep | awk '{print $2}')if [ -n "$PID" ]; then# 杀死进程kill -SIGKILL $PIDecho "Process ./test (PID $PID) killed."
elseecho "Process ./test not found."
fi

这个脚本中,ps aux命令获取当前所有进程的信息,grep './test'用于查找包含"./test"的进程,awk '{print $2}'用于提取PID。然后,脚本检查是否找到了进程,如果找到,就使用kill命令杀死进程,并输出相关信息。如果没有找到对应进程,输出相应的提示。

grep -v grep 是为了在使用 ps 命令结合 grep 进行进程查询时,排除掉 grep 进程本身。当你执行 ps aux | grep 'test' 时,该命令本身也会被匹配,因为它包含了关键字 'test'。为了排除掉这个匹配,使用 grep -v grep 来过滤掉含有 'grep' 字符串的行,从而得到准确的进程信息。

将这个脚本保存为kill_test.sh,并添加执行权限:

chmod +x kill_test.sh

然后可以通过运行./kill_test.sh来执行脚本。确保在运行脚本之前你的程序已经启动。

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

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

相关文章

KVM虚拟机的NAT网络模式原理及过程展示

NAT的方式及原理 NAT方式是KVM安装后的默认方式。 它支持主机与虚拟机的互访&#xff0c;同时也支持虚拟机访问互联网&#xff0c;但不支持外界访问虚拟机。 default是宿主机安装虚拟机支持模块的时候自动安装的。 其中 virbr0是由宿主机虚拟机支持模块安装时产生的虚拟网络接…

4、LED闪烁

LED亮灭 使用STC-ISP软件的延时计算器自动生成延迟子函数 #include <REGX52.H> #include <INTRINS.H>//延迟函数 void Delay500ms() //12.000MHz {unsigned char i, j, k;//_nop_()需要导入<INTRINS.H>包_nop_();i 4;j 205;k 187;do{do{while (--k);}…

JVM类加载的过程和JVM垃圾回收机制

文章目录 一、JVM类加载的过程1.1类加载的基本流程1.1.1加载1.1.2验证1.1.3准备1.1.4解析1.1.5初始化 1.2双亲委派模型 二、JVM垃圾回收机制2.1找到垃圾2.1.1引用计数(比如Python&#xff0c;PHP中用到)2.1.2可达性分析(比如Java中用到) 2.2释放垃圾2.2.1标记清除2.2.2复制算法…

jetson NX部署Yolov8

一,事情起因,由于需要对无人机机载识别算法进行更新,所以需要对yolov8算法进行部署到边缘端。 二,环境安装 安装虚拟环境管理工具,这个根据个人喜好。 我们需要选择能够在ARM架构上运行的conda,这里我们选择conda-forge 下载地址 安装即可 剩下的就是和conda 创建虚拟…

Jensen不等式

如果是正数&#xff0c;并且它们的和等于1&#xff0c;f是凸函数&#xff0c;那么&#xff1a; 也可表述为&#xff1a; 即x期望的凸函数值小于等于x凸函数值的期望

5、LED流水灯

LED流水灯 思路&#xff1a;每次LED灯熄灭后&#xff0c;下一个LED灯亮 #include <REGX52.H> #include <INTRINS.H>void Delay500ms() //12.000MHz {unsigned char i, j, k;_nop_();i 4;j 205;k 187;do{do{while (--k);} while (--j);} while (--i); }void m…

Leetcode—45.跳跃游戏II【中等】

2023每日刷题&#xff08;四十&#xff09; Leetcode—45.跳跃游戏II 贪心法思想 实现代码 #define MAX(a, b) (a > b ? (a) : (b))int jump(int* nums, int numsSize) {int start 0;int end 1;int ans 0;int maxStride 0;while(end < numsSize) {maxStride 0;fo…

【程序员的自我修养01】编译流程概述

绪论 大家好&#xff0c;欢迎来到【程序员的自我修养】专栏。正如其专栏名&#xff0c;本专栏主要分享学习《程序员的自我修养——链接、装载与库》的知识点以及结合自己的工作经验以及思考。编译原理相关知识本身就比较有难度&#xff0c;我会尽自己最大的努力&#xff0c;争取…

Kotlin学习——流程控制,when,循环,range工具 kt里的equals if实现类似三元表达式的效果

Kotlin 是一门现代但已成熟的编程语言&#xff0c;旨在让开发人员更幸福快乐。 它简洁、安全、可与 Java 及其他语言互操作&#xff0c;并提供了多种方式在多个平台间复用代码&#xff0c;以实现高效编程。 https://play.kotlinlang.org/byExample/01_introduction/02_Functio…

acm是什么?你准备好去打了吗?

1.引言2.acm究竟是什么&#xff1f;3.acm的时间安排重点 赛制查询榜单网络赛的作用1.名额分配2.校内选拔 icpc省赛省赛选拔赛(校内) 4.acm该如何准备1.前期的算法积累1.Acwing 平台算法基础课 -y总业界良心。算法提高课 基本囊括了蓝桥杯的知识范畴算法进阶课&#xff08;选&am…

只考数据结构,计算机评级C+,成都信息工程大学考情分析

成都信息工程大学(C) 考研难度&#xff08;☆☆&#xff09; 内容&#xff1a;23考情概况&#xff08;拟录取和复试分析&#xff09;、院校概况、24专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文1715字&#xff0c;预计阅读&#xff1a;3分钟 2023考情概况 …

2022年12月 Scratch(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 默认小猫角色和气球角色都是显示状态,小猫程序如下图所示,气球没有程序,点击绿旗,舞台上最终显示的效果是?( ) A:可能出现6个不同位置的小猫和6个小球 B:可能出现6个不同位…