Convert face crops to RGB before embedding (#23712)

* Convert face crops to RGB before embedding

Face crops flow through the cv2 pipeline as BGR arrays, but
_process_image passes ndarrays to PIL without any channel conversion,
so the FaceNet and ArcFace embedders receive BGR input while both
models expect RGB. The error is symmetric between enrollment and
recognition so it partially cancels, but it still costs accuracy.

* Move BGR to RGB conversion into a shared helper

Deduplicate the channel swap from both _preprocess_inputs methods
into a BaseEmbedding._bgr_to_rgb static helper, as suggested in
review.
This commit is contained in:
Jozef Huscava 2026-07-14 00:45:29 +02:00 committed by GitHub
parent 65af0b1351
commit 6f24f5a595
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 8 additions and 2 deletions

View File

@ -57,6 +57,12 @@ class BaseEmbedding(ABC):
def _preprocess_inputs(self, raw_inputs: Any) -> Any: def _preprocess_inputs(self, raw_inputs: Any) -> Any:
pass pass
@staticmethod
def _bgr_to_rgb(frame: Any) -> Any:
if isinstance(frame, np.ndarray) and frame.ndim == 3:
return np.ascontiguousarray(frame[:, :, ::-1])
return frame
def _process_image(self, image, output: str = "RGB") -> Image.Image: def _process_image(self, image, output: str = "RGB") -> Image.Image:
if isinstance(image, str): if isinstance(image, str):
if image.startswith("http"): if image.startswith("http"):

View File

@ -73,7 +73,7 @@ class FaceNetEmbedding(BaseEmbedding):
self.tensor_output_details = self.runner.get_output_details() self.tensor_output_details = self.runner.get_output_details()
def _preprocess_inputs(self, raw_inputs): def _preprocess_inputs(self, raw_inputs):
pil = self._process_image(raw_inputs[0]) pil = self._process_image(self._bgr_to_rgb(raw_inputs[0]))
# handle images larger than input size # handle images larger than input size
width, height = pil.size width, height = pil.size
@ -159,7 +159,7 @@ class ArcfaceEmbedding(BaseEmbedding):
) )
def _preprocess_inputs(self, raw_inputs): def _preprocess_inputs(self, raw_inputs):
pil = self._process_image(raw_inputs[0]) pil = self._process_image(self._bgr_to_rgb(raw_inputs[0]))
# handle images larger than input size # handle images larger than input size
width, height = pil.size width, height = pil.size