垃圾分类子项目-识别垃圾类型

思路: 阿里云图像识别 +  语音模块实现

主程序:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h> // access()

#include <error.h>  // remove()

#include "uartTool.h"

#include "garbage.h"

static int detect_process(const char *process_name) // 判断某个进程是否在运行

{

    int n = -1;

    FILE *strm;

    char buf[128] = {0};

    sprintf(buf, "ps -ax | grep %s|grep -v grep", process_name); // 组合进程名字,为完整命令

    if ((strm = popen(buf, "r")) != NULL)                        // 通过 popen 的 方式去执行

    {

        if (fgets(buf, sizeof(buf), strm) != NULL) // 执行完后 判断是否能拿到正确的进程号,空格分开,第一个字符串就是进程号

        {

            n = atoi(buf); // 拿到就放回 进程号,不然  返回 -1

        }

    }

    else

    {

        return -1; // 执行失败

    }

    pclose(strm);

    return n;

}

int main(int argc, char **argv)

{

    int serial_fd = -1;

    int len = 0;

    int ret = -1;

    char *category = NULL;

    unsigned char buffer[6] = {0xAA, 0x55, 0x00, 0x00, 0x55, 0xAA}; // 初始化 buffer[2] --  关联垃圾类型

     garbage_init();     // 先初始化 阿里云接口

    ret = detect_process("mjpg_streamer"); // 用于判断mjpg_streamer服务是否已经启动

    if (-1 == ret)

    {

        goto END;

    }

                           

    serial_fd = myserialOpen(SERIAL_DEV, BAUD); // 初始化串口,打开串口设备(语言模块)

    if (serial_fd == -1)

    { // 初始化串口失败

        goto END;

    }

    while (1) // 等待语言输入

    {

        len = serialGetstring(serial_fd, buffer); // 通过串口获得语言输入

        printf("lend=%d, buf[2]=0x%x\n", len, buffer[2]);

        if (len > 0 && buffer[2] == 0x46)         // 判断是否 需要启动识别

        {

            buffer[2] = 0x00;// 判断完后 恢复,方便下次判断

            system(WGET_CMD); // 拍照

           

           

            //if (access(GARBAGE_FILE, F_OK) == 0) // 判断 文件存在

           // {

                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;                       // 发送完后,一堆有效数据位清零,方便下一次调用

            remove(GARBAGE_FILE);                   // 清理缓存 删除刚刚拍摄的图片,避免对下一次拍摄造成干扰

        }

    }

END:

    garbage_final();

    return 0;

}

头文件

  garbage.h

#ifndef __GARBAGE__H
#define __GARBAGE__H


void garbage_init(void);
void garbage_final(void);
char *garbage_category(char *category);

//为什么能用 127.0.0.1  我们是vscode 远程连接到香橙派 --  实际上是在orangepi上运行,用本地ip即可
#define WGET_CMD "wget http://127.0.0.1:8080/?action=snapshot -O/tmp/garbage.jpg"
#define GARBAGE_FILE "/tmp/garbage.jpg"

#endif

uartTool.h

#ifndef __UARTTOOL_H
#define _UARTTOOL_H

int myserialOpen (const char *device, const int baud);
void serialSendstring (const int fd, const unsigned char *s,int len);
int serialGetstring (const int fd,unsigned char *buffer);

//设置串口5  和 波特率 115200
#define SERIAL_DEV "/dev/ttyS5"
#define BAUD 115200

#endif

其他源文件: 

  garbage.c



#include<Python.h>
#include "garbage.h"

void garbage_init(void)
{
	Py_Initialize();
	PyObject *sys = PyImport_ImportModule("sys");

	PyObject *path = PyObject_GetAttrString(sys,"path");

	PyList_Append(path, PyUnicode_FromString("."));

}
void garbage_final(void)
{
         Py_Finalize();

}



char *garbage_category(char *category)
{

	PyObject *pModule= PyImport_ImportModule("garbage");
	if(!pModule)
	{
		PyErr_Print();
		printf("Error: failed to load garbage.py\n");
	        goto FAILED_MODULE;
	}

	PyObject *pfunc =PyObject_GetAttrString(pModule,"alibaba_garbage");


	if(!pfunc)
	{
		PyErr_Print();
		printf("Error: failed to load alibaba_garbage\n");
                goto FAILED_FUNC;
	}



	PyObject *pValue = PyObject_CallObject(pfunc, NULL);


	if(!pValue)
	{
		PyErr_Print();
		printf("Error:function call failed\n");
                goto FAILED_VALUE;

	}

	char * result = NULL;
	if(!PyArg_Parse(pValue,"s",&result))
	{

		PyErr_Print();
		printf("Error:garbage failed\n");
                goto FAILED_RESULT;

	}	
	printf("result=%s\n",result );
        // pValue 下面会被释放,他的result值就拿不到,得先存起来
        category = (char*)malloc(sizeof(char)*(strlen(result)+1));
        memset(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.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 "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 ;
}
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) ;
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);
status |= TIOCM_DTR ;
status |= TIOCM_RTS ;
ioctl (fd, TIOCMSET, &status);
usleep (10000) ; // 10mS

return fd ;
}
//0xAA 0x55  0x64 00  0x55 0xAA  //0x AA > 157 unsigned
void serialSendstring (const int fd, const unsigned char *s,int len)
{
int ret;
ret = write (fd, s, len); //我们有结束位,而且不为'\0',所以不能用strlen
if (ret < 0)
printf("Serial Puts Error\n");
}
int serialGetstring (const int fd,unsigned char *buffer)
{
int n_read;
n_read = read(fd, buffer,32);
return n_read;
}

  • 15
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值