Exemplo n.º 1
0
    def trim(im, *, border=0, color=None):
        """ 默认裁剪掉白色边缘,可以配合 get_backgroup_color 裁剪掉背景色

        :param border: 上下左右保留多少边缘
            输入一个整数,表示统一留边
            也可以输入[int, int, int, int],分别表示left top right bottom留白
        :param color: 要裁剪的颜色,这是精确值,没有误差,如果需要模糊,可以提前预处理成精确值
            这个默认值设成None,本来是想说支持灰度图,此时输入一个255的值就好
            但是pil的灰度图机制好像有些不太一样,总之目前默认值还是自动会设成 (255, 255, 255)
        :param percent-background: TODO 控制裁剪百分比上限
        """
        from PIL import Image, ImageChops
        from pyxllib.algo.geo import xywh2ltrb, ltrb2xywh, ltrb_border

        if color is None:
            color = (255, 255, 255)

        bg = Image.new(im.mode, im.size, color)
        diff = ImageChops.difference(im, bg)
        bbox = diff.getbbox()  # 如果im跟bg一样,也就是裁"消失"了,此时bbox值为None
        if bbox:
            if border:
                ltrb = xywh2ltrb(bbox)
                ltrb = ltrb_border(ltrb, border, im.size)
                bbox = ltrb2xywh(ltrb)
            im = im.crop(bbox)
        return im
Exemplo n.º 2
0
    def to_icdar_label_quad(self, outfile, *, min_score=0):
        """ 将coco的dt结果转为icdar的标注格式

        存成一个zip文件,zip里面每张图对应一个txt标注文件
        每个txt文件用quad八个数值代表一个标注框

        适用于 sroie 检测格式
        """
        # 1 获取dt_list
        if min_score:
            dt_list = [b for b in self.dt_list if (b['score'] >= min_score)]
        else:
            dt_list = self.dt_list

        # 2 转df,按图片分组处理
        df = pd.DataFrame.from_dict(dt_list)  # noqa from_dict可以传入List[Dict]
        df = df.groupby('image_id')

        # 3 建立一个zip文件
        myzip = ZipFile(str(outfile), 'w')

        # 4 遍历每一组数据,生成一个文件放到zip里面
        id2name = {
            im['id']: pathlib.Path(im['file_name']).stem
            for im in self.gt_dict['images']
        }
        for image_id, items in df:
            label_file = id2name[image_id] + '.txt'
            quads = [
                rect2polygon(xywh2ltrb(x), dtype=int).reshape(-1)
                for x in items['bbox']
            ]
            quads = [','.join(map(str, x)) for x in quads]
            myzip.writestr(label_file, '\n'.join(quads))
        myzip.close()
Exemplo n.º 3
0
 def img2rects(self,
               img,
               haystack=None,
               *,
               grayscale=None,
               confidence=None):
     """ 根据预存的img数据,匹配出多个内容对应的所在的rect位置 """
     # 1 配置参数
     if isinstance(img, str):
         img = self[img]['img']
     grayscale = first_nonnone([grayscale, self.grayscale, False])
     confidence = first_nonnone([confidence, self.confidence, 0.95])
     # 2 查找子图
     if haystack is None:
         self.update_shot()
         haystack = self.last_shot
     boxes = pyautogui.locateAll(img,
                                 haystack,
                                 grayscale=grayscale,
                                 confidence=confidence)
     # 3 过滤掉重叠超过一半面积的框
     return ComputeIou.nms_ltrb([xywh2ltrb(box) for box in list(boxes)])
Exemplo n.º 4
0
    def check_img(self,
                  loclabel,
                  needle=None,
                  *,
                  grayscale=None,
                  confidence=None):
        grayscale = first_nonnone([grayscale, self.grayscale, False])
        confidence = first_nonnone([confidence, self.confidence, 0.95])
        if needle is None:
            needle = self[loclabel]['img']
        elif isinstance(needle, str):
            needle = self[needle]['img']
        haystack = self.screenshot(loclabel)

        if confidence >= 1:
            return np.array_equal(needle, haystack)
        else:
            boxes = pyautogui.locateAll(needle,
                                        self.screenshot(loclabel),
                                        grayscale=grayscale,
                                        confidence=confidence)
            boxes = [xywh2ltrb(box) for box in list(boxes)]
            return len(boxes)
Exemplo n.º 5
0
 def bbox2ltrb(cls, b):
     return [int(round(v, 0)) for v in xywh2ltrb(b)]
Exemplo n.º 6
0
    def to_labelme_cls(self, root, *, bbox=True, seg=False, info=False):
        """
        :param root: 图片根目录
        :return:
            extdata,存储了一些匹配异常信息
        """
        root, data = Dir(root), {}
        catid2name = {x['id']: x['name'] for x in self.gt_dict['categories']}

        # 1 准备工作,构建文件名索引字典
        gs = PathGroups.groupby(root.select_files('**/*'))

        # 2 遍历生成labelme数据
        not_finds = set()  # coco里有的图片,root里没有找到
        multimatch = dict()  # coco里的某张图片,在root找到多个匹配文件
        for img, anns in tqdm(self.group_gt(reserve_empty=True),
                              disable=not info):
            # 2.1 文件匹配
            imfiles = gs.find_files(img['file_name'])
            if not imfiles:  # 没有匹配图片的,不处理
                not_finds.add(img['file_name'])
                continue
            elif len(imfiles) > 1:
                multimatch[img['file_name']] = imfiles
                imfile = imfiles[0]
            else:
                imfile = imfiles[0]

            # 2.2 数据内容转换
            lmdict = LabelmeDict.gen_data(imfile)
            img = DictTool.or_(img, {'xltype': 'image'})
            lmdict['shapes'].append(
                LabelmeDict.gen_shape(json.dumps(img, ensure_ascii=False),
                                      [[-10, 0], [-5, 0]]))
            for ann in anns:
                if bbox:
                    ann = DictTool.or_(
                        ann, {'category_name': catid2name[ann['category_id']]})
                    label = json.dumps(ann, ensure_ascii=False)
                    shape = LabelmeDict.gen_shape(label,
                                                  xywh2ltrb(ann['bbox']))
                    lmdict['shapes'].append(shape)

                if seg:
                    # 把分割也显示出来(用灰色)
                    for x in ann['segmentation']:
                        an = {
                            'box_id': ann['id'],
                            'xltype': 'seg',
                            'shape_color': [191, 191, 191]
                        }
                        label = json.dumps(an, ensure_ascii=False)
                        lmdict['shapes'].append(LabelmeDict.gen_shape(
                            label, x))

            f = imfile.with_suffix('.json')

            data[f.relpath(root)] = lmdict

        return LabelmeDataset(root,
                              data,
                              extdata={
                                  'categories': self.gt_dict['categories'],
                                  'not_finds': not_finds,
                                  'multimatch': Groups(multimatch)
                              })