Aruco Spiegeln

This commit is contained in:
chk
2026-05-30 16:38:41 +02:00
parent 50baeae449
commit 36b68b240d
8 changed files with 1942 additions and 909 deletions

View File

@@ -9,6 +9,7 @@ from typing import List, Tuple
from reportlab.pdfgen import canvas
from reportlab.lib.units import mm
from reportlab.pdfbase import pdfmetrics
try:
import cv2
@@ -27,7 +28,7 @@ ORIENTATION = "portrait" # "portrait" oder "landscape"
NUM_ARUCOS = 60
ARUCO_SIZE_MM = 25.0
ARUCO_START_ID = 103 # erster Marker aus DICT_4X4_250
ARUCO_START_ID = 46 # erster Marker aus DICT_4X4_250
SEED = 223 # Zufalls-Seed für reproduzierbare Verteilung
PAGE_BORDER_MARGIN_MM = 50.0 # Abstand aller Marker vom Seitenrand
@@ -37,6 +38,9 @@ FORBIDDEN_RECT_H_MM = 1000.0
FORBIDDEN_RECT_MARGIN_MM = 30.0 # keine ArUcos innerhalb dieses Abstands
LINE_WIDTH_MM = 1.0 # Linienstärke des Rechtecks
TEXT_FONT = "Times-Roman"
TEXT_SIZE_PT = 8
TEXT_GAP_MM = 4.0
OUTPUT_BASENAME = f"A0_{NUM_ARUCOS}Arucos_{int(ARUCO_SIZE_MM)}mm_Seet{SEED}"
@@ -151,7 +155,8 @@ def draw_aruco_vector(
for col in range(modules):
if pattern[r][col] == 1:
cell_x_mm = x_mm + col * cell_mm
cell_y_mm = y_mm + (modules - 1 - r) * cell_mm
#cell_y_mm = y_mm + (modules - 1 - r) * cell_mm
cell_y_mm = y_mm + r * cell_mm
c.rect(
mm_to_pt(cell_x_mm),
mm_to_pt(page_h_mm - cell_y_mm - cell_mm),
@@ -162,6 +167,24 @@ def draw_aruco_vector(
)
def draw_aruco_label(
c: canvas.Canvas,
x_mm: float,
y_mm: float,
size_mm: float,
page_h_mm: float,
marker_id: int,
) -> None:
c.setFont(TEXT_FONT, TEXT_SIZE_PT)
text = str(marker_id)
text_width_pt = pdfmetrics.stringWidth(text, TEXT_FONT, TEXT_SIZE_PT)
text_x_pt = mm_to_pt(x_mm + size_mm / 2.0) - text_width_pt / 2.0
font = pdfmetrics.getFont(TEXT_FONT)
ascent_mm = (font.face.ascent / 1000.0) * TEXT_SIZE_PT * 0.352777777777778
text_baseline_y_mm = y_mm + size_mm + TEXT_GAP_MM + ascent_mm
c.drawString(text_x_pt, mm_to_pt(page_h_mm - text_baseline_y_mm), text)
def place_markers(
page_w_mm: float,
page_h_mm: float,
@@ -295,27 +318,27 @@ def main() -> None:
mm_to_pt(page_h_mm - (origin_y_mm + ARROW_LEN_MM - 4)),
)
# Y-Achse (grün, nach links)
# Y-Achse (grün, nach rechts)
c.setStrokeColorRGB(0, 0.7, 0)
c.line(
mm_to_pt(origin_x_mm),
mm_to_pt(page_h_mm - origin_y_mm),
mm_to_pt(origin_x_mm - ARROW_LEN_MM),
mm_to_pt(origin_x_mm + ARROW_LEN_MM),
mm_to_pt(page_h_mm - origin_y_mm),
)
# Pfeilspitze
c.line(
mm_to_pt(origin_x_mm - ARROW_LEN_MM),
mm_to_pt(origin_x_mm + ARROW_LEN_MM),
mm_to_pt(page_h_mm - origin_y_mm),
mm_to_pt(origin_x_mm - ARROW_LEN_MM + 4),
mm_to_pt(origin_x_mm + ARROW_LEN_MM - 4),
mm_to_pt(page_h_mm - origin_y_mm - 4),
)
c.line(
mm_to_pt(origin_x_mm - ARROW_LEN_MM),
mm_to_pt(origin_x_mm + ARROW_LEN_MM),
mm_to_pt(page_h_mm - origin_y_mm),
mm_to_pt(origin_x_mm - ARROW_LEN_MM + 4),
mm_to_pt(origin_x_mm + ARROW_LEN_MM - 4),
mm_to_pt(page_h_mm - origin_y_mm + 4),
)
@@ -332,39 +355,59 @@ def main() -> None:
marker_id=item["id"],
page_h_mm=page_h_mm,
)
draw_aruco_label(
c=c,
x_mm=item["x_mm"],
y_mm=item["y_mm"],
size_mm=item["size_mm"],
page_h_mm=page_h_mm,
marker_id=item["id"],
)
c.showPage()
c.save()
# JSON mit Positionen
with json_path.open("w", encoding="utf-8") as f:
json.dump(
{
"page_format": PAGE_FORMAT,
"orientation": ORIENTATION,
"page_size_mm": {"width": page_w_mm, "height": page_h_mm},
"seed": SEED,
"num_arucos": NUM_ARUCOS,
"aruco_size_mm": ARUCO_SIZE_MM,
"aruco_dictionary": "DICT_4X4_250",
"aruco_start_id": ARUCO_START_ID,
"page_border_margin_mm": PAGE_BORDER_MARGIN_MM,
"forbidden_rectangle_mm": {
"x": round(forbidden_rect.x, 2),
"y": round(forbidden_rect.y, 2),
"w": forbidden_rect.w,
"h": forbidden_rect.h,
},
"forbidden_rectangle_margin_mm": FORBIDDEN_RECT_MARGIN_MM,
"placements": [
{"id": p["id"],"position": [-1*round((p["y_mm"] + ARUCO_SIZE_MM / 2) - origin_y_mm, 2), round(origin_x_mm - (p["x_mm"] + ARUCO_SIZE_MM / 2), 2),-19],"normal": [0, 0, 1],"spin": 90}
for p in placements
],
meta = {
"page_format": PAGE_FORMAT,
"orientation": ORIENTATION,
"page_size_mm": {"width": page_w_mm, "height": page_h_mm},
"seed": SEED,
"num_arucos": NUM_ARUCOS,
"aruco_size_mm": ARUCO_SIZE_MM,
"aruco_dictionary": "DICT_4X4_250",
"aruco_start_id": ARUCO_START_ID,
"page_border_margin_mm": PAGE_BORDER_MARGIN_MM,
"forbidden_rectangle_mm": {
"x": round(forbidden_rect.x, 2),
"y": round(forbidden_rect.y, 2),
"w": forbidden_rect.w,
"h": forbidden_rect.h,
},
f,
indent=2,
ensure_ascii=False,
)
"forbidden_rectangle_margin_mm": FORBIDDEN_RECT_MARGIN_MM,
}
f.write(json.dumps(meta, indent=2, ensure_ascii=False)[:-2])
f.write(',\n "placements": [\n')
for index, p in enumerate(placements):
item = {
"id": p["id"],
"position": [
round((p["y_mm"] + ARUCO_SIZE_MM / 2) - origin_y_mm, 2),
-1*round(origin_x_mm - (p["x_mm"] + ARUCO_SIZE_MM / 2), 2),
-27.3,
],
"normal": [0, 0, 1],
"spin": 90,
}
line = json.dumps(item, ensure_ascii=False)
if index < len(placements) - 1:
line += ","
f.write(f" {line}\n")
f.write(" ]\n}\n")
print(f"PDF geschrieben: {pdf_path.resolve()}")
print(f"JSON geschrieben: {json_path.resolve()}")