美文网首页
OpenCV对图片指定颜色区域识别

OpenCV对图片指定颜色区域识别

作者: hylccmh | 来源:发表于2020-11-20 12:14 被阅读0次
    一、说明

    根据项目需求,最近在做一些技术研究相关的工作,主要是:实时获取游戏比赛视频中每个角色的 血量大小,以及对应角色的名字,以便于对游戏中角色情况进行实时检测,从而实时预测游戏战况。
    由于比赛的源数据,在游戏开发商手中,比如:和平精英游戏由某讯开发,要想拿到他们的数据是相当困难的。
    而我们能做的,就是截取比赛视频上的图片,从而对截取的图片进行检测

    二、 既然是研究性工作,当然我们也是想了几种实现方案的

    方案一:我们通过YOLO训练识别建立模型库,找到我们要使用的数据,并对它进行识别,如下图:
    YOLO(You Only Look Once)是一种基于深度神经网络的对象识别和定位算法,其最大的特点是运行速度很快,可以用于实时系统


    AL AG 5 7t.png

    对于图片上的信息,我们可以通过OCR 来识别名字,但是对于白色的识别,我们遇到麻烦了,看到这里的小伙伴说,可以通过二值化处理啊,把白色的区域给检测出来,但是请看下图:

    401 4AM • 33Sva 42m 4AM - BEGI.png

    对于图片上这种情况,二值化方案不是一个好的方式,在游戏比赛过程中,这种重叠的情况并不少见,而且有时候,名字都无法识别出来,所以这种方案是不利于我们 实时检测数据的,那么我们来看看方案二

    方案二:请先看下图:

    RIS 60 BA E 15.png

    经常玩游戏或者喜欢打终端游戏的小伙伴,对这个界面一定不陌生,这个视图是固定在左上角的,我们可以实时获取这个视图,并对它的名字和血量进行识别,由于随着血量的消耗,选手血量的颜色会有所不同,我们需要提前获取要检测目标区域的颜色,然后在计算出目标区域的大小。

    获取图片的颜色:

    #获取检测目标的BGR值
    def getTargetColor(img):
        imgShape = img.shape
        # 获取像素坐标(5,H/2)的BGR值
        imgHeightHalf = int(imgShape[0]/2)
        BGR = np.array([img[imgHeightHalf][5][0], img[imgHeightHalf][5][1], img[imgHeightHalf][5][2]])
        print(BGR)
        return BGR
    
    

    但是,由于血量在变成粉红色或者灰色的时候,不是一个纯色(半透明色),会和后面的颜色进行融合,会导致,我们在做指定区域颜色识别的时候存在一定误差,为了,可以让我们识别的区域更准确,我们可以指定一个颜色的范围 ,由于检测返回的是区域边缘的坐标,我们可以找出X 方向最大的值和X 方向最小的值,从而确定目标区域的长度,也就是血量的大小,由于我们截图的时候知道总的血量的大小,从而知道某个选手,剩余血量的百分比,以及当前的状态

    C001.png

    以下是核心代码:

    #获取血液剩余的百分比
    def getPercentageOfBloodVolume(BGR,img):
        B = int(BGR[0])
        G = int(BGR[1])
        R = int(BGR[2])
    
        # 寻找合适的上浮范围  不得使 RGB 值高于 255
        upRange = 20
        if 255 - B < upRange:
            upRange = 255 - B
        if 255 - G < upRange:
            upRange = 255 - G
        if 255 - R < upRange:
            upRange = 255 - R
    
        #寻找合适的下浮范围值 不得使 RGB 值低于 0
        lowRange = 40
        if B - lowRange < 0:
            lowRange = B
        if G - lowRange < 0:
            lowRange = G
        if R - lowRange < 0:
            lowRange = R
    
        # print('upRange == ',upRange)
        # print('lowRange ==',lowRange)
        upper = BGR + upRange
        lower = BGR - lowRange
    
        # 确定要检测的颜色范围
        mask = cv.inRange(img, lower, upper)
        (contours, hierarchy) = cv.findContours(mask.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
        print('number of countours: %d' % (len(contours)))
    
        #================================= 测试检测范围的代码 =============================
    
        # 找到绘画轮廓 水平方向最大值
        originXMax = 0
        for pointArray in contours:
            for x in pointArray:
                for y in x:
                    for originX in y:
                        if originXMax < originX:
                            originXMax = originX
    
        print('originXMax == ', originXMax)
    
        # 根据图片的大小判断,目前血量所占的 百分比
        imgShape = img.shape
        imgWidth = imgShape[1]
        bloodPer = originXMax / (imgWidth - 2)
        bloodPer = format(bloodPer, '.2f')
        return bloodPer
    
    

    这里需要注意的是:在取值颜色范围的时候,BGR 范围取值要控制在 0 ~ 255 ,否则结果会出问题

    三、总结

    由于是研究性工作,这其中也遇到了很多问题和困难,不过都一一解决了,这其中也包含,怎么对文字的准确识别,以及如何矫正错误名字识别,这里暂时不过多言表,写这篇文章,一是做下记录,二是给有相似需求的小伙伴做个参考

    相关文章

      网友评论

          本文标题:OpenCV对图片指定颜色区域识别

          本文链接:https://www.haomeiwen.com/subject/sojdiktx.html