查看: 15028
回复: 3
做了一个简单的基于Opencv和STM32F103的人脸追踪

主题

回复
发表于2018-11-23 16:03:41 | 显示全部楼层
1# 电梯直达

突然想用手边的STM32最小系统版做一个人脸追踪平台,芯片是STM32F103RCT6。用的是Opencv的人脸识别框架,通过串口把人脸坐标发回单片机完成通信通信。单片机控制两自由度的舵机平台。参考论坛的资料自己做了一个比较简单的实验,高手勿喷


上位机用的C++,但是一直没搞懂C++的8位数据存储结构,导致串口发到单片机里的数据是错误的。但是因为图像坐标最大只有320*300,索性直接除二发出去,单片机接收到之后在乘以2.虽然会造成数据不精确,但由于本身数据不大,精度还行。控制方面用的增量式PID,追踪性能挺好的。


这里贴出增量式PID的基本公式方便大家理解,因为只需要对人脸的移动做出快速的反应,所以只需要PD即可,积分环节可以考虑删除。

 


再把opencv的代码也贴出来,用于在摄像头中找到人脸并返回人脸的中心坐标(只会找到离摄像头最近的人脸)

void detectAndDraw(Mat& img, CascadeClassifier& cascade, CascadeClassifier& nestedCascade, double scale, bool tryflip)
{
    int i = 0;
    double t = 0;
    int coor_SIZE = 3;
    LPBYTE coordinate = NULL;
    coordinate = new BYTE[3];
    vector<Rect> faces, faces2;
    const static Scalar colors[] = { CV_RGB(0,0,255),
        CV_RGB(0,128,255),
        CV_RGB(0,255,255),
        CV_RGB(0,255,0),
        CV_RGB(255,128,0),
        CV_RGB(255,255,0),
        CV_RGB(255,0,0),
        CV_RGB(255,0,255) };

    line(img, cvPoint(230, 200),
        cvPoint(250, 200),
        CV_RGB(0, 255, 255), 2, CV_AA, 0);
    line(img, cvPoint(240, 190),
        cvPoint(240, 210),
        CV_RGB(0, 255, 255), 2, CV_AA, 0);
    Mat gray, smallImg(cvRound(img.rows / scale), cvRound(img.cols / scale), CV_8UC1);
    cvtColor(img, gray, CV_BGR2GRAY);
    resize(gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR);
    equalizeHist(smallImg, smallImg);
    t = (double)cvGetTickCount();
    cascade.detectMultiScale(smallImg, faces, 1.1, 3, 0
        | CV_HAAR_SCALE_IMAGE
        ,
        Size(30, 30));
    if (tryflip)
    {
        flip(smallImg, smallImg, 1);
        cascade.detectMultiScale(smallImg, faces2, 1.1, 2, 0
            | CV_HAAR_SCALE_IMAGE
            , Size(30, 30));
        for (vector<Rect>::const_iterator r = faces2.begin(); r != faces2.end(); r++)
        {
            faces.push_back(Rect(r->x, r->y, r->width, r->height));
        }
    }

    t = (double)cvGetTickCount() - t;


    for (vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++)
    {
        Mat smallImgROI;
        vector<Rect> nestedObjects;
        Point center;
        Scalar color = colors[i % 8];
        int radius = 0;

        double aspect_ratio = (double)r->width / r->height;
        if (0.75 < aspect_ratio && aspect_ratio < 1.3)
        {
            center.x = cvRound((r->x + r->width*0.5)*scale);
            center.y = cvRound((r->y + r->height*0.5)*scale);
            radius = cvRound((r->width + r->height)*0.25*scale);

            circle(img, center, radius, color, 3, 8, 0);
            coordinate[0] = 100;
            coordinate[1] = center.x/2;
            coordinate[2] = center.y/2;
            cout << radius << endl;
            COM_Operate.ComWrite(coordinate, coor_SIZE);
        }
        else
            rectangle(img, cvPoint(cvRound(r->x*scale), cvRound(r->y*scale)),
                cvPoint(cvRound((r->x + r->width - 1)*scale), cvRound((r->y + r->height - 1)*scale)),
                color, 3, 8, 0);

        if (nestedCascade.empty())
            continue;


    }

    cv::imshow("摄像头", img);
}

希望大家多多支持我,我是休息的哈密瓜,每周五随缘更新。大家锁定我的频道,收藏,点赞加转发。


主题

回复
发表于2020-12-02 09:34:17   |  显示全部楼层
3#
你好,可以加个联系吗,大佬。想问你问题

主题

回复
  • 温馨提示: 标题不合格、重复发帖、发布广告贴,将会被删除帖子或禁止发言。 详情请参考: 社区发帖规则
  • 您当前输入了 0 个文字。还可以输入 8000 个文字。 已添加复制上传图片功能,该功能目前仅支持chrome和火狐

禁言/删除

X
请选择禁言时长:
是否清除头像:
禁言/删除备注:
昵 称:
 
温馨提示:昵称只能设置一次,设置后无法修改。
只支持中文、英文和数字。

举报

X
请选择举报类型:
请输入详细内容:

顶部