美文网首页
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