基于Mask rcnn的行人检测与安卓客户端的移动监控系统

一. Mask rcnn简述

Mask rcnn是何凯明基于以往的faster rcnn架构提出的新的卷积网络,一举完成了object instance segmentation. 该方法在有效地目标的同时完成了高质量的语义分割。 文章的主要思路就是把原有的Faster-RCNN进行扩展,添加一个分支使用现有的检测对目标进行并行预测。同时,这个网络结构比较容易实现和训练,速度5fps也算比较快点,可以很方便的应用到其他的领域,像目标检测,分割,和人物关键点检测等。并且比着现有的算法效果都要好,在后面的实验结果部分有展示出来。

场景理解

Mask R-CNN: overview

 

从上面可以知道,mask rcnn主要的贡献在于如下:

1. 强化的基础网络

通过 ResNeXt-101+FPN 用作特征提取网络,达到 state-of-the-art 的效果。作者替换了在faster rcnn中使用的vgg网络,转而使用特征表达能力更强的残差网络,另外为了挖掘多尺度信息,作者还使用了FPN网络。

2. ROIAlign解决Misalignment 的问题

说到这里,自然要与roi pooling对比。

我们先看看roi pooling的原理,这里我们可以看下面的动图,一目了然。

roi_pooling_animation.gif

 

对于roi pooling,经历了两个量化的过程:

第一个:从roi proposal到feature map的映射过程。方法是[x/16],这里x是原始roi的坐标值,而方框代表四舍五入。

第二个:从feature map划分成7*7的bin,每个bin使用max pooling。

如上,roi映射到feature map后,不再进行四舍五入。然后将候选区域分割成k x k个单元, 在每个单元中计算固定四个坐标位置,用双线性内插的方法计算出这四个位置的值,然后进行最大池化操作。

这里对上述步骤的第三点作一些说明:这个固定位置是指在每一个矩形单元(bin)中按照比例确定的相对位置。比如,如果采样点数是1,那么就是这个单元的中心点。如果采样点数是4,那么就是把这个单元平均分割成四个小方块以后它们分别的中心点。显然这些采样点的坐标通常是浮点数,所以需要使用插值的方法得到它的像素值。在相关实验中,作者发现将采样点设为4会获得最佳性能,甚至直接设为1在性能上也相差无几。事实上,ROI Align 在遍历取样点的数量上没有ROIPooling那么多,但却可以获得更好的性能,这主要归功于解决了misalignment的问题。值得一提的是,在做实验的时候发现,ROI Align在VOC2007数据集上的提升效果并不如在COCO上明显。经过分析为造成这种区别的原因是COCO上小目标的数量更多,而小目标misalignment问题的影响更为明显(比如,同样是0.5个像素点的偏差,对于较大的目标而言显得微不足道,但是对于小目标,误差的影响就要高很多)

二. 实验结果

 

三. 将图片进行推流,并在安卓端显示

from flask import Flask, render_template, Response
from camera import VideoCamera

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

def gen(camera):
    while True:
        frame = camera.get_frame()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')

@app.route('/video_feed')
def video_feed():
    return Response(gen(VideoCamera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080, debug=True)

 

其实完成第一步就几乎完成了很大部分的工作了,用手机浏览器输入ip地址就可以查看。但是编写手机客户端有利于摄像头的管

我在这里主要说说图片获取之后的处理和显示的方法。

http获取图片数据流


  private void doGet() {
        //get http img
        String url = "http://192.168.0.105:8080/?action=snapshot";
//        Log.d(TAG, url);
        myHttpThreadGet = new HttpThreadGet(url, HttpThreadGet.GETIMG, handler);
        myHttpThreadGet.start();
}

消息传递获取,这里只用了获取图片

/************************** msg接收 *************************/
 
        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case HttpThreadPost.POST:
                        result = (String) msg.obj;
                        break;
                    case HttpThreadGet.GET:
                        result = (String) msg.obj;
                        break;
                    case HttpThreadGet.GETIMG:
                        buffer = (byte[])msg.obj;
                        try {
                            image = BitmapFactory.decodeByteArray(buffer, 0, buffer.length, BitmapFactoryinfo);
                            faceDetect(image);
                        } catch (Exception e) {
                            Log.e(TAG, e.toString());
                        }
                        doGet();    //再请求
                        break;
                    default:
                        break;
                }
            }
        };

由于图片是JPEG格式的数据流,需要通过BitmapFactory重新编码,如果要实现人脸识别FaceDetector的话需要将图片格式化Bitmap.Config.RGB_565。

