From bc6e80015844dfd4be44a877109e68798c26e79a Mon Sep 17 00:00:00 2001 From: Matthias Baumgartner Date: Wed, 26 Jul 2023 13:04:55 +0200 Subject: code style and type annotation fixes --- .pylintrc | 3 ++- bsie/apps/index.py | 3 +-- bsie/apps/info.py | 1 - bsie/extractor/image/face/detect.py | 1 + bsie/extractor/image/face/identify.py | 12 ++++++------ bsie/lib/pipeline.py | 2 +- bsie/reader/face.py | 23 ++++++++++++----------- bsie/utils/filewalker.py | 4 ++-- 8 files changed, 25 insertions(+), 24 deletions(-) diff --git a/.pylintrc b/.pylintrc index 576e81a..aca6a8a 100644 --- a/.pylintrc +++ b/.pylintrc @@ -156,7 +156,8 @@ disable=raw-checker-failed, useless-suppression, deprecated-pragma, use-symbolic-message-instead, - duplicate-code + duplicate-code, + missing-module-docstring diff --git a/bsie/apps/index.py b/bsie/apps/index.py index 260d3c8..268a520 100644 --- a/bsie/apps/index.py +++ b/bsie/apps/index.py @@ -1,13 +1,12 @@ # standard imports import argparse -import os import typing # bsie imports from bsie.lib import BSIE from bsie.matcher import nodes, DefaultMatcher -from bsie.utils import bsfs, errors, list_files +from bsie.utils import bsfs, list_files # inner-module imports from . import _loader diff --git a/bsie/apps/info.py b/bsie/apps/info.py index b6494da..f36fb1d 100644 --- a/bsie/apps/info.py +++ b/bsie/apps/info.py @@ -1,7 +1,6 @@ # standard imports import argparse -import os import sys import typing diff --git a/bsie/extractor/image/face/detect.py b/bsie/extractor/image/face/detect.py index 51d5659..68a03ef 100644 --- a/bsie/extractor/image/face/detect.py +++ b/bsie/extractor/image/face/detect.py @@ -24,6 +24,7 @@ __all__: typing.Sequence[str] = ( bsf = ns.bsn.Face() class FaceDetect(base.Extractor): + """Extract faces detected in an image.""" CONTENT_READER = 'bsie.reader.face.FaceExtract' diff --git a/bsie/extractor/image/face/identify.py b/bsie/extractor/image/face/identify.py index 44a75c4..dee935f 100644 --- a/bsie/extractor/image/face/identify.py +++ b/bsie/extractor/image/face/identify.py @@ -4,7 +4,6 @@ import csv import typing # external imports -from facenet_pytorch import MTCNN, InceptionResnetV1 import numpy as np import torch @@ -26,6 +25,7 @@ __all__: typing.Sequence[str] = ( bsf = ns.bsn.Face() class FaceIdentify(base.Extractor): + """Extract identified people in an image.""" CONTENT_READER = 'bsie.reader.face.FaceExtract' @@ -49,9 +49,9 @@ class FaceIdentify(base.Extractor): thres: float = 0.9, cuda_device: str = 'cuda:0', restklasse: str = 'https://example.com/user/anon', - ): + ): # pylint: disable=too-many-arguments # initialize parent with the schema - super().__init__(bsfs.schema.from_string(base.SCHEMA_PREAMBLE + f''' + super().__init__(bsfs.schema.from_string(base.SCHEMA_PREAMBLE + ''' bsn:Face rdfs:subClassOf bsfs:Node . bsn:Person rdfs:subClassOf bsfs:Node . rdfs:subClassOf bsfs:Predicate ; @@ -84,7 +84,7 @@ class FaceIdentify(base.Extractor): targets, embeds = emb_with_trg[:, 0], emb_with_trg[:, 1:] self._targets = torch.tensor(targets, dtype=torch.int32).to(self._device) self._embeds = torch.tensor(embeds).to(self._device) - with open(ref_mapping, 'rt') as ifile: + with open(ref_mapping, 'rt', encoding='UTF-8') as ifile: mapping = [(int(idx), name) for name, idx in csv.reader(ifile)] # ensure that the mapping is unique ids, names = zip(*mapping) @@ -133,13 +133,13 @@ class FaceIdentify(base.Extractor): self._restidx, )) - def _classify(self, emb: torch.Tensor) -> torch.Tensor: # [Nx512] -> [N] + def _classify(self, emb: torch.Tensor) -> typing.List[int]: # [Nx512] -> [N] # nearest neighbour approach dist = torch.cdist(emb, self._embeds) # pairwise distances best = dist.argmin(dim=1) # idx of lowest distance, per row labels = self._targets[best] # label (int) of nearest neighbour acc = dist[range(len(best)), best] < self._thres # check if distance is below threshold - return [lbl.item() if cnd == True else self._restidx for cnd, lbl in zip(acc, labels)] + return [lbl.item() if cnd is True else self._restidx for cnd, lbl in zip(acc, labels)] def extract( self, diff --git a/bsie/lib/pipeline.py b/bsie/lib/pipeline.py index 98d9cc8..29b5ca3 100644 --- a/bsie/lib/pipeline.py +++ b/bsie/lib/pipeline.py @@ -8,7 +8,7 @@ import typing from bsie.extractor import Extractor from bsie.matcher import nodes from bsie.reader import Reader -from bsie.utils import bsfs, errors, ns +from bsie.utils import bsfs, errors # exports __all__: typing.Sequence[str] = ( diff --git a/bsie/reader/face.py b/bsie/reader/face.py index e43b93f..5e38101 100644 --- a/bsie/reader/face.py +++ b/bsie/reader/face.py @@ -1,6 +1,5 @@ # standard imports -import operator import typing # external imports @@ -9,7 +8,7 @@ import PIL.Image import torch # bsie imports -from bsie.utils import bsfs, errors, ns +from bsie.utils import bsfs, errors # inner-module imports from . import base @@ -44,9 +43,9 @@ class FaceExtract(base.Reader): min_face_prob: float = 0.992845, cuda_device: str = 'cuda:0', ext_face_size: int = 160, - thresholds: typing.Tuple[float, float, float] = [0.5, 0.6, 0.6], + thresholds: typing.Tuple[float, float, float] = (0.5, 0.6, 0.6), factor: float = 0.709, - ): + ): # pylint: disable=too-many-arguments # initialize self._device = torch.device(cuda_device if torch.cuda.is_available() else 'cpu') # initialize the face detection network @@ -81,7 +80,9 @@ class FaceExtract(base.Reader): img: PIL.Image.Image, target_size: int, rotate: typing.Union[bool, int] = True, - ) -> typing.Tuple[PIL.Image.Image, typing.Callable[[typing.Tuple[float, float]], typing.Tuple[float, float]]]: + ) -> typing.Tuple[ + PIL.Image.Image, + typing.Callable[[typing.Tuple[float, float]], typing.Tuple[float, float]]]: """Preprocess an image. Return the image and a coordinate back-transformation function. 1. Scale larger side to *target_size* 2. Rotate by angle *rotate*, or auto-rotate if *rotate=None* (the default). @@ -106,23 +107,23 @@ class FaceExtract(base.Reader): ), reducing_gap=3) # get scale factors - sX = orig_size[0] / img.width - sY = orig_size[1] / img.height + scale_x = orig_size[0] / img.width + scale_y = orig_size[1] / img.height # rotate image (if need be) - denorm = lambda xy: (sX*xy[0], sY*xy[1]) + denorm = lambda xy: (scale_x*xy[0], scale_y*xy[1]) if rotate is not None: # auto-rotate according to EXIF information img_ori = img.getexif().get(exif_ori, None) if img_ori == 3 or rotate == 180: img = img.rotate(180, expand=True) - denorm = lambda xy: (orig_size[0] - sX*xy[0], orig_size[1] - sY*xy[1]) + denorm = lambda xy: (orig_size[0] - scale_x*xy[0], orig_size[1] - scale_y*xy[1]) elif img_ori == 6 or rotate == 270: img = img.rotate(270, expand=True) - denorm = lambda xy: (orig_size[0] - sX*xy[1], sY*xy[0]) + denorm = lambda xy: (orig_size[0] - scale_x*xy[1], scale_y*xy[0]) elif img_ori == 8 or rotate == 90: img = img.rotate(90, expand=True) - denorm = lambda xy: (sX*xy[1], orig_size[1] - sY*xy[0]) + denorm = lambda xy: (scale_x*xy[1], orig_size[1] - scale_y*xy[0]) # return image and denormalization function return img, denorm diff --git a/bsie/utils/filewalker.py b/bsie/utils/filewalker.py index 3c36926..df72c38 100644 --- a/bsie/utils/filewalker.py +++ b/bsie/utils/filewalker.py @@ -21,11 +21,11 @@ def list_files( for path in roots: if not os.path.exists(path): continue - elif os.path.isdir(path) and recursive: + if os.path.isdir(path) and recursive: for dirpath, _, filenames in os.walk(path, topdown=True, followlinks=follow_symlinks): for filename in filenames: yield os.path.join(dirpath, filename) - elif os.path.isfile(path): + if os.path.isfile(path): yield path ## EOF ## -- cgit v1.2.3