aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.pylintrc3
-rw-r--r--bsie/apps/index.py3
-rw-r--r--bsie/apps/info.py1
-rw-r--r--bsie/extractor/image/face/detect.py1
-rw-r--r--bsie/extractor/image/face/identify.py12
-rw-r--r--bsie/lib/pipeline.py2
-rw-r--r--bsie/reader/face.py23
-rw-r--r--bsie/utils/filewalker.py4
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 .
<https://schema.bsfs.io/ie/Node/Face#depicts> 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 ##