【阿里云】图像识别智能分类识别项目开发(一)
- 开源代码
- 2025-07-21 19:26:54

语音模块和阿里云图像识别结合 环境准备 代码实现 编译运行 写个shell脚本用于杀死运行的进程
语音模块和阿里云图像识别结合使用语音模块和摄像头在香橙派上做垃圾智能分类识别 语音控制摄像下载上传阿里云解析功能点实现
环境准备将语音模块接在UART5的位置
在orange pi 3.0.6上确认已经配置开启了uart5:(overlays=uart5)
cat /boot/orangepiEnv.txt3. 同时将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_imagerecog20190930 import 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 RuntimeOptions config = Config( # 创建AccessKey ID和AccessKey Secret,请参考 help.aliyun /document_detail/175144.html。 # 如果您用的是RAM用户的AccessKey,还需要为RAM用户授予权限AliyunVIAPIFullAccess,请参考 help.aliyun /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 -shanghai.aliyuncs ', # 访问的域名对应的region region_id='cn-shanghai' ) def alibaba_garbage(): # 场景一:文件在本地 img = open(r'/tmp/garbage.jpg', 'rb') # 场景二:使用任意可访问的url # url = ' viapi-test-bj.oss-cn-beijing.aliyuncs /viapi-3.0domepic/imagerecog/ClassifyingRubbish/ClassifyingRubbish1.jpg' # img = io.BytesIO(urlopen(url).read()) classifying_rubbish_request = ClassifyingRubbishAdvanceRequest() classifying_rubbish_request.image_urlobject = img runtime = RuntimeOptions() try: # 初始化Client client = 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__H void 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_H int 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 ; // 如果打开失败,返回错误代码 -1 fcntl (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 $PID echo "Process ./test (PID $PID) killed." else echo "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来执行脚本。确保在运行脚本之前你的程序已经启动。
【阿里云】图像识别智能分类识别项目开发(一)由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【阿里云】图像识别智能分类识别项目开发(一)”