def _add_images_doc(self, path: str, import_path: str, url_prefix: str): """ 为文件夹下的图片添加信息字典文件(id为不含扩展的文件名) @param {str} path - 要处理的文件目录 """ _import_path = os.path.realpath(import_path) # 处理当前文件夹 _file_list = FileTool.get_filelist(path, regex_str=r'^((?!\.json$).)*$', is_fullname=True) for _file in _file_list: _ext = FileTool.get_file_ext(_file) _json_file = _file[0:-len(_ext)] + 'json' if os.path.exists(_json_file): # 字典文件已存在,无需处理 continue # 生成并写入字典 _file_name = FileTool.get_file_name_no_ext(_file) _url = os.path.realpath(_file)[len(_import_path):].replace( '\\', '/').lstrip('/') _url = '%s/%s' % (url_prefix, _url) _image_doc = {'id': _file_name, 'url': _url, 'path': _file} _json_str = json.dumps(_image_doc, ensure_ascii=False) with open(_json_file, 'wb') as _fid: _fid.write(_json_str.encode(encoding='utf-8')) # 处理子文件夹 _sub_dir_list = FileTool.get_dirlist(path) for _sub_dir in _sub_dir_list: self._add_images_doc(_sub_dir, import_path, url_prefix)
def load_trans_from_dir(self, trans_file_path, trans_file_prefix, encoding='utf-8', append=True): """ 从指定路径加载语言信息文件到对象中 @param {string} trans_file_path - 语言信息文件所在路径,如果为None则代表不处理信息文件 @param {string} trans_file_prefix - 语言信息文件前缀, 例如前缀为test,信息文件名为test_en.json、test_zh.json等 @param {string} encoding='utf-8' - 解析文件的编码 @param {bool} append=True - 是否追加模式,如果是则以增量方式更新,否则覆盖原来的配置 """ file_list = FileTool.get_filelist(path=trans_file_path, regex_str=r'^' + trans_file_prefix + r'_\S+\.json$', is_fullname=True) for file in file_list: # 循环加载语言信息文件 file_name = os.path.split(os.path.realpath(file))[1] file_lang = re.sub( r'\.json$', '', re.sub(r'^' + trans_file_prefix + r'_', '', file_name)) self.load_trans_from_file(file_full_path=file, lang=file_lang, encoding=encoding, append=append)
def rename_file_to_num(cls, path: str, start_index: int = 1) -> int: """ 重命名文件为数字序号 @param {str} path - 要处理的文件夹 @param {int} start_index=1 - 开始序号 @returns {int} - 返回当前序号 """ # 处理当前目录 _start_index = start_index _path = os.path.realpath(path) _file_list = FileTool.get_filelist(_path, is_fullname=False) for _file in _file_list: _ext = FileTool.get_file_ext(_file) os.rename( os.path.join(_path, _file), os.path.join( _path, StringTool.fill_fix_string(str(_start_index), 10, '0') + '.' + _ext)) _start_index += 1 # 处理子目录 _sub_dir_list = FileTool.get_dirlist(_path) for _sub_dir in _sub_dir_list: _start_index = cls.rename_file_to_num(_sub_dir, start_index=_start_index) # 返回当前序号值 return _start_index
def test_JadeTypeDetect(): """ 测试翡翠类型处理器 """ _execute_path = RunTool.get_global_var('EXECUTE_PATH') _pipeline = RunTool.get_global_var('EMPTY_PIPELINE') _processer_class: PipelineProcesser = Pipeline.get_plugin('processer', 'JadeTypeDetect') _filelist = FileTool.get_filelist( os.path.join(_execute_path, os.path.pardir, 'test_data/test_pic/'), is_fullname=True ) for _file in _filelist: # 遍历执行 with open(_file, 'rb') as _fid: _file_bytes = _fid.read() _input = { 'type': '', 'sub_type': '', 'image': Image.open(_file_bytes), 'score': 0.0 } _output = _processer_class.execute(_input, {}, _pipeline) # 输出图片和对应文字 _image = _output['image'] _print_str = 'type: %s\nsub_type: %s\nscore: %s' % ( _output['type'], _output['sub_type'], str(_output['score'])) _draw = ImageDraw.Draw(_image) # PIL图片上打印汉字 # 参数1:字体文件路径,参数2:字体大小;Windows系统“simhei.ttf”默认存储在路径:C:\Windows\Fonts中 _font = ImageFont.truetype("simhei.ttf", 20, encoding="utf-8") _draw.text((0, 0), _print_str, (255, 0, 0), font=_font) plt.figure(_file) plt.imshow(_image) plt.show()
def load_predef_by_path(self, path: str, encoding: str = 'utf-8'): """ 通过文件路径装载预定义模板 @param {str} path - 要装载模板的路径 @param {str} encoding='utf-8' - 文件编码 """ _file_list = FileTool.get_filelist(path, is_fullname=True) for _file in _file_list: self.load_predef_by_file(_file, encoding=encoding)
def labelimg_rename_filename(cls, path: str, fix_len: int = 10): """ 重名名labelimg对应目录下的文件名(图片文件和标注文件同步修改) @param {str} path - 要修改文件名的路径 @param {int} fix_len=10 - 文件名长度 """ _path = os.path.realpath(path) _files = FileTool.get_filelist(path=_path, is_fullname=False) _index = 1 for _file in _files: _file_ext = FileTool.get_file_ext(_file) if _file_ext == 'xml': # 标签文件不处理 continue _file_no_ext = FileTool.get_file_name_no_ext(_file) # 获取最新的文件名 while True: _new_name = StringTool.fill_fix_string(str(_index), fix_len, '0', left=True) _new_file = _new_name + '.' + _file_ext _index += 1 if os.path.exists(os.path.join(path, _new_file)): # 文件名已存在 _index += 1 continue # 文件名不存在,跳出循环 break # 修改文件名 os.rename(os.path.join(_path, _file), os.path.join(_path, _new_file)) if os.path.exists(os.path.join(_path, _file_no_ext + '.xml')): # 需要修改标签文件 _xml_file = _new_name + '.xml' os.rename(os.path.join(_path, _file_no_ext + '.xml'), os.path.join(_path, _xml_file)) # 修改标签文件内容 _tree = ET.parse(os.path.join(_path, _xml_file)) _root = _tree.getroot() _root.find('filename').text = _new_file _root.find('path').text = os.path.join(_path, _new_file) _tree.write(os.path.join(_path, _xml_file), encoding='utf-8', method="xml", xml_declaration=None)
def load_plugins_by_path(cls, path: str): """ 装载指定目录下的管道插件(处理器和路由器) @param {str} path - 要装载的目录 """ _file_list = FileTool.get_filelist(path=path, regex_str=r'.*\.py$', is_fullname=True) for _file in _file_list: if _file == '__init__.py': continue cls.load_plugins_by_file(_file)
def _get_dom_files(cls, path: str, files: list): """ 获取指定目录下的所有dom.html文件 @param {str} path - 路径 @param {list} files - 找到的文件清单 """ # 先找当前目录下的文件 _temp_list = FileTool.get_filelist(path, regex_str=r'^dom\.html$', is_fullname=True) files.extend(_temp_list) # 遍历所有子目录获取文件 _dirs = FileTool.get_dirlist(path) for _dir in _dirs: cls._get_dom_files(_dir, files)
def load_plugins(self, path: str): """ 装载job运行插件 @param {str} path - 插件所在目录 """ _file_list = FileTool.get_filelist(path=path, regex_str=r'.*\.py$', is_fullname=False) for _file in _file_list: if _file == '__init__.py': continue # 执行加载 _module = ImportTool.import_module(_file[0:-3], extend_path=path, is_force=True) _clsmembers = inspect.getmembers(_module, inspect.isclass) for (_class_name, _class) in _clsmembers: if _module.__name__ != _class.__module__: # 不是当前模块定义的函数 continue # 判断类型 _type_fun = getattr(_class, 'plugin_type', None) if _type_fun is None or not callable(_type_fun): # 不是标准的插件类 continue _plugin_type = _type_fun() self.plugins.setdefault(_plugin_type, dict()) self.plugins[_plugin_type][_class_name] = dict() self._log_debug( 'add [%s] plugin file[%s] class[%s]:' % (_plugin_type, _file, _class_name), ) for _name, _value in inspect.getmembers(_class): if not _name.startswith('_') and callable( _value) and _name not in ['plugin_type']: if _name == 'initialize': # 装载时执行一次初始化 _value(self, self.qa_manager, self.qa) else: self.plugins[_plugin_type][_class_name][ _name] = _value self._log_debug(' add fun[%s]' % _name)
def test_search_image(self, path: str, pipeline: str): """ 测试匹配图片 @param {str} path - 要测试图片所在目录 @param {str} pipeline - 管道标识 """ _file_list = FileTool.get_filelist(path) for _file in _file_list: with open(_file, 'rb') as _fid: _matchs = self.search_engine.search(_fid.read(), pipeline) # 打印信息 print('Search File: %s' % _file) # 计算结果有多少行 _line_count = math.ceil(len(_matchs) / 3) + 1 # 展示出来 _image = Image.open(_file) plt.subplot(_line_count, 3, 2) plt.imshow(_image) plt.title('source pic') plt.xticks([]) plt.yticks([]) _index = 1 for _image_doc in _matchs: print('Match: %s' % str(_image_doc)) _image_file = _image_doc['path'] _image = Image.open(_image_file) plt.subplot(_line_count, 3, _index + 3) plt.imshow(_image) plt.title( 'match %d: %.2f, %.3f' % (_index, _image_doc['distance'], _image_doc['score'])) plt.xticks([]) plt.yticks([]) _index += 1 plt.show()
def load_action_module_by_dir(cls, module_path: str, robot_id: str = None): """ 加载指定目录的动作模块文件 @param {str} module_path - 要加载的动作模块文件目录 @param {str} robot_id=None - 机器人id,如果有传值代表导入对应机器人实例自有路由中 """ # 检查环境是否已加载 cls._check_inited_raise() # 遍历文件执行加载 _file_list = FileTool.get_filelist( path=module_path, regex_str=r'.*\.py$', is_fullname=False ) for _file in _file_list: if _file == '__init__.py': continue # 逐笔进行加载处理 cls.load_action_module(os.path.join(module_path, _file), robot_id=robot_id)
def import_images(self, path: str, pipeline: str, encoding: str = 'utf-8'): """ 将指定路径的图片导入搜索库 @param {str} path - 图片及信息字典所在路径,包含文件: 图片文件,例如"abc.jpg" 对应的json信息字典文件,例如"abc.json",文件内容按标准json字符串格式编写 注:json中可以通过添加collection域指定该图片的所属分类集合名 @param {str} pipeline - 处理管道标识 @param {str} encoding='utf-8' - json文件的编码 """ _pipeline_obj = self._get_pipeline(pipeline) _file_list = FileTool.get_filelist(path, regex_str=r'^((?!\.json$).)*$', is_fullname=True) for _file in _file_list: try: # 获取图片的信息字典 _ext = FileTool.get_file_ext(_file) _json_file = _file[0:-len(_ext)] + 'json' if not os.path.exists(_json_file): self.log_debug( 'Json file not exists, not imported: [%s]!' % _file) continue with open(_json_file, 'r', encoding=encoding) as _fid: _image_doc = json.loads(_fid.read()) # 导入图片 _collection = _image_doc.get('collection', '') with open(_file, 'rb') as _fid: self._image_to_search_db(_fid.read(), _image_doc, _pipeline_obj, init_collection=_collection) # 输出日志 self.log_debug('image [%s] imported success' % _file) except: self.log_debug('image [%s] import error: %s' % (_file, traceback.format_exc()))
def test_jade_pipeline(): """ 测试管道 """ _execute_path = RunTool.get_global_var('EXECUTE_PATH') _pipeline: Pipeline = RunTool.get_global_var('JADE_PIPELINE') _filelist = FileTool.get_filelist( os.path.join(_execute_path, os.path.pardir, 'test_data/test_pic/'), is_fullname=True ) for _file in _filelist: # 遍历执行 with open(_file, 'rb') as _fid: _file_bytes = _fid.read() _input = { 'image': _file_bytes } _status, _output = _pipeline.start( _input, {} ) print('Pipeline run status: %s' % _status) if _status == 'success': # 执行成功 print('Image Vertor: %s' % str(_output['vertor'])) # 输出图片和对应文字 _image = Image.open(BytesIO(_output['image'])) _print_str = 'type: %s\nsub_type: %s\nscore: %s' % ( _output['type'], _output['sub_type'], str(_output['score'])) _draw = ImageDraw.Draw(_image) # PIL图片上打印汉字 # 参数1:字体文件路径,参数2:字体大小;Windows系统“simhei.ttf”默认存储在路径:C:\Windows\Fonts中 _font = ImageFont.truetype("simhei.ttf", 20, encoding="utf-8") _draw.text((0, 0), _print_str, (255, 0, 0), font=_font) plt.figure(_file) plt.imshow(_image) plt.show()
def _get_pic_file_list(cls, input_path: str) -> list: """ 获取制定目录下的所有图片文件清单 @param {str} input_path - 要处理的目录 @returns {list} - 文件清单列表 """ _list = [] # 先获取当前目录下的所有xml文件 for _file in FileTool.get_filelist(input_path, is_fullname=True): _ext = FileTool.get_file_ext(_file) if _ext.lower() in ('jpg', 'jpeg'): _list.append(_file) # 获取子目录 for _dir in FileTool.get_dirlist(input_path): _temp_list = cls._get_pic_file_list(_dir) _list.extend(_temp_list) return _list
def _get_labelimg_annotation_file_list(cls, input_path: str) -> list: """ 获取要处理的LabelImg标注文件清单 @param {str} input_path - 起始目录 @returns {list} - 返回文件清单 """ _list = [] # 先获取当前目录下的所有xml文件 for _file in FileTool.get_filelist(input_path, regex_str=r'.*\.xml$'): _pic_file = _file[0:-3] + 'jpg' if os.path.exists(_pic_file): _list.append(_file) # 获取子目录 for _dir in FileTool.get_dirlist(input_path): _temp_list = cls._get_labelimg_annotation_file_list(_dir) _list.extend(_temp_list) return _list
def test_images_show(cls, path: str): """ 测试图片显示 @param {str} path - 图片目录 """ _file_list = FileTool.get_filelist(path) _image = Image.open(_file_list[0]) plt.subplot(2, 2, 3) plt.imshow(_image) plt.title('source pic 1-1') plt.xticks([]) plt.yticks([]) plt.subplot(4, 3, 7) plt.imshow(_image) plt.title('source pic 2-1') plt.xticks([]) plt.yticks([]) plt.subplot(4, 3, 8) plt.imshow(_image) plt.title('source pic 2-2') plt.xticks([]) plt.yticks([]) plt.subplot(4, 3, 9) plt.imshow(_image) plt.title('source pic 2-3') plt.xticks([]) plt.yticks([]) plt.subplot(4, 3, 10) plt.imshow(_image) plt.title('source pic 3-1') plt.xticks([]) plt.yticks([]) plt.show()
def labelimg_del_not_rgb_pic(cls, path: str): """ 删除位深不为RGB三通道的图片 (解决image_size must contain 3 elements[4]报错) @param {str} path - 要处理的路径 """ _path = os.path.realpath(path) # 遍历所有子目录 _sub_dirs = FileTool.get_dirlist(path=_path, is_fullpath=True) for _dir in _sub_dirs: # 递归删除子目录的信息 cls.labelimg_del_not_rgb_pic(_dir) # 检查自己目录下的图片 _files = FileTool.get_filelist(path=_path, is_fullname=False) for _file in _files: _file_ext = FileTool.get_file_ext(_file) if _file_ext == 'xml': # 标签文件不处理 continue # 打开图片判断位深 _fp = open(os.path.join(_path, _file), 'rb') _img = Image.open(_fp) if _img.mode != 'RGB': # 需要删除掉 _fp.close() _img_file = os.path.join(_path, _file) _xml_file = os.path.join( _path, FileTool.get_file_name_no_ext(_file) + '.xml') print('delete %s' % _img_file) FileTool.remove_file(_img_file) if os.path.exists(_xml_file): FileTool.remove_file(_xml_file) else: _fp.close()
def test_HistogramVetor(): """ 测试直方图特征变量生成 """ _execute_path = RunTool.get_global_var('EXECUTE_PATH') _pipeline = RunTool.get_global_var('EMPTY_PIPELINE') _processer_class: PipelineProcesser = Pipeline.get_plugin('processer', 'HistogramVetor') _filelist = FileTool.get_filelist( os.path.join(_execute_path, os.path.pardir, 'test_data/test_pic/'), is_fullname=True ) for _file in _filelist: # 遍历执行 with open(_file, 'rb') as _fid: _file_bytes = _fid.read() _input = { 'type': '', 'sub_type': '', 'image': Image.open(_file_bytes), 'score': 0.0 } _output = _processer_class.execute(_input, {}, _pipeline) print(_output['vertor'])
def _clean_file_path(cls, path: str, class_path: str): """ 清理当前目录文件 @param {str} path - 要处理的目录地址 @param {str} class_path - 类目录 """ # 处理自身目录,先获取商品信息 _info = dict() _info_file = os.path.join(path, 'info.json') if os.path.exists(_info_file): with open(_info_file, 'rb') as f: _eval = str(f.read(), encoding='utf-8') _info = eval(_eval) # 判断是否不处理 _shop_name = _info['店名'] # if _info['款式'] == '挂件' and _info['挂件类型'] == '': # return # 遍历文件进行处理 _product_num = FileTool.get_dir_name(path) _files = FileTool.get_filelist(path) _order = 1 for _file in _files: _file_ext = FileTool.get_file_ext(_file).lower() if _file_ext not in ['jpg', 'jpeg', 'png', 'bmp']: # 不是合适的文件类型 continue # 判断是否有括号 if _file.find('(') >= 0: FileTool.remove_file(_file) continue # 判断是否匹配上要删除的图片大小 if _shop_name in DEL_SHOP_PIC_SIZE.keys() and os.path.getsize( _file) in DEL_SHOP_PIC_SIZE[_shop_name]: FileTool.remove_file(_file) continue # 修改文件名 if not FileTool.get_file_name(_file).startswith(_product_num): os.rename( _file, os.path.join( path, '%s_%s_%d.%s' % (_product_num, 'main' if _file.find('主图') >= 0 or _file.find('main') >= 0 else 'detail', _order, _file_ext))) # 下一个文件 _order += 1 # 移动文件夹到指定的分类目录 _class_path = _info['款式'] if _class_path in PROP_TYPE_TRAN_DICT.keys(): _class_path = PROP_TYPE_TRAN_DICT[_info['款式']] shutil.move(path, os.path.join(class_path, _class_path, _product_num)) # 处理完成,返回 return
def test_jade_pipeline_pic_compare(): """ 测试通道结果比较 """ _execute_path = RunTool.get_global_var('EXECUTE_PATH') _pipeline: Pipeline = RunTool.get_global_var('JADE_PIPELINE') _filelist = FileTool.get_filelist( os.path.join(_execute_path, os.path.pardir, 'test_data/pic_compare/'), is_fullname=True ) _row = len(_filelist) # 行数 _col = 3 # 图片列数 _index = 1 # 当前图片序号 _y_max = 0.5 # y坐标最大值 _vertor_list = [] # 向量清单 for _file in _filelist: # 遍历执行 with open(_file, 'rb') as _fid: _file_bytes = _fid.read() _input = { 'image': _file_bytes } _status, _output = _pipeline.start( _input, {} ) print('Pipeline run status: %s' % _status) if _status == 'success': # 执行成功, 显示相关图片 _src_img = Image.open(_file) plt.subplot(_row, _col, _index) plt.imshow(_src_img) plt.title('source pic') plt.xticks([]) plt.yticks([]) _index += 1 # 处理后的图 _image = Image.open(BytesIO(_output['image'])) plt.subplot(_row, _col, _index) plt.imshow(_image) plt.title(_output['collection']) plt.xticks([]) plt.yticks([]) _index += 1 # 统计图 plt.subplot(_row, _col, _index) _x = list(range(1, 6 * 4 * 3 + 1)) plt.plot(_x, _output['vertor']) plt.axis([1, 6 * 4 * 3, 0.0, _y_max]) _index += 1 # 加入向量清单 _vertor_list.append(_output['vertor']) # 计算两两之间的欧式距离(L2) _compare = list(itertools.combinations(list(range(_row)), 2)) for _item in _compare: _sum = 0 _v1 = _vertor_list[_item[0]].tolist() _v2 = _vertor_list[_item[1]].tolist() for _index in range(len(_v1)): _sum += (_v1[_index] - _v2[_index])**2 _l2 = math.sqrt(_sum) print('%d - %d : %f, %f' % ( _item[0] + 1, _item[1] + 1, # np.linalg.norm(_vertor_list[_item[0]] - _vertor_list[_item[1]]) np.sqrt(np.sum(np.square(_vertor_list[_item[0]] - _vertor_list[_item[1]]))), _l2 )) # 统一显示 plt.show()
def test_hsv_color(): """ 测试HSV的颜色聚类处理 """ _execute_path = RunTool.get_global_var('EXECUTE_PATH') _filelist = FileTool.get_filelist( os.path.join(_execute_path, os.path.pardir, 'test_data/test_pic/'), is_fullname=True ) def convert_color(RGB: tuple, split_h: int = 6, split_s: int = 2, split_v: int = 2): """ 颜色聚类转换 @param {tuple} RGB - (r,g,b)颜色数组 @param {int} split_h=6 - 指定将HSV颜色坐标的基础色转换为几个分类([0, 359]) @param {int} split_s=2 - 指定将HSV颜色坐标的饱和度转换为几个分类([0, 1]) @param {int} split_v=2 - 指定将HSV颜色坐标的亮度转换为几个分类([0, 1]) """ # 转换RBG颜色为HSV r, g, b = RGB[0] / 255.0, RGB[1] / 255.0, RGB[2] / 255.0 mx = max(r, g, b) mn = min(r, g, b) df = mx - mn if mx == mn: h = 0 elif mx == r: h = (60 * ((g - b) / df) + 360) % 360 elif mx == g: h = (60 * ((b - r) / df) + 120) % 360 elif mx == b: h = (60 * ((r - g) / df) + 240) % 360 if mx == 0: s = 0 else: s = df / mx v = mx # 根据HSV坐标将颜色归类 df = 360.0 / split_h h = round(h / df) * df if h >= 360: h = 0 if split_s <= 1: s = 1.0 else: df = 1.0 / (split_s - 1) s = round(s / df) * df if split_v <= 1: v = 1.0 else: df = 1.0 / (split_v - 1) v = round(v / df) * df # 将HSV转换为RGB h60 = h / 60.0 h60f = math.floor(h60) hi = int(h60f) % 6 f = h60 - h60f p = v * (1 - s) q = v * (1 - f * s) t = v * (1 - (1 - f) * s) r, g, b = 0, 0, 0 if hi == 0: r, g, b = v, t, p elif hi == 1: r, g, b = q, v, p elif hi == 2: r, g, b = p, v, t elif hi == 3: r, g, b = p, q, v elif hi == 4: r, g, b = t, p, v elif hi == 5: r, g, b = v, p, q r, g, b = int(r * 255), int(g * 255), int(b * 255) return (r, g, b) for _file in _filelist: _image = Image.open(_file) _image = _image.resize((299, 299)).convert("RGB") _pix = _image.load() for _x in range(299): for _y in range(299): # 遍历每个变量修改颜色 _pix[_x, _y] = convert_color(_pix[_x, _y], split_s=4, split_v=3) # 显示转换后的图片 _image_src = Image.open(_file) plt.subplot(1, 2, 1) plt.imshow(_image_src) plt.title('source pic') plt.xticks([]) plt.yticks([]) plt.subplot(1, 2, 2) plt.imshow(_image) plt.title('dest pic') plt.xticks([]) plt.yticks([]) plt.show()
def labelimg_pic_deal(cls, path: str): """ TFRecord图片兼容处理 1.删除位深不为RGB三通道的图片 (解决image_size must contain 3 elements[4]报错) 2.转换图片格式为jpg 3.检查xml文件的文件名和路径是否正确 @param {str} path - 要处理的路径 """ _path = os.path.realpath(path) # 遍历所有子目录 _sub_dirs = FileTool.get_dirlist(path=_path, is_fullpath=True) for _dir in _sub_dirs: # 递归删除子目录的信息 cls.labelimg_pic_deal(_dir) # 检查自己目录下的图片 _files = FileTool.get_filelist(path=_path, is_fullname=False) for _file in _files: _file_ext = FileTool.get_file_ext(_file) if _file_ext == 'xml': # 标签文件不处理 continue _img_file = os.path.join(_path, _file) _file_no_ext = FileTool.get_file_name_no_ext(_file) if _file_ext in ('png', 'gif'): # 转换图片格式 _fp = open(_img_file, 'rb') _img = Image.open(_fp) _rgb_im = _img.convert('RGB') _rgb_im.save(os.path.join(_path, _file_no_ext + '.jpg')) _fp.close() # 删除原文件,修改xml中的文件名 FileTool.remove_file(_img_file) _xml_file = os.path.join(_path, _file_no_ext + '.xml') if os.path.exists(_xml_file): _tree = ET.parse(os.path.join(_path, _xml_file)) _root = _tree.getroot() _root.find('filename').text = _file_no_ext + '.jpg' _root.find('path').text = os.path.join( _path, _file_no_ext + '.jpg') _tree.write(os.path.join(_path, _xml_file), encoding='utf-8', method="xml", xml_declaration=None) # 修改文件名变量 _img_file = os.path.join(_path, _file_no_ext + '.jpg') # 打开图片判断位深 _fp = open(_img_file, 'rb') _img = Image.open(_fp) if _img.mode != 'RGB': # 需要删除掉 _fp.close() _xml_file = os.path.join( _path, FileTool.get_file_name_no_ext(_file) + '.xml') print('delete %s' % _img_file) FileTool.remove_file(_img_file) if os.path.exists(_xml_file): FileTool.remove_file(_xml_file) else: _fp.close() # 检查xml文件 _xml_file = os.path.join(_path, _file_no_ext + '.xml') if os.path.exists(_xml_file): _tree = ET.parse(os.path.join(_path, _xml_file)) _root = _tree.getroot() if _root.find('filename' ).text != _file_no_ext + '.jpg' or os.path.split( _root.find('path').text)[0] != _path: _root.find('filename').text = _file_no_ext + '.jpg' _root.find('path').text = os.path.join( _path, _file_no_ext + '.jpg') _tree.write(os.path.join(_path, _xml_file), encoding='utf-8', method="xml", xml_declaration=None)
def import_config(cls, qa_manager: QAManager, logger: Logger): """ 添加标准配置(不考虑删除问题) @param {QAManager} qa_manager - 数据管理对象 @param {Logger} logger - 日志对象 """ FORM_PLUGIN_CONFIG = RunTool.get_global_var('FORM_PLUGIN_CONFIG') if FORM_PLUGIN_CONFIG is None: FORM_PLUGIN_CONFIG = dict() RunTool.set_global_var('FORM_PLUGIN_CONFIG', FORM_PLUGIN_CONFIG) FORM_PLUGIN_SELF_TABLE = RunTool.get_global_var( 'FORM_PLUGIN_SELF_TABLE') if FORM_PLUGIN_SELF_TABLE is None: FORM_PLUGIN_SELF_TABLE = dict() RunTool.set_global_var('FORM_PLUGIN_SELF_TABLE', FORM_PLUGIN_SELF_TABLE) # 插入标准问题 _std_q = StdQuestion.create(tag='form_direct_action', q_type='context', milvus_id=-1, collection=FORM_PLUGIN_COLLECTION, partition=FORM_PLUGIN_PARTITION, question='表单插件通用处理') # 插入问题答案 Answer.create(std_question_id=_std_q.id, a_type='job', type_param="['FormPlugin', 'operate', {}]", replace_pre_def='N', answer='表单插件通用处理') if logger is not None: logger.info('create form plugin std question config success!') # 处理扩展插件 if FORM_PLUGIN_SEARCH_PATH is not None: _path = os.path.join(os.path.dirname(__file__), FORM_PLUGIN_SEARCH_PATH) _file_list = FileTool.get_filelist(path=_path, regex_str=r'.*\.py$', is_fullname=False) for _file in _file_list: if _file == '__init__.py': continue # 执行加载 _module = ImportTool.import_module(_file[0:-3], extend_path=_path, is_force=True) _clsmembers = inspect.getmembers(_module, inspect.isclass) for (_class_name, _class) in _clsmembers: if _module.__name__ != _class.__module__: # 不是当前模块定义的函数 continue # 判断类型 _get_form_type = getattr(_class, 'get_form_type', None) if _get_form_type is None or not callable(_get_form_type): # 不是标准的插件类 continue _form_type = _get_form_type() _get_form_config = getattr(_class, 'get_form_config', None) # 加入配置 FORM_PLUGIN_CONFIG[_form_type] = _get_form_config() # 循环插件实例进行处理 for _form_type in FORM_PLUGIN_CONFIG.keys(): _config = FORM_PLUGIN_CONFIG[_form_type] # 创建表单类型意图参数 NlpPurposConfigDict.create( action=_form_type, match_collection='', match_partition='', collection=FORM_PLUGIN_COLLECTION, partition=FORM_PLUGIN_PARTITION, std_question_id=_std_q.id, order_num=_config['order_num'], exact_match_words=str(_config['exact_match_words']), exact_ignorecase=_config['exact_ignorecase'], match_words=str(_config['match_words']), ignorecase=_config['ignorecase'], word_scale=_config['word_scale'], info=str(_config['info']), check=str(_config['check'])) if logger is not None: logger.info('create form plugin [%s] success!' % _form_type)
def initialize(cls, loader, qa_manager, qa, **kwargs): """ 装载插件前执行的初始化处理 可以不定义 @param {QAServerLoader} loader - 服务装载器 @param {QAManager} qa_manager - 数据管理 @param {QA} qa - 问答服务 """ FORM_PLUGIN_CONFIG = RunTool.get_global_var('FORM_PLUGIN_CONFIG') if FORM_PLUGIN_CONFIG is None: FORM_PLUGIN_CONFIG = dict() RunTool.set_global_var('FORM_PLUGIN_CONFIG', FORM_PLUGIN_CONFIG) FORM_PLUGIN_SELF_TABLE = RunTool.get_global_var( 'FORM_PLUGIN_SELF_TABLE') if FORM_PLUGIN_SELF_TABLE is None: FORM_PLUGIN_SELF_TABLE = dict() RunTool.set_global_var('FORM_PLUGIN_SELF_TABLE', FORM_PLUGIN_SELF_TABLE) # 获取表单实例库 if FORM_PLUGIN_SEARCH_PATH is not None: _path = os.path.join(os.path.dirname(__file__), FORM_PLUGIN_SEARCH_PATH) _file_list = FileTool.get_filelist(path=_path, regex_str=r'.*\.py$', is_fullname=False) for _file in _file_list: if _file == '__init__.py': continue # 执行加载 _module = ImportTool.import_module(_file[0:-3], extend_path=_path, is_force=True) _clsmembers = inspect.getmembers(_module, inspect.isclass) for (_class_name, _class) in _clsmembers: if _module.__name__ != _class.__module__: # 不是当前模块定义的函数 continue # 判断类型 _get_form_type = getattr(_class, 'get_form_type', None) if _get_form_type is None or not callable(_get_form_type): # 不是标准的插件类 continue _form_type = _get_form_type() _get_form_config = getattr(_class, 'get_form_config', None) # 加入配置 FORM_PLUGIN_CONFIG[_form_type] = _get_form_config() # 循环插件实例进行处理 for _form_type in FORM_PLUGIN_CONFIG.keys(): _config = FORM_PLUGIN_CONFIG[_form_type] # 执行初始化 _initialize_fun = _config.get('initialize_fun', None) if _initialize_fun is not None: _initialize_fun(loader, qa_manager, qa, **kwargs)