扫描图像场景下平移手机的运动检测方法探索

最近的项目中,需要连续的扫描图像进行图像识别。(之所以是用扫的方式,而不是用拍的方式,是为了后面做自动化,扫其实是自动的拍,摄像头打开,视频流过来,我要有能力知道我要用哪一帧,而不是用户去拍)。扫描的过程中,我不可能把每一帧都识别一下,这个开销太高,而且也没有必要,很多帧是重复。所以,我需要采样策略,我的采样策略是先判断手机是否在运动,后面再判断图像质量,因为图像分析有一定开销,轻量的漏斗放前面,总体的开销会小。

至于如何做运动检测,可以通过系统接口获取各种传感器的值(包括加速度计、陀螺仪、磁力计),自己来做分析;也可以直接使用系统的服务,获取系统通过各种传感器的值综合分析得到的运动状态(walk,run,静止等等)。后者听着很不错,不用自己分析传感器的值。然而,遗憾的是,对于我们的这个场景来说,系统的服务一直返回的静止,它本身就是为导航设计的,对从对准一张图片平移到对准另外一张照片这种幅度较小的运动不敏感。所以决定自己动手。

首先看看,我们有哪些传感器

  • 加速度计
  • 陀螺仪
  • 磁力计

感觉加速度计满足我的需要。开始的时候,我是这么简单判断的,加速度近似为0的时候,手机静止,否则手机在运动。这样判断的问题是会把匀速运动也识别为静止。因为加速度为0的时候,代表速度不变,可能是静止,也可能是匀速运动。问题是存在,但是我们认为问题不大,因为手持手机平移一个较小的幅度,不太可能会出现匀速。

但是我按照这个思路实现了之后,发现了一个问题,在我平移的过程中,中间阶段被识别成了静止,(而明明是移动的最快的时候),问题不大也是问题。打Log的话,结果类似于这样:

...
Have fun Still
Have fun Moving
Have fun Moving
Have fun Moving
Have fun Moving
Have fun Moving
Have fun Moving
Have fun Moving
Have fun Moving
Have fun Still
Have fun Still
Have fun Still
Have fun Still
Have fun Moving
Have fun Moving
Have fun Moving
Have fun Still
...

怎么解决呢?能不能把这个不大的问题也解决了。卡了这里很久,(应该早点把数据可视化,分析一下),我先想到的是加速度要正负平衡过,手机才会静止。从力的角度来看,要有一个作用力让它动起来,需要一个反作用力(中学物理我懂,我指的是反方向的作用力)作用于它,才能让它停下来。再想想,其实静止不静止就是看速度是不是为0,你把加速度积起来不就是速度吗,结果是0就是静止,否则就是运动中。(要有套路的做理论分析,在那扣,憋个点子是不靠谱的)。但是求加速度对时间的积分不太靠谱,因为误差太大,加速度的误差会在积分过程中被放大。放弃。而且加速度变号并达到零点有效,何必选择积分这种开销较高的方式呢。(感慨一下,自己独立解决问题越来越少了,总是在搜索现有的解决。这个问题尝试自己独立解决,发现欠缺理论分析的套路,有套路的话,先想到对加速度积分可以得到速度,然后简化实现一下,用加速度变过号再次到达零点的点作为静止点)

应用了之后,确实解决了我的问题,平移过程的中间阶段,不会识别为静止了。Log 类似于这样:

...
Have fun Still
Have fun Moving
Have fun Moving
Have fun Moving
Have fun Moving
Have fun Moving
Have fun Moving
Have fun Moving
Have fun Moving
Have fun Moving
Have fun Moving
Have fun Still
...

解决完,又觉得加速度变号之后到达零点就一定静止,没有什么说服力。虽然测试的结果是比单纯用加速度是否接近零点来判断来说是好的。所以,我找了可以证明在我的这个识别场景下这么做是可以识别运动静止的数据,就是我平移手机的时候加速度的变化曲线。(我顺序有点颠倒了,应该上来就把加速度数据可视化一些,分析分析的。用 Python 进行的可视化,很方便。)

这里写图片描述

我是来回的平移。看变化最大的分量的波形图,分解到每个平移周期,是差不多中心对称的,正负加速之后再回到零点的时候,基本是静止的了,不太可能是匀速运动,没有用户会这么做——给手机一个作用力让它动起来,然后一个反方向的作用力让它减速,然后不减到零,而是减到一定的速度让它匀速运动下去。

附识别流程及识别代码(代码写到粗陋了,回头来更新)

这里写图片描述

        if (!self.motionManager) {
            CMMotionManager *motionManager = [[CMMotionManager alloc] init];
            if (motionManager.isDeviceMotionAvailable) {
                [motionManager startDeviceMotionUpdates];
            }
            self.motionManager = motionManager;
        }

        CMAcceleration userAcceleration    = self.motionManager.deviceMotion.userAcceleration;       
        double userAccel = MAX(MAX(fabs(userAcceleration.x), fabs(userAcceleration.y)), fabs(userAcceleration.z));

        bool isMoving = userAccel > self.accelDeltaThreshold;


        if (isMoving) {
            self.moveBeg = true;

            if (userAccel == fabs(userAcceleration.x)) {
                if (userAcceleration.x > 0) {
                    self.xPositive = true;
                } else {
                    self.xNegative = true;
                }
            } else if (userAccel == fabs(userAcceleration.y)) {
                if (userAcceleration.y > 0) {
                    self.yPositive = true;
                } else {
                    self.yNegative = true;
                }
            } else if (userAccel == fabs(userAcceleration.z)) {
                if (userAcceleration.z > 0) {
                    self.zPositive = true;
                } else {
                    self.zNegative = true;
                }
            }

            return;
        } else {

            if (self.moveBeg) {
                bool changeSymbol = false;
                if (self.xPositive || self.xNegative) {
                    if (self.xPositive && self.xNegative) {
                        changeSymbol = true;
                    }
                } else if (self.yPositive || self.yNegative) {
                    if (self.yPositive && self.yNegative) {
                        changeSymbol = true;
                    }
                } else if (self.zPositive || self.zNegative) {
                    if (self.zPositive && self.zNegative) {
                        changeSymbol = true;
                    }
                }
                if (!changeSymbol) {
                    return;
                }
            }

            self.moveBeg = false;
        }

猜你喜欢

转载自blog.csdn.net/fly1183989782/article/details/80315759