perf: 用 numpy 加速 is_blank_frame/compute_binary_matrix/compute_iou 三个像素遍历函数

This commit is contained in:
simonkoson
2026-06-12 18:04:57 +08:00
parent a826212302
commit 47e17179c7
2 changed files with 14 additions and 28 deletions
+1
View File
@@ -16,6 +16,7 @@ authors = [
dependencies = [ dependencies = [
"Pillow>=10.0.0", "Pillow>=10.0.0",
"imagehash>=4.3.1", "imagehash>=4.3.1",
"numpy>=1.24.0",
"requests>=2.31.0", "requests>=2.31.0",
"python-dotenv>=1.0.0", "python-dotenv>=1.0.0",
"click>=8.1.0", "click>=8.1.0",
+13 -28
View File
@@ -19,6 +19,7 @@ import tempfile
from pathlib import Path from pathlib import Path
from typing import Dict, List, Tuple, Optional from typing import Dict, List, Tuple, Optional
import numpy as np
from PIL import Image from PIL import Image
import imagehash import imagehash
@@ -185,14 +186,12 @@ def is_blank_frame(image_path: Path, debug: bool = False) -> Tuple[bool, float]:
返回: (is_blank, white_ratio) 返回: (is_blank, white_ratio)
""" """
img = Image.open(image_path).convert("L") img = Image.open(image_path).convert("L")
pixels = list(img.getdata()) arr = np.array(img)
total = len(pixels) white_ratio = float(np.mean(arr > BLANK_FRAME_BRIGHTNESS_THRESHOLD))
white_count = sum(1 for p in pixels if p > BLANK_FRAME_BRIGHTNESS_THRESHOLD)
white_ratio = white_count / total if total > 0 else 0
is_blank = white_ratio < BLANK_FRAME_WHITE_PIXEL_RATIO is_blank = white_ratio < BLANK_FRAME_WHITE_PIXEL_RATIO
if debug: if debug:
frame_idx = image_path.stem # e.g. "frame_0226" frame_idx = image_path.stem
print(f"[debug] {frame_idx}, white_ratio={white_ratio:.6f}, is_blank={is_blank}") print(f"[debug] {frame_idx}, white_ratio={white_ratio:.6f}, is_blank={is_blank}")
return is_blank, white_ratio return is_blank, white_ratio
@@ -226,39 +225,25 @@ def hamming_distance(s1: str, s2: str) -> int:
return sum(c1 != c2 for c1, c2 in zip(s1, s2)) return sum(c1 != c2 for c1, c2 in zip(s1, s2))
def compute_binary_matrix(image_path: Path, threshold: int = 200) -> List[List[int]]: def compute_binary_matrix(image_path: Path, threshold: int = 200) -> np.ndarray:
""" """
将图片转为二值化矩阵(亮度 > threshold → 1,否则 → 0) 将图片转为二值化矩阵(亮度 > threshold → 1,否则 → 0)
用于 IoU 对比 用于 IoU 对比
返回: np.ndarray (dtype=uint8, 值为 0 或 1)
""" """
img = Image.open(image_path).convert("L") img = Image.open(image_path).convert("L")
w, h = img.size arr = np.array(img)
matrix = [] return (arr > threshold).astype(np.uint8)
for y in range(h):
row = []
for x in range(w):
pixel = img.getpixel((x, y))
row.append(1 if pixel > threshold else 0)
matrix.append(row)
return matrix
def compute_iou(matrix1: List[List[int]], matrix2: List[List[int]]) -> float: def compute_iou(matrix1: np.ndarray, matrix2: np.ndarray) -> float:
""" """
计算两个二值化矩阵的 IoU(交并比) 计算两个二值化矩阵的 IoU(交并比)
matrix1, matrix2: np.ndarray (dtype=uint8, 值为 0 或 1)
""" """
h = len(matrix1) intersection = int(np.sum((matrix1 == 1) & (matrix2 == 1)))
w = len(matrix1[0]) if h > 0 else 0 union = int(np.sum((matrix1 == 1) | (matrix2 == 1)))
intersection = 0
union = 0
for y in range(h):
for x in range(w):
v1 = matrix1[y][x]
v2 = matrix2[y][x]
if v1 == 1 or v2 == 1:
union += 1
if v1 == 1 and v2 == 1:
intersection += 1
return intersection / union if union > 0 else 1.0 return intersection / union if union > 0 else 1.0