From 80fba922a879a4e473e95d09a57e4fca5f04bf8a Mon Sep 17 00:00:00 2001 From: "rujiao.lrj" Date: Thu, 17 Nov 2022 14:14:04 +0800 Subject: [PATCH] update for table_recognition --- data/test/images/table_recognition.jpg | Bin 0 -> 202112 bytes modelscope/metainfo.py | 1 + modelscope/outputs/outputs.py | 1 + modelscope/pipelines/builder.py | 2 + modelscope/pipelines/cv/__init__.py | 2 + .../pipelines/cv/ocr_utils/model_dla34.py | 574 ++++++++++++++++++ .../pipelines/cv/ocr_utils/table_process.py | 280 +++++++++ .../cv/table_recognition_pipeline.py | 114 ++++ modelscope/utils/constant.py | 1 + tests/pipelines/test_table_recognition.py | 39 ++ 10 files changed, 1014 insertions(+) create mode 100755 data/test/images/table_recognition.jpg create mode 100644 modelscope/pipelines/cv/ocr_utils/model_dla34.py create mode 100644 modelscope/pipelines/cv/ocr_utils/table_process.py create mode 100644 modelscope/pipelines/cv/table_recognition_pipeline.py create mode 100644 tests/pipelines/test_table_recognition.py diff --git a/data/test/images/table_recognition.jpg b/data/test/images/table_recognition.jpg new file mode 100755 index 0000000000000000000000000000000000000000..f8dd24778ea2c979e16565bf3971b4bd0c4c31b5 GIT binary patch literal 202112 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°2 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�okN$<32Iw{4ed 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 literal 0 HcmV?d00001 diff --git a/modelscope/metainfo.py b/modelscope/metainfo.py index c7c3e729..b5a5d209 100644 --- a/modelscope/metainfo.py +++ b/modelscope/metainfo.py @@ -149,6 +149,7 @@ class Pipelines(object): image_denoise = 'nafnet-image-denoise' person_image_cartoon = 'unet-person-image-cartoon' ocr_detection = 'resnet18-ocr-detection' + table_recognition = 'dla34-table-recognition' action_recognition = 'TAdaConv_action-recognition' animal_recognition = 'resnet101-animal-recognition' general_recognition = 'resnet101-general-recognition' diff --git a/modelscope/outputs/outputs.py b/modelscope/outputs/outputs.py index 2c6dd85a..f3117190 100644 --- a/modelscope/outputs/outputs.py +++ b/modelscope/outputs/outputs.py @@ -59,6 +59,7 @@ TASK_OUTPUTS = { # [x1, y1, x2, y2, x3, y3, x4, y4] # } Tasks.ocr_detection: [OutputKeys.POLYGONS], + Tasks.table_recognition: [OutputKeys.POLYGONS], # ocr recognition result for single sample # { diff --git a/modelscope/pipelines/builder.py b/modelscope/pipelines/builder.py index 70f8f11c..b27dc766 100644 --- a/modelscope/pipelines/builder.py +++ b/modelscope/pipelines/builder.py @@ -82,6 +82,8 @@ DEFAULT_MODEL_FOR_PIPELINE = { 'damo/cv_unet_person-image-cartoon_compound-models'), Tasks.ocr_detection: (Pipelines.ocr_detection, 'damo/cv_resnet18_ocr-detection-line-level_damo'), + Tasks.table_recognition: (Pipelines.table_recognition, + 'damo/cv_dla34_table-structure-recognition_cycle-centernet'), Tasks.fill_mask: (Pipelines.fill_mask, 'damo/nlp_veco_fill-mask-large'), Tasks.feature_extraction: (Pipelines.feature_extraction, 'damo/pert_feature-extraction_base-test'), diff --git a/modelscope/pipelines/cv/__init__.py b/modelscope/pipelines/cv/__init__.py index 97cd8761..9b7b928c 100644 --- a/modelscope/pipelines/cv/__init__.py +++ b/modelscope/pipelines/cv/__init__.py @@ -41,6 +41,7 @@ if TYPE_CHECKING: from .live_category_pipeline import LiveCategoryPipeline from .ocr_detection_pipeline import OCRDetectionPipeline from .ocr_recognition_pipeline import OCRRecognitionPipeline + from .table_recognition_pipeline import TableRecognitionPipeline from .skin_retouching_pipeline import SkinRetouchingPipeline from .tinynas_classification_pipeline import TinynasClassificationPipeline from .video_category_pipeline import VideoCategoryPipeline @@ -107,6 +108,7 @@ else: 'image_inpainting_pipeline': ['ImageInpaintingPipeline'], 'ocr_detection_pipeline': ['OCRDetectionPipeline'], 'ocr_recognition_pipeline': ['OCRRecognitionPipeline'], + 'table_recognition_pipeline': ['TableRecognitionPipeline'], 'skin_retouching_pipeline': ['SkinRetouchingPipeline'], 'tinynas_classification_pipeline': ['TinynasClassificationPipeline'], 'video_category_pipeline': ['VideoCategoryPipeline'], diff --git a/modelscope/pipelines/cv/ocr_utils/model_dla34.py b/modelscope/pipelines/cv/ocr_utils/model_dla34.py new file mode 100644 index 00000000..ab343a74 --- /dev/null +++ b/modelscope/pipelines/cv/ocr_utils/model_dla34.py @@ -0,0 +1,574 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import math +from os.path import join + +import torch +from torch import nn +import torch.utils.model_zoo as model_zoo + +import numpy as np + +BatchNorm = nn.BatchNorm2d + +def get_model_url(data='imagenet', name='dla34', hash='ba72cf86'): + return join('http://dl.yf.io/dla/models', data, '{}-{}.pth'.format(name, hash)) + +class BasicBlock(nn.Module): + def __init__(self, inplanes, planes, stride=1, dilation=1): + super(BasicBlock, self).__init__() + self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=3, + stride=stride, padding=dilation, + bias=False, dilation=dilation) + self.bn1 = BatchNorm(planes) + self.relu = nn.ReLU(inplace=True) + self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, + stride=1, padding=dilation, + bias=False, dilation=dilation) + self.bn2 = BatchNorm(planes) + self.stride = stride + + def forward(self, x, residual=None): + if residual is None: + residual = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + + out += residual + out = self.relu(out) + + return out + + +class Bottleneck(nn.Module): + expansion = 2 + + def __init__(self, inplanes, planes, stride=1, dilation=1): + super(Bottleneck, self).__init__() + expansion = Bottleneck.expansion + bottle_planes = planes // expansion + self.conv1 = nn.Conv2d(inplanes, bottle_planes, + kernel_size=1, bias=False) + self.bn1 = BatchNorm(bottle_planes) + self.conv2 = nn.Conv2d(bottle_planes, bottle_planes, kernel_size=3, + stride=stride, padding=dilation, + bias=False, dilation=dilation) + self.bn2 = BatchNorm(bottle_planes) + self.conv3 = nn.Conv2d(bottle_planes, planes, + kernel_size=1, bias=False) + self.bn3 = BatchNorm(planes) + self.relu = nn.ReLU(inplace=True) + self.stride = stride + + def forward(self, x, residual=None): + if residual is None: + residual = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + out = self.relu(out) + + out = self.conv3(out) + out = self.bn3(out) + + out += residual + out = self.relu(out) + + return out + + +class BottleneckX(nn.Module): + expansion = 2 + cardinality = 32 + + def __init__(self, inplanes, planes, stride=1, dilation=1): + super(BottleneckX, self).__init__() + cardinality = BottleneckX.cardinality + # dim = int(math.floor(planes * (BottleneckV5.expansion / 64.0))) + # bottle_planes = dim * cardinality + bottle_planes = planes * cardinality // 32 + self.conv1 = nn.Conv2d(inplanes, bottle_planes, + kernel_size=1, bias=False) + self.bn1 = BatchNorm(bottle_planes) + self.conv2 = nn.Conv2d(bottle_planes, bottle_planes, kernel_size=3, + stride=stride, padding=dilation, bias=False, + dilation=dilation, groups=cardinality) + self.bn2 = BatchNorm(bottle_planes) + self.conv3 = nn.Conv2d(bottle_planes, planes, + kernel_size=1, bias=False) + self.bn3 = BatchNorm(planes) + self.relu = nn.ReLU(inplace=True) + self.stride = stride + + def forward(self, x, residual=None): + if residual is None: + residual = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + out = self.relu(out) + + out = self.conv3(out) + out = self.bn3(out) + + out += residual + out = self.relu(out) + + return out + + +class Root(nn.Module): + def __init__(self, in_channels, out_channels, kernel_size, residual): + super(Root, self).__init__() + self.conv = nn.Conv2d( + in_channels, out_channels, 1, + stride=1, bias=False, padding=(kernel_size - 1) // 2) + self.bn = BatchNorm(out_channels) + self.relu = nn.ReLU(inplace=True) + self.residual = residual + + def forward(self, *x): + children = x + x = self.conv(torch.cat(x, 1)) + x = self.bn(x) + if self.residual: + x += children[0] + x = self.relu(x) + + return x + + +class Tree(nn.Module): + def __init__(self, levels, block, in_channels, out_channels, stride=1, + level_root=False, root_dim=0, root_kernel_size=1, + dilation=1, root_residual=False): + super(Tree, self).__init__() + if root_dim == 0: + root_dim = 2 * out_channels + if level_root: + root_dim += in_channels + if levels == 1: + self.tree1 = block(in_channels, out_channels, stride, + dilation=dilation) + self.tree2 = block(out_channels, out_channels, 1, + dilation=dilation) + else: + self.tree1 = Tree(levels - 1, block, in_channels, out_channels, + stride, root_dim=0, + root_kernel_size=root_kernel_size, + dilation=dilation, root_residual=root_residual) + self.tree2 = Tree(levels - 1, block, out_channels, out_channels, + root_dim=root_dim + out_channels, + root_kernel_size=root_kernel_size, + dilation=dilation, root_residual=root_residual) + if levels == 1: + self.root = Root(root_dim, out_channels, root_kernel_size, + root_residual) + self.level_root = level_root + self.root_dim = root_dim + self.downsample = None + self.project = None + self.levels = levels + if stride > 1: + self.downsample = nn.MaxPool2d(stride, stride=stride) + if in_channels != out_channels: + self.project = nn.Sequential( + nn.Conv2d(in_channels, out_channels, + kernel_size=1, stride=1, bias=False), + BatchNorm(out_channels) + ) + + def forward(self, x, residual=None, children=None): + children = [] if children is None else children + bottom = self.downsample(x) if self.downsample else x + residual = self.project(bottom) if self.project else bottom + if self.level_root: + children.append(bottom) + x1 = self.tree1(x, residual) + if self.levels == 1: + x2 = self.tree2(x1) + x = self.root(x2, x1, *children) + else: + children.append(x1) + x = self.tree2(x1, children=children) + return x + + +class DLA(nn.Module): + def __init__(self, levels, channels, num_classes=1000, + block=BasicBlock, residual_root=False, return_levels=False, + pool_size=7, linear_root=False): + super(DLA, self).__init__() + self.channels = channels + self.return_levels = return_levels + self.num_classes = num_classes + self.base_layer = nn.Sequential( + nn.Conv2d(3, channels[0], kernel_size=7, stride=1, + padding=3, bias=False), + BatchNorm(channels[0]), + nn.ReLU(inplace=True)) + self.level0 = self._make_conv_level( + channels[0], channels[0], levels[0]) + self.level1 = self._make_conv_level( + channels[0], channels[1], levels[1], stride=2) + self.level2 = Tree(levels[2], block, channels[1], channels[2], 2, + level_root=False, + root_residual=residual_root) + self.level3 = Tree(levels[3], block, channels[2], channels[3], 2, + level_root=True, root_residual=residual_root) + self.level4 = Tree(levels[4], block, channels[3], channels[4], 2, + level_root=True, root_residual=residual_root) + self.level5 = Tree(levels[5], block, channels[4], channels[5], 2, + level_root=True, root_residual=residual_root) + + self.avgpool = nn.AvgPool2d(pool_size) + self.fc = nn.Conv2d(channels[-1], num_classes, kernel_size=1, + stride=1, padding=0, bias=True) + + for m in self.modules(): + if isinstance(m, nn.Conv2d): + n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels + m.weight.data.normal_(0, math.sqrt(2. / n)) + elif isinstance(m, BatchNorm): + m.weight.data.fill_(1) + m.bias.data.zero_() + + def _make_level(self, block, inplanes, planes, blocks, stride=1): + downsample = None + if stride != 1 or inplanes != planes: + downsample = nn.Sequential( + nn.MaxPool2d(stride, stride=stride), + nn.Conv2d(inplanes, planes, + kernel_size=1, stride=1, bias=False), + BatchNorm(planes), + ) + + layers = [] + layers.append(block(inplanes, planes, stride, downsample=downsample)) + for i in range(1, blocks): + layers.append(block(inplanes, planes)) + + return nn.Sequential(*layers) + + def _make_conv_level(self, inplanes, planes, convs, stride=1, dilation=1): + modules = [] + for i in range(convs): + modules.extend([ + nn.Conv2d(inplanes, planes, kernel_size=3, + stride=stride if i == 0 else 1, + padding=dilation, bias=False, dilation=dilation), + BatchNorm(planes), + nn.ReLU(inplace=True)]) + inplanes = planes + return nn.Sequential(*modules) + + def forward(self, x): + y = [] + x = self.base_layer(x) + for i in range(6): + x = getattr(self, 'level{}'.format(i))(x) + y.append(x) + if self.return_levels: + return y + else: + x = self.avgpool(x) + x = self.fc(x) + x = x.view(x.size(0), -1) + + return x + + def load_pretrained_model(self, data='imagenet', name='dla34', hash='ba72cf86'): + fc = self.fc + if name.endswith('.pth'): + model_weights = torch.load(data + name) + else: + model_url = get_model_url(data, name, hash) + model_weights = model_zoo.load_url(model_url) + num_classes = len(model_weights[list(model_weights.keys())[-1]]) + self.fc = nn.Conv2d( + self.channels[-1], num_classes, + kernel_size=1, stride=1, padding=0, bias=True) + self.load_state_dict(model_weights) + self.fc = fc + + +def dla34(pretrained, **kwargs): # DLA-34 + model = DLA([1, 1, 1, 2, 2, 1], + [16, 32, 64, 128, 256, 512], + block=BasicBlock, **kwargs) + if pretrained: + model.load_pretrained_model(data='imagenet', name='dla34', hash='ba72cf86') + return model + + +def dla46_c(pretrained=None, **kwargs): # DLA-46-C + Bottleneck.expansion = 2 + model = DLA([1, 1, 1, 2, 2, 1], + [16, 32, 64, 64, 128, 256], + block=Bottleneck, **kwargs) + if pretrained is not None: + model.load_pretrained_model(pretrained, 'dla46_c') + return model + + +def dla46x_c(pretrained=None, **kwargs): # DLA-X-46-C + BottleneckX.expansion = 2 + model = DLA([1, 1, 1, 2, 2, 1], + [16, 32, 64, 64, 128, 256], + block=BottleneckX, **kwargs) + if pretrained is not None: + model.load_pretrained_model(pretrained, 'dla46x_c') + return model + + +def dla60x_c(pretrained, **kwargs): # DLA-X-60-C + BottleneckX.expansion = 2 + model = DLA([1, 1, 1, 2, 3, 1], + [16, 32, 64, 64, 128, 256], + block=BottleneckX, **kwargs) + if pretrained: + model.load_pretrained_model(data='imagenet', name='dla60x_c', hash='b870c45c') + return model + + +def dla60(pretrained=None, **kwargs): # DLA-60 + Bottleneck.expansion = 2 + model = DLA([1, 1, 1, 2, 3, 1], + [16, 32, 128, 256, 512, 1024], + block=Bottleneck, **kwargs) + if pretrained is not None: + model.load_pretrained_model(pretrained, 'dla60') + return model + + +def dla60x(pretrained=None, **kwargs): # DLA-X-60 + BottleneckX.expansion = 2 + model = DLA([1, 1, 1, 2, 3, 1], + [16, 32, 128, 256, 512, 1024], + block=BottleneckX, **kwargs) + if pretrained is not None: + model.load_pretrained_model(pretrained, 'dla60x') + return model + + +def dla102(pretrained=None, **kwargs): # DLA-102 + Bottleneck.expansion = 2 + model = DLA([1, 1, 1, 3, 4, 1], [16, 32, 128, 256, 512, 1024], + block=Bottleneck, residual_root=True, **kwargs) + if pretrained is not None: + model.load_pretrained_model(pretrained, 'dla102') + return model + + +def dla102x(pretrained=None, **kwargs): # DLA-X-102 + BottleneckX.expansion = 2 + model = DLA([1, 1, 1, 3, 4, 1], [16, 32, 128, 256, 512, 1024], + block=BottleneckX, residual_root=True, **kwargs) + if pretrained is not None: + model.load_pretrained_model(pretrained, 'dla102x') + return model + + +def dla102x2(pretrained=None, **kwargs): # DLA-X-102 64 + BottleneckX.cardinality = 64 + model = DLA([1, 1, 1, 3, 4, 1], [16, 32, 128, 256, 512, 1024], + block=BottleneckX, residual_root=True, **kwargs) + if pretrained is not None: + model.load_pretrained_model(pretrained, 'dla102x2') + return model + + +def dla169(pretrained=None, **kwargs): # DLA-169 + Bottleneck.expansion = 2 + model = DLA([1, 1, 2, 3, 5, 1], [16, 32, 128, 256, 512, 1024], + block=Bottleneck, residual_root=True, **kwargs) + if pretrained is not None: + model.load_pretrained_model(pretrained, 'dla169') + return model + + +def set_bn(bn): + global BatchNorm + BatchNorm = bn + dla.BatchNorm = bn + + +class Identity(nn.Module): + def __init__(self): + super(Identity, self).__init__() + + def forward(self, x): + return x + + +def fill_up_weights(up): + w = up.weight.data + f = math.ceil(w.size(2) / 2) + c = (2 * f - 1 - f % 2) / (2. * f) + for i in range(w.size(2)): + for j in range(w.size(3)): + w[0, 0, i, j] = \ + (1 - math.fabs(i / f - c)) * (1 - math.fabs(j / f - c)) + for c in range(1, w.size(0)): + w[c, 0, :, :] = w[0, 0, :, :] + + +class IDAUp(nn.Module): + def __init__(self, node_kernel, out_dim, channels, up_factors): + super(IDAUp, self).__init__() + self.channels = channels + self.out_dim = out_dim + for i, c in enumerate(channels): + if c == out_dim: + proj = Identity() + else: + proj = nn.Sequential( + nn.Conv2d(c, out_dim, + kernel_size=1, stride=1, bias=False), + BatchNorm(out_dim), + nn.ReLU(inplace=True)) + f = int(up_factors[i]) + if f == 1: + up = Identity() + else: + up = nn.ConvTranspose2d( + out_dim, out_dim, f * 2, stride=f, padding=f // 2, + output_padding=0, groups=out_dim, bias=False) + fill_up_weights(up) + setattr(self, 'proj_' + str(i), proj) + setattr(self, 'up_' + str(i), up) + + for i in range(1, len(channels)): + node = nn.Sequential( + nn.Conv2d(out_dim * 2, out_dim, + kernel_size=node_kernel, stride=1, + padding=node_kernel // 2, bias=False), + BatchNorm(out_dim), + nn.ReLU(inplace=True)) + setattr(self, 'node_' + str(i), node) + + for m in self.modules(): + if isinstance(m, nn.Conv2d): + n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels + m.weight.data.normal_(0, math.sqrt(2. / n)) + elif isinstance(m, BatchNorm): + m.weight.data.fill_(1) + m.bias.data.zero_() + + def forward(self, layers): + assert len(self.channels) == len(layers), \ + '{} vs {} layers'.format(len(self.channels), len(layers)) + layers = list(layers) + for i, l in enumerate(layers): + upsample = getattr(self, 'up_' + str(i)) + project = getattr(self, 'proj_' + str(i)) + layers[i] = upsample(project(l)) + x = layers[0] + y = [] + for i in range(1, len(layers)): + node = getattr(self, 'node_' + str(i)) + x = node(torch.cat([x, layers[i]], 1)) + y.append(x) + return x, y + + +class DLAUp(nn.Module): + def __init__(self, channels, scales=(1, 2, 4, 8, 16), in_channels=None): + super(DLAUp, self).__init__() + if in_channels is None: + in_channels = channels + self.channels = channels + channels = list(channels) + scales = np.array(scales, dtype=int) + for i in range(len(channels) - 1): + j = -i - 2 + setattr(self, 'ida_{}'.format(i), + IDAUp(3, channels[j], in_channels[j:], + scales[j:] // scales[j])) + scales[j + 1:] = scales[j] + in_channels[j + 1:] = [channels[j] for _ in channels[j + 1:]] + + def forward(self, layers): + layers = list(layers) + assert len(layers) > 1 + for i in range(len(layers) - 1): + ida = getattr(self, 'ida_{}'.format(i)) + x, y = ida(layers[-i - 2:]) + layers[-i - 1:] = y + return x + +def fill_fc_weights(layers): + for m in layers.modules(): + if isinstance(m, nn.Conv2d): + nn.init.normal_(m.weight, std=0.001) + # torch.nn.init.kaiming_normal_(m.weight.data, nonlinearity='relu') + # torch.nn.init.xavier_normal_(m.weight.data) + if m.bias is not None: + nn.init.constant_(m.bias, 0) + +class DLASeg(nn.Module): + def __init__(self, base_name='dla34', + pretrained=False, down_ratio=4, head_conv=256): + super(DLASeg, self).__init__() + assert down_ratio in [2, 4, 8, 16] + self.heads = {'hm': 2,'v2c':8, 'c2v': 8, 'reg': 2} + self.first_level = int(np.log2(down_ratio)) + self.base = globals()[base_name]( + pretrained=pretrained, return_levels=True) + channels = self.base.channels + scales = [2 ** i for i in range(len(channels[self.first_level:]))] + self.dla_up = DLAUp(channels[self.first_level:], scales=scales) + + for head in self.heads: + classes = self.heads[head] + if head_conv > 0: + fc = nn.Sequential( + nn.Conv2d(channels[self.first_level], head_conv, + kernel_size=3, padding=1, bias=True), + nn.ReLU(inplace=True), + nn.Conv2d(head_conv, classes, + kernel_size=1, stride=1, + padding=0, bias=True)) + if 'hm' in head: + fc[-1].bias.data.fill_(-2.19) + else: + fill_fc_weights(fc) + else: + fc = nn.Conv2d(channels[self.first_level], classes, + kernel_size=1, stride=1, + padding=0, bias=True) + if 'hm' in head: + fc.bias.data.fill_(-2.19) + else: + fill_fc_weights(fc) + self.__setattr__(head, fc) + + def forward(self, x): + x = self.base(x) + x = self.dla_up(x[self.first_level:]) + ret = {} + for head in self.heads: + ret[head] = self.__getattr__(head)(x) + return [ret] + + +def TableRecModel(): + model = DLASeg() + return model diff --git a/modelscope/pipelines/cv/ocr_utils/table_process.py b/modelscope/pipelines/cv/ocr_utils/table_process.py new file mode 100644 index 00000000..2cfd7257 --- /dev/null +++ b/modelscope/pipelines/cv/ocr_utils/table_process.py @@ -0,0 +1,280 @@ +import numpy as np +import cv2 +import copy +import math +import random +import torch +import torch.nn as nn + +def transform_preds(coords, center, scale, output_size, rot=0): + target_coords = np.zeros(coords.shape) + trans = get_affine_transform(center, scale, rot, output_size, inv=1) + for p in range(coords.shape[0]): + target_coords[p, 0:2] = affine_transform(coords[p, 0:2], trans) + return target_coords + +def get_affine_transform(center, + scale, + rot, + output_size, + shift=np.array([0, 0], dtype=np.float32), + inv=0): + if not isinstance(scale, np.ndarray) and not isinstance(scale, list): + scale = np.array([scale, scale], dtype=np.float32) + + scale_tmp = scale + src_w = scale_tmp[0] + dst_w = output_size[0] + dst_h = output_size[1] + + rot_rad = np.pi * rot / 180 + src_dir = get_dir([0, src_w * -0.5], rot_rad) + dst_dir = np.array([0, dst_w * -0.5], np.float32) + + src = np.zeros((3, 2), dtype=np.float32) + dst = np.zeros((3, 2), dtype=np.float32) + src[0, :] = center + scale_tmp * shift + src[1, :] = center + src_dir + scale_tmp * shift + dst[0, :] = [dst_w * 0.5, dst_h * 0.5] + dst[1, :] = np.array([dst_w * 0.5, dst_h * 0.5], np.float32) + dst_dir + + src[2:, :] = get_3rd_point(src[0, :], src[1, :]) + dst[2:, :] = get_3rd_point(dst[0, :], dst[1, :]) + + if inv: + trans = cv2.getAffineTransform(np.float32(dst), np.float32(src)) + else: + trans = cv2.getAffineTransform(np.float32(src), np.float32(dst)) + + return trans + +def affine_transform(pt, t): + new_pt = np.array([pt[0], pt[1], 1.], dtype=np.float32).T + new_pt = np.dot(t, new_pt) + return new_pt[:2] + +def get_dir(src_point, rot_rad): + sn, cs = np.sin(rot_rad), np.cos(rot_rad) + + src_result = [0, 0] + src_result[0] = src_point[0] * cs - src_point[1] * sn + src_result[1] = src_point[0] * sn + src_point[1] * cs + + return src_result + +def get_3rd_point(a, b): + direct = a - b + return b + np.array([-direct[1], direct[0]], dtype=np.float32) + +def _sigmoid(x): + y = torch.clamp(x.sigmoid_(), min=1e-4, max=1-1e-4) + return y + +def _gather_feat(feat, ind, mask=None): + dim = feat.size(2) + ind = ind.unsqueeze(2).expand(ind.size(0), ind.size(1), dim) + feat = feat.gather(1, ind) + if mask is not None: + mask = mask.unsqueeze(2).expand_as(feat) + feat = feat[mask] + feat = feat.view(-1, dim) + return feat + +def _tranpose_and_gather_feat(feat, ind): + feat = feat.permute(0, 2, 3, 1).contiguous() + feat = feat.view(feat.size(0), -1, feat.size(3)) + feat = _gather_feat(feat, ind) + return feat + +def _nms(heat, kernel=3): + pad = (kernel - 1) // 2 + + hmax = nn.functional.max_pool2d( + heat, (kernel, kernel), stride=1, padding=pad) + keep = (hmax == heat).float() + return heat * keep,keep + +def _topk(scores, K=40): + batch, cat, height, width = scores.size() + + topk_scores, topk_inds = torch.topk(scores.view(batch, cat, -1), K) + + topk_inds = topk_inds % (height * width) + topk_ys = (topk_inds / width).int().float() + topk_xs = (topk_inds % width).int().float() + + topk_score, topk_ind = torch.topk(topk_scores.view(batch, -1), K) + topk_clses = (topk_ind / K).int() + topk_inds = _gather_feat( + topk_inds.view(batch, -1, 1), topk_ind).view(batch, K) + topk_ys = _gather_feat(topk_ys.view(batch, -1, 1), topk_ind).view(batch, K) + topk_xs = _gather_feat(topk_xs.view(batch, -1, 1), topk_ind).view(batch, K) + + return topk_score, topk_inds, topk_clses, topk_ys, topk_xs + + +def bbox_decode(heat, wh, reg=None, K=100): + batch, cat, height, width = heat.size() + + # heat = torch.sigmoid(heat) + # perform nms on heatmaps + heat,keep = _nms(heat) + + scores, inds, clses, ys, xs = _topk(heat, K=K) + if reg is not None: + reg = _tranpose_and_gather_feat(reg, inds) + reg = reg.view(batch, K, 2) + xs = xs.view(batch, K, 1) + reg[:, :, 0:1] + ys = ys.view(batch, K, 1) + reg[:, :, 1:2] + else: + xs = xs.view(batch, K, 1) + 0.5 + ys = ys.view(batch, K, 1) + 0.5 + wh = _tranpose_and_gather_feat(wh, inds) + wh = wh.view(batch, K, 8) + clses = clses.view(batch, K, 1).float() + scores = scores.view(batch, K, 1) + + bboxes = torch.cat([xs - wh[..., 0:1], + ys - wh[..., 1:2], + xs - wh[..., 2:3], + ys - wh[..., 3:4], + xs - wh[..., 4:5], + ys - wh[..., 5:6], + xs - wh[..., 6:7], + ys - wh[..., 7:8]], dim=2) + detections = torch.cat([bboxes, scores, clses], dim=2) + + return detections,keep + +def gbox_decode(mk, st_reg, reg=None, K=400): + batch, cat, height, width = mk.size() + mk,keep = _nms(mk) + scores, inds, clses, ys, xs = _topk(mk, K=K) + if reg is not None: + reg = _tranpose_and_gather_feat(reg, inds) + reg = reg.view(batch, K, 2) + xs = xs.view(batch, K, 1) + reg[:, :, 0:1] + ys = ys.view(batch, K, 1) + reg[:, :, 1:2] + else: + xs = xs.view(batch, K, 1) + 0.5 + ys = ys.view(batch, K, 1) + 0.5 + scores = scores.view(batch, K, 1) + clses = clses.view(batch, K, 1).float() + st_Reg = _tranpose_and_gather_feat(st_reg, inds) + bboxes = torch.cat([xs - st_Reg[..., 0:1], + ys - st_Reg[..., 1:2], + xs - st_Reg[..., 2:3], + ys - st_Reg[..., 3:4], + xs - st_Reg[..., 4:5], + ys - st_Reg[..., 5:6], + xs - st_Reg[..., 6:7], + ys - st_Reg[..., 7:8]], dim=2) + return torch.cat([xs,ys,bboxes,scores,clses], dim=2), keep + +def bbox_post_process(bbox, c, s, h, w): + # dets: batch x max_dets x dim + # return 1-based class det dict + for i in range(bbox.shape[0]): + bbox[i, :, 0:2] = transform_preds(bbox[i, :, 0:2], c[i], s[i], (w, h)) + bbox[i, :, 2:4] = transform_preds(bbox[i, :, 2:4], c[i], s[i], (w, h)) + bbox[i, :, 4:6] = transform_preds(bbox[i, :, 4:6], c[i], s[i], (w, h)) + bbox[i, :, 6:8] = transform_preds(bbox[i, :, 6:8], c[i], s[i], (w, h)) + return bbox + +def gbox_post_process(gbox, c, s, h, w): + for i in range(gbox.shape[0]): + gbox[i, :, 0:2] = transform_preds(gbox[i, :, 0:2], c[i], s[i], (w, h)) + gbox[i, :, 2:4] = transform_preds(gbox[i, :, 2:4], c[i], s[i], (w, h)) + gbox[i, :, 4:6] = transform_preds(gbox[i, :, 4:6], c[i], s[i], (w, h)) + gbox[i, :, 6:8] = transform_preds(gbox[i, :, 6:8], c[i], s[i], (w, h)) + gbox[i, :, 8:10] = transform_preds(gbox[i, :, 8:10], c[i], s[i], (w, h)) + return gbox + +def nms(dets,thresh): + if len(dets)<2: + return dets + scores = dets[:,8] + index_keep = [] + keep = [] + for i in range(len(dets)): + box = dets[i] + if box[-1] 0 and b > 0 and c > 0 and d > 0) or (a < 0 and b < 0 and c < 0 and d < 0)): + if dets[i][8] > dets[j][8] and max_score_index < 0: + max_score_index = i + elif dets[i][8] < dets[j][8]: + max_score_index = -2 + break + if max_score_index > -1: + index_keep.append(max_score_index) + elif max_score_index==-1: + index_keep.append(i) + for i in range(0,len(index_keep)): + keep.append(dets[index_keep[i]]) + return np.array(keep) + + +def group_bbox_by_gbox(bboxes,gboxes,score_thred=0.3, v2c_dist_thred=2, c2v_dist_thred=0.5): + + def point_in_box(box,point): + x1,y1,x2,y2 = box[0],box[1],box[2],box[3] + x3,y3,x4,y4 = box[4],box[5],box[6],box[7] + ctx,cty = point[0],point[1] + a = (x2 - x1)*(cty - y1) - (y2 - y1)*(ctx - x1) + b = (x3 - x2)*(cty - y2) - (y3 - y2)*(ctx - x2) + c = (x4 - x3)*(cty - y3) - (y4 - y3)*(ctx - x3) + d = (x1 - x4)*(cty - y4) - (y1 - y4)*(ctx - x4) + if ((a > 0 and b > 0 and c > 0 and d > 0) or (a < 0 and b < 0 and c < 0 and d < 0)): + return True + else : + return False + + def get_distance(pt1,pt2): + return math.sqrt((pt1[0]-pt2[0])*(pt1[0]-pt2[0]) + (pt1[1]-pt2[1])*(pt1[1]-pt2[1])) + + dets = copy.deepcopy(bboxes) + sign = np.zeros((len(dets),4)) + + for idx,gbox in enumerate(gboxes): #vertex x,y, gbox, score + if gbox[10] < score_thred: + break + vertex = [gbox[0],gbox[1]] + for i in range(0,4): + center = [gbox[2*i+2],gbox[2*i+3]] + if get_distance(vertex,center) < v2c_dist_thred: + continue + for k,bbox in enumerate(dets): + if bbox[8] < score_thred: + break + if sum(sign[k])==4: + continue + w = (abs(bbox[6] - bbox[0]) + abs(bbox[4] - bbox[2])) / 2 + h = (abs(bbox[3] - bbox[1]) + abs(bbox[5] - bbox[7])) / 2 + m = max(w,h) + if point_in_box(bbox,center): + min_dist,min_id = 1e4,-1 + for j in range(0,4): + dist = get_distance(vertex,[bbox[2*j],bbox[2*j+1]]) + if dist < min_dist: + min_dist = dist + min_id = j + if min_id>-1 and min_dist Dict[str, Any]: + if isinstance(input, str): + img = np.array(load_image(input)) + elif isinstance(input, PIL.Image.Image): + img = np.array(input) + elif isinstance(input, np.ndarray): + if len(input.shape) == 3: + img = input + else: + raise TypeError(f'input should be either str, PIL.Image,' + f' np.array, but got {type(input)}') + + mean = np.array([0.408, 0.447, 0.470], dtype=np.float32).reshape(1, 1, 3) + std = np.array([0.289, 0.274, 0.278], dtype=np.float32).reshape(1, 1, 3) + height, width = img.shape[0:2] + inp_height, inp_width = 1024, 1024 + c = np.array([width / 2., height / 2.], dtype=np.float32) + s = max(height, width) * 1.0 + + trans_input = get_affine_transform(c, s, 0, [inp_width, inp_height]) + resized_image = cv2.resize(img, (width, height)) + inp_image = cv2.warpAffine( + resized_image, trans_input, (inp_width, inp_height), + flags=cv2.INTER_LINEAR) + inp_image = ((inp_image / 255. - mean) / std).astype(np.float32) + + images = inp_image.transpose(2, 0, 1).reshape(1, 3, inp_height, inp_width) + images = torch.from_numpy(images).to(self.device) + meta = {'c': c, 's': s, + 'input_height':inp_height, + 'input_width':inp_width, + 'out_height': inp_height // 4, + 'out_width': inp_width // 4} + + result = {'img': images, 'meta': meta} + + return result + + def forward(self, input: Dict[str, Any]) -> Dict[str, Any]: + pred = self.infer_model(input['img']) + return {'results': pred, 'meta': input['meta']} + + def postprocess(self, inputs: Dict[str, Any]) -> Dict[str, Any]: + output = inputs['results'][0] + meta = inputs['meta'] + hm = output['hm'].sigmoid_() + v2c = output['v2c'] + c2v = output['c2v'] + reg = output['reg'] + bbox, _ = bbox_decode(hm[:,0:1,:,:], c2v, reg=reg, K=self.K) + gbox, _ = gbox_decode(hm[:,1:2,:,:], v2c, reg=reg, K=self.MK) + + bbox = bbox.detach().cpu().numpy() + gbox = gbox.detach().cpu().numpy() + bbox = nms(bbox,0.3) + bbox = bbox_post_process(bbox.copy(),[meta['c'].cpu().numpy()],[meta['s']],meta['out_height'],meta['out_width']) + gbox = gbox_post_process(gbox.copy(),[meta['c'].cpu().numpy()],[meta['s']],meta['out_height'],meta['out_width']) + bbox = group_bbox_by_gbox(bbox[0],gbox[0]) + + res = [] + for box in bbox: + if box[8] > 0.3: + res.append(box[0:8]) + + result = {OutputKeys.POLYGONS: np.array(res)} + return result \ No newline at end of file diff --git a/modelscope/utils/constant.py b/modelscope/utils/constant.py index f0a97dbd..ff6b3e41 100644 --- a/modelscope/utils/constant.py +++ b/modelscope/utils/constant.py @@ -16,6 +16,7 @@ class CVTasks(object): # ocr ocr_detection = 'ocr-detection' ocr_recognition = 'ocr-recognition' + table_recognition = 'table-recognition' # human face body related animal_recognition = 'animal-recognition' diff --git a/tests/pipelines/test_table_recognition.py b/tests/pipelines/test_table_recognition.py new file mode 100644 index 00000000..b7f265d5 --- /dev/null +++ b/tests/pipelines/test_table_recognition.py @@ -0,0 +1,39 @@ +# Copyright (c) Alibaba, Inc. and its affiliates. +import unittest + +from modelscope.pipelines import pipeline +from modelscope.pipelines.base import Pipeline +from modelscope.utils.constant import Tasks +from modelscope.utils.demo_utils import DemoCompatibilityCheck +from modelscope.utils.test_utils import test_level + + +class TableRecognitionTest(unittest.TestCase, DemoCompatibilityCheck): + + def setUp(self) -> None: + self.model_id = 'damo/cv_dla34_table-structure-recognition_cycle-centernet' + self.test_image = 'data/test/images/table_recognition.jpg' + self.task = Tasks.table_recognition + + def pipeline_inference(self, pipeline: Pipeline, input_location: str): + result = pipeline(input_location) + print('table recognition results: ') + print(result) + + @unittest.skipUnless(test_level() >= 0, 'skip test in current test level') + def test_run_with_model_from_modelhub(self): + table_recognition = pipeline(Tasks.table_recognition, model=self.model_id) + self.pipeline_inference(table_recognition, self.test_image) + + @unittest.skipUnless(test_level() >= 2, 'skip test in current test level') + def test_run_modelhub_default_model(self): + table_recognition = pipeline(Tasks.table_recognition) + self.pipeline_inference(table_recognition, self.test_image) + + @unittest.skip('demo compatibility test is only enabled on a needed-basis') + def test_demo_compatibility(self): + self.compatibility_check() + + +if __name__ == '__main__': + unittest.main()