Scan-Pfad entschlacken, Container-Limits setzen
Drei Änderungen, die den Spitzenverbrauch eines Stapelscans senken: - Zuschnitte werden nicht mehr auf 1400 px hochgerechnet. Auf einem Stapelfoto ist eine Karte nur ein paar hundert Pixel breit; sie aufzublasen erzeugt vier Mal so viele Pixel ohne mehr Information und kostet zusätzlich Bildtokens beim Modellaufruf. OUT_WIDTH ist jetzt eine Obergrenze. - Die um 180 Grad gedrehte Fassung entsteht erst, wenn ein Ergebnis leer bleibt, statt für jede Karte auf Vorrat. Das halbiert die JPEG-Kodierungen im Normalfall. - Zuschnitte werden einzeln kodiert und sofort freigegeben, statt gesammelt im Speicher zu liegen. Dazu mem_limit und cpus für den App-Container: ein Ausreißer soll den Container treffen, nicht den Host, auf dem auch Jitsi und MySQL laufen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,8 @@ import numpy as np
|
||||
CARD_RATIO = 85.6 / 54.0
|
||||
RATIO_MIN, RATIO_MAX = 1.25, 2.05
|
||||
|
||||
OUT_WIDTH = 1400
|
||||
OUT_WIDTH = 1400 # Obergrenze; kleinere Karten werden nicht hochskaliert
|
||||
MIN_WIDTH = 600
|
||||
OUT_HEIGHT = round(OUT_WIDTH / CARD_RATIO)
|
||||
|
||||
DETECT_EDGE = 1600 # Aufloesung, auf der gesucht wird
|
||||
@@ -129,19 +130,32 @@ def segment(image: np.ndarray) -> tuple[list[np.ndarray], bool]:
|
||||
crops = []
|
||||
for rect in _reading_order(rects):
|
||||
quad = _order_quad(cv2.boxPoints(rect)) / scale # zurueck auf volle Aufloesung
|
||||
width, height = _target_size(quad)
|
||||
target = np.array(
|
||||
[[0, 0], [OUT_WIDTH, 0], [OUT_WIDTH, OUT_HEIGHT], [0, OUT_HEIGHT]],
|
||||
dtype="float32",
|
||||
[[0, 0], [width, 0], [width, height], [0, height]], dtype="float32"
|
||||
)
|
||||
matrix = cv2.getPerspectiveTransform(quad, target)
|
||||
crops.append(
|
||||
cv2.warpPerspective(
|
||||
image, matrix, (OUT_WIDTH, OUT_HEIGHT), flags=cv2.INTER_CUBIC
|
||||
)
|
||||
cv2.warpPerspective(image, matrix, (width, height), flags=cv2.INTER_CUBIC)
|
||||
)
|
||||
return crops, False
|
||||
|
||||
|
||||
def _target_size(quad: np.ndarray) -> tuple:
|
||||
"""Zuschnitt so gross wie die Vorlage, hoechstens OUT_WIDTH.
|
||||
|
||||
Auf einem Stapelfoto ist eine Karte nur ein paar hundert Pixel breit.
|
||||
Sie auf 1400 hochzurechnen erzeugt vier Mal so viele Pixel ohne ein
|
||||
Quentchen mehr Information - und kostet Speicher, Bildgroesse und
|
||||
Bildtokens beim Modellaufruf.
|
||||
"""
|
||||
long_edge = max(
|
||||
np.linalg.norm(quad[1] - quad[0]), np.linalg.norm(quad[2] - quad[3])
|
||||
)
|
||||
width = int(min(OUT_WIDTH, max(MIN_WIDTH, round(long_edge))))
|
||||
return width, round(width / CARD_RATIO)
|
||||
|
||||
|
||||
def _fit_whole(image: np.ndarray) -> np.ndarray:
|
||||
"""Ohne Fund: das ganze Bild als eine Karte behandeln."""
|
||||
height, width = image.shape[:2]
|
||||
|
||||
Reference in New Issue
Block a user