123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- # -*- coding:utf-8 -*-
- from ssat_sdk.picture.RGB import RGBColor
- from ssat_sdk.picture.color_space import CIEluvCaculator
- from ssat_sdk.picture.feature_detect import FeatureDetect
- from ssat_sdk.picture.image_util import *
- import os
- import sys
- import time
- import numpy as np
- import cv2 as cv
- import json
- from BaseLog import CBaseLog
- from ExtraData import CExtraData
- from OptionConfig import COptionConfig
- from OptionExcel import COptionExcel
- class COptionFocus(CBaseLog):
- __rgbColor = RGBColor()
- __CIE = CIEluvCaculator()
- __fd = FeatureDetect()
- def __init__(self, optionConfig):
- CBaseLog.__init__(self)
- # CConfigManager对象;
- self.__optionConfig = optionConfig
- if self.__optionConfig is None:
- self.error("configManger对象空")
- # 当前电视机分辨率(通过截图查看图片大小);
- self.__tvResolution = None
- # icon原始分辨率;
- self.__iconResolution = self.__optionConfig.getICONResolutionConfig()
- '''
- dir.png的用法:
- 每个dir图片,必定会有一个icon图片。而icon实际上是dir的二次截图,从里抠出来的一块颜色图片。
- dir的作用是用来找文本框的,因为有些文字是在icon颜色域外面。
- '''
- # 已读取过的dir图片对象的icon图片大小记录;
- # 数据格式及说明:
- # {
- # "dir1路径": {"icon_box": ["dir1对应icon,在dir1内的区域坐标"], "width": "dir1图片宽", "height": "dir1图片高"}
- # "dir2路径": {"icon_box": ["dir2对应icon,在dir2内的区域坐标"], "width": "dir2图片宽", "height": "dir2图片高"}
- # }
- self.__dirIconRectDict = {}
- '''
- 函数:通过源图,获取当前电视机的分辨率大小;
- 参数:
- 返回:
- '''
- def __getTvResolution(self, src_pic):
- # 只获取一次;
- if self.__tvResolution is None or self.__tvResolution.__len__() == 0:
- src_img = cv.imread(src_pic)
- if src_img is not None:
- self.__tvResolution = [src_img.shape[1], src_img.shape[0]]
- self.info(u"获取图片【%s】分辨率成功,使用图片分辨率%s做为当前电视分辨率" % (src_pic, self.__tvResolution))
- else:
- self.__tvResolution = [1920, 1080]
- self.error(u"获取图片【%s】分辨率失败,将使用默认分辨率%s做为当前电视分辨率" % (src_pic, self.__tvResolution))
- '''
- 函数:根据option的配置内容,在指定源图上查找焦点框;
- 参数:
- src_pic: 源图路径;
- opc_cfg: Option的配置数据;
- 返回:Boolean, [焦点框坐标]
- '''
- def __focusByColor(self, src_pic, opc_cfg):
- # 将字典参数析出;
- icon_cfg = opc_cfg['dcfg']
- icon_path = opc_cfg['icon_path']
- icon_dir_path = opc_cfg['dir_path']
- morphology = icon_cfg['morphology'] if 'morphology' in icon_cfg else []
- # 读取图片;
- icon_img = cv.imread(icon_path)
- if icon_img is None:
- self.error("读取%s图片失败" % icon_path)
- return False, None
- # 获取icon平均bgr值;
- icon_bgr = COptionFocus.__rgbColor.getAvgBGR(icon_img)
- # 返回查找结果,失败返回 False, None; 成功返回(焦点的坐标点) True, [l,t,r,b]
- return COptionFocus.__fd.findCurrentFoucsByColor(src_pic, [], icon_bgr, icon_cfg['offset'],
- icon_cfg['minPeri'], icon_cfg['maxPeri'],
- icon_cfg['minArea'], icon_cfg['maxArea'], morphology)
- '''
- 函数:根据Option的icon配置来查找聚集框;
- 参数:
- src_pic: 源图;
- cur_option: Option名称;
- isValueSheet:
- false表示查找当前Option的paths配置内容(icon和offset之类),
- True表示查找当前Option的value配置内容。
- 即,当前Option是在Excel表的哪个sheet中。
- 返回:Boolean, [焦点框坐标]
- '''
- def findFocusByIcon(self, src_pic, curOptionName, isValueSheet=False):
- result, opc_cfg = False, {}
- if isValueSheet:
- result, opc_cfg = self.__optionConfig.getValueICONConfig(curOptionName)
- else:
- result, opc_cfg = self.__optionConfig.getOptionICONConfig(curOptionName)
- # 根据源图获取当前电视分辨率;
- self.__getTvResolution(src_pic)
- icon_cfg = opc_cfg['dcfg']
- # 计算出icon源分辨率与当前电视分辨率比例;
- resolutionRate = self.__iconResolution[0] / self.__tvResolution[0]
- if int(resolutionRate) != 1:
- icon_cfg['minPeri'] = resolutionRate * icon_cfg['minPeri']
- icon_cfg['maxPeri'] = resolutionRate * icon_cfg['maxPeri']
- icon_cfg['minArea'] = pow(resolutionRate, 2) * icon_cfg['minArea']
- icon_cfg['maxArea'] = pow(resolutionRate, 2) * icon_cfg['maxArea']
- return self.__focusByColor(src_pic, opc_cfg)
- '''
- 函数:获取焦点框所在区域的文本框坐标;
- 参数:
- curOptionName: 当前Option名称;
- curFocusBox: 当前Option的聚集框区域坐标(由findFocusByIcon所得)
- isValueSheet: 是否是value表.
- 返回: 数组[]。文本框坐标
- '''
- def getFocusTextBox(self, curOptionName, curFocusBox, isValueSheet=False):
- # 参数校验;
- if curFocusBox is None or curFocusBox.__len__() == 0:
- self.error(u"当前聚焦框None或空")
- return None
- # 获取配置信息;
- result, opc_cfg = False, {}
- if isValueSheet:
- result, opc_cfg = self.__optionConfig.getValueICONConfig(curOptionName)
- else:
- result, opc_cfg = self.__optionConfig.getOptionICONConfig(curOptionName)
- if result is False:
- self.warn(u"获取【%s】的icon配置失败,将使用聚集框作为文本框坐标" % curOptionName)
- return curFocusBox
- dir_path = opc_cfg['dir_path']
- # 判断方位图是否存在,不存在使用默认聚集框作为文本框;
- if os.path.exists(dir_path) is False:
- self.warn(u"dir图片%s不存在,将使用聚集框作为文本框坐标" % dir_path)
- return curFocusBox
- # 判断该dir是否已读取过(减少文件读写),读取过直接使用记录;
- if dir_path in self.__dirIconRectDict:
- # 析出dir的宽高;
- dirWidth = self.__dirIconRectDict[dir_path]['width']
- dirHeight = self.__dirIconRectDict[dir_path]['height']
- # 析出dir对应的icon,在dir内的坐标区域;
- refIconBox = self.__dirIconRectDict[dir_path]['icon_box']
- # 计算出dir在原图中实际坐标,即文本区域坐标;
- x = curFocusBox[0] - refIconBox[0]
- y = curFocusBox[1] - refIconBox[1]
- # 返回结果,即文本区域;
- return [x, y, x + dirWidth, y + dirHeight]
- # 没有记录,否读取图片并记录;
- dir_img = cv.imread(dir_path)
- if dir_img is None:
- self.error(u"读取【%s】失败,将使用聚集框作为文本框坐标" % dir_path)
- return curFocusBox
- result, focusBox = self.findFocusByIcon(dir_path, curOptionName, isValueSheet)
- if result is False:
- self.error(u"在dir图片【%s】查找聚集框失败,将使用聚集框作为文本框坐标" % dir_path)
- return curFocusBox
- # 记录dir对应的icon等信息, 以备下次使用;
- self.__dirIconRectDict[dir_path] = {"icon_box": focusBox, "width": dir_img.shape[1], "height": dir_img.shape[0]}
- # 计算起始坐标点;
- x, y = curFocusBox[0] - focusBox[0], curFocusBox[1] - focusBox[1]
- # 返回文本框;
- return [x, y, x + dir_img.shape[1], y + dir_img.shape[0]]
- # end-class
- if __name__ == "__main__":
- exData = CExtraData()
- optionExcel = COptionExcel(exData)
- opcfg = COptionConfig(exData, optionExcel)
- opfocus = COptionFocus(opcfg)
- res, Box = opfocus.findFocusByIcon(src_pic="", curOptionName="picture")
- opfocus.getFocusTextBox("picture", Box)
|