/************************** face detect *************************/
 
    private void faceDetect(Bitmap fBitmap) {
//        myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.baby, BitmapFactoryOptionsbfo);
        int imageWidth = fBitmap.getWidth();
        int imageHeight = fBitmap.getHeight();
        myFace = new FaceDetector.Face[numberOfFace];       //分配人脸数组空间
        myFaceDetect = new FaceDetector(imageWidth, imageHeight, numberOfFace);
        numberOfFaceDetected = myFaceDetect.findFaces(fBitmap, myFace);    //FaceDetector 构造实例并解析人脸
        countertext.setText("numberOfFaceDetected is " + numberOfFaceDetected);
        Log.i(TAG,"numberOfFaceDetected is " + numberOfFaceDetected);
        Bitmap bitmapTemp = Bitmap.createBitmap(fBitmap.getWidth(), fBitmap.getHeight(), Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(bitmapTemp);
        canvas.drawColor(Color.TRANSPARENT);
        Paint myPaint = new Paint();
        myPaint.setColor(Color.GREEN);
        myPaint.setStyle(Paint.Style.STROKE);
        myPaint.setStrokeWidth(3);          //设置位图上paint操作的参数
        canvas.drawBitmap(fBitmap, 0, 0, myPaint);
 
        for(int i=0; i < numberOfFaceDetected; i++){
            Face face = myFace[i];
            PointF myMidPoint = new PointF();
            face.getMidPoint(myMidPoint);
            myEyesDistance = face.eyesDistance();   //得到人脸中心点和眼间距离参数,并对每个人脸进行画框
            canvas.drawRect(            //矩形框的位置参数
                    (int)(myMidPoint.x - myEyesDistance),
                    (int)(myMidPoint.y - myEyesDistance),
                    (int)(myMidPoint.x + myEyesDistance),
                    (int)(myMidPoint.y + myEyesDistance),
                    myPaint);
        }
        imageview.setImageBitmap(bitmapTemp);
}


 

### Mask R-CNN 部署教程及最佳实践 #### 1. 环境准备 为了成功部署 Mask R-CNN 模型,首先需要安装必要的依赖项。这通常包括 Python、TensorFlow 或 PyTorch(取决于具体实现)、以及 OpenCV 和其他辅助库。如果使用的是 Keras 实现,则需确保 TensorFlow 后端已正确配置[^2]。 对于硬件环境而言,GPU 加速可以显著提升推理速度。因此建议在支持 CUDA 的 GPU 上运行模型。此外,还需要考虑目标设备的计算能力,例如嵌入式系统可能无法满足高性能需求,此时可采用模型压缩技术来优化性能[^3]。 #### 2. 数据预处理输入格式转换 Mask R-CNN 接受标准化后的图像作为输入数据。一般情况下,这些图片会被调整到固定尺寸并减去均值向量以匹配训练阶段的数据分布特性。开发人员应仔细阅读所选框架文档中关于数据加载部分的内容,从而保证测试样本能够被正确解析和传递给神经网络层进行前向传播运算。 #### 3. 导出为推理专用格式 当完成训练之后,下一步就是将权重文件保存下来以便后续导入至生产环境中执行预测操作。某些深度学习平台允许导出 ONNX (Open Neural Network Exchange) 格式的通用表示形式,这样就可以跨不同框架共享同一个模型定义而无需重新编写代码逻辑[^4]。 另外值得注意的一点是在实际应用当中可能会遇到多种异构计算单元共存的情况比如 CPU/GPU/FPGA/DSP 等混合架构下工作负载分配问题;针对这种情况可以通过 TensorRT 这样的工具进一步加速特定场景下的表现水平同时保持较高的精度标准不变。 #### 4. 性能调优策略 - **批量大小设置**:适当增大 batch size 可提高吞吐率但会增加延迟时间; - **线程数控制**:合理利用多核处理器资源减少等待队列长度加快整体响应速度; - **内存管理机制改进措施**:避免频繁申请释放大块连续空间造成碎片化现象影响长期稳定性。 最后提醒大家注意监控整个系统的健康状况及时发现潜在瓶颈所在之处进而采取针对性解决方案持续迭代完善直至达到预期效果为止。 ```python import tensorflow as tf from keras.models import load_model # Load the trained model model_path = 'path/to/mask_rcnn.h5' mask_rcnn_model = load_model(model_path) # Prepare input image for inference image = cv2.imread('test_image.jpg') input_tensor = preprocess_image(image) # Custom preprocessing function based on your implementation # Perform prediction using loaded model predictions = mask_rcnn_model.predict(input_tensor) ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值