Baseline
This commit is contained in:
4724
PreProcessing/.matplotlib-cache/fontlist-v390.json
Normal file
4724
PreProcessing/.matplotlib-cache/fontlist-v390.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
PreProcessing/comparisons/篆文字_page_017_text_17_comparison.png
Normal file
BIN
PreProcessing/comparisons/篆文字_page_017_text_17_comparison.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
BIN
PreProcessing/original_characters/篆文字_page_017_text_17.png
Normal file
BIN
PreProcessing/original_characters/篆文字_page_017_text_17.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
Binary file not shown.
264
PreProcessing/scripts/process_characters.py
Normal file
264
PreProcessing/scripts/process_characters.py
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import html
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
|
||||||
|
os.environ.setdefault(
|
||||||
|
"MPLCONFIGDIR",
|
||||||
|
str(Path(__file__).resolve().parents[1] / ".matplotlib-cache"),
|
||||||
|
)
|
||||||
|
|
||||||
|
import matplotlib
|
||||||
|
|
||||||
|
matplotlib.use("Agg")
|
||||||
|
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
IMAGE_SUFFIXES = {".png", ".jpg", ".jpeg", ".tif", ".tiff", ".bmp", ".webp"}
|
||||||
|
|
||||||
|
|
||||||
|
def read_image(path: Path) -> np.ndarray:
|
||||||
|
raw = np.fromfile(str(path), dtype=np.uint8)
|
||||||
|
image = cv2.imdecode(raw, cv2.IMREAD_COLOR)
|
||||||
|
if image is None:
|
||||||
|
raise ValueError(f"Cannot read image: {path}")
|
||||||
|
return image
|
||||||
|
|
||||||
|
|
||||||
|
def write_image(path: Path, image: np.ndarray) -> None:
|
||||||
|
ok, encoded = cv2.imencode(path.suffix, image)
|
||||||
|
if not ok:
|
||||||
|
raise ValueError(f"Cannot encode image: {path}")
|
||||||
|
encoded.tofile(str(path))
|
||||||
|
|
||||||
|
|
||||||
|
def binarize_foreground(gray: np.ndarray) -> np.ndarray:
|
||||||
|
blurred = cv2.GaussianBlur(gray, (3, 3), 0)
|
||||||
|
threshold, _ = cv2.threshold(
|
||||||
|
blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU
|
||||||
|
)
|
||||||
|
|
||||||
|
border = np.concatenate(
|
||||||
|
[
|
||||||
|
gray[0, :],
|
||||||
|
gray[-1, :],
|
||||||
|
gray[:, 0],
|
||||||
|
gray[:, -1],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
background_is_light = np.median(border) >= 128
|
||||||
|
|
||||||
|
if background_is_light:
|
||||||
|
foreground = (gray < threshold).astype(np.uint8) * 255
|
||||||
|
else:
|
||||||
|
foreground = (gray > threshold).astype(np.uint8) * 255
|
||||||
|
|
||||||
|
return foreground
|
||||||
|
|
||||||
|
|
||||||
|
def clean_mask(
|
||||||
|
mask: np.ndarray,
|
||||||
|
open_kernel_size: int,
|
||||||
|
close_kernel_size: int,
|
||||||
|
median_size: int,
|
||||||
|
) -> np.ndarray:
|
||||||
|
if median_size > 1:
|
||||||
|
if median_size % 2 == 0:
|
||||||
|
median_size += 1
|
||||||
|
mask = cv2.medianBlur(mask, median_size)
|
||||||
|
|
||||||
|
open_kernel = cv2.getStructuringElement(
|
||||||
|
cv2.MORPH_RECT, (open_kernel_size, open_kernel_size)
|
||||||
|
)
|
||||||
|
opened = cv2.morphologyEx(mask, cv2.MORPH_OPEN, open_kernel)
|
||||||
|
|
||||||
|
close_kernel = cv2.getStructuringElement(
|
||||||
|
cv2.MORPH_RECT, (close_kernel_size, close_kernel_size)
|
||||||
|
)
|
||||||
|
return cv2.morphologyEx(opened, cv2.MORPH_CLOSE, close_kernel)
|
||||||
|
|
||||||
|
|
||||||
|
def pixelate(mask: np.ndarray, factor: int) -> tuple[np.ndarray, np.ndarray]:
|
||||||
|
height, width = mask.shape
|
||||||
|
small_width = max(1, round(width / factor))
|
||||||
|
small_height = max(1, round(height / factor))
|
||||||
|
sampled = cv2.resize(
|
||||||
|
mask, (small_width, small_height), interpolation=cv2.INTER_AREA
|
||||||
|
)
|
||||||
|
small = np.where(sampled >= 96, 255, 0).astype(np.uint8)
|
||||||
|
large = cv2.resize(small, (width, height), interpolation=cv2.INTER_NEAREST)
|
||||||
|
return small, large
|
||||||
|
|
||||||
|
|
||||||
|
def mask_to_display(mask: np.ndarray) -> np.ndarray:
|
||||||
|
return np.where(mask > 0, 0, 255).astype(np.uint8)
|
||||||
|
|
||||||
|
|
||||||
|
def save_comparison(
|
||||||
|
path: Path,
|
||||||
|
original_bgr: np.ndarray,
|
||||||
|
cleaned_mask: np.ndarray,
|
||||||
|
pixelated_mask: np.ndarray,
|
||||||
|
) -> None:
|
||||||
|
original_rgb = cv2.cvtColor(original_bgr, cv2.COLOR_BGR2RGB)
|
||||||
|
cleaned = mask_to_display(cleaned_mask)
|
||||||
|
pixelated = mask_to_display(pixelated_mask)
|
||||||
|
|
||||||
|
fig, axes = plt.subplots(1, 3, figsize=(12, 4), constrained_layout=True)
|
||||||
|
panels = [
|
||||||
|
("Original", original_rgb, None),
|
||||||
|
("Cleaned binary", cleaned, "gray"),
|
||||||
|
("Pixelated", pixelated, "gray"),
|
||||||
|
]
|
||||||
|
|
||||||
|
for axis, (title, image, cmap) in zip(axes, panels):
|
||||||
|
axis.imshow(image, cmap=cmap)
|
||||||
|
axis.set_title(title)
|
||||||
|
axis.axis("off")
|
||||||
|
|
||||||
|
fig.savefig(path, dpi=180)
|
||||||
|
plt.close(fig)
|
||||||
|
|
||||||
|
|
||||||
|
def small_matrix_to_svg(
|
||||||
|
small_mask: np.ndarray,
|
||||||
|
original_width: int,
|
||||||
|
original_height: int,
|
||||||
|
title: str,
|
||||||
|
) -> str:
|
||||||
|
rows, cols = small_mask.shape
|
||||||
|
cell_width = original_width / cols
|
||||||
|
cell_height = original_height / rows
|
||||||
|
escaped_title = html.escape(title)
|
||||||
|
parts = [
|
||||||
|
'<?xml version="1.0" encoding="UTF-8"?>',
|
||||||
|
(
|
||||||
|
f'<svg xmlns="http://www.w3.org/2000/svg" '
|
||||||
|
f'width="{original_width}" height="{original_height}" '
|
||||||
|
f'viewBox="0 0 {original_width} {original_height}" '
|
||||||
|
f'shape-rendering="crispEdges">'
|
||||||
|
),
|
||||||
|
f" <title>{escaped_title}</title>",
|
||||||
|
' <rect width="100%" height="100%" fill="white"/>',
|
||||||
|
' <g fill="black">',
|
||||||
|
]
|
||||||
|
|
||||||
|
for row_index in range(rows):
|
||||||
|
col_index = 0
|
||||||
|
while col_index < cols:
|
||||||
|
if small_mask[row_index, col_index] == 0:
|
||||||
|
col_index += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
run_start = col_index
|
||||||
|
while col_index < cols and small_mask[row_index, col_index] > 0:
|
||||||
|
col_index += 1
|
||||||
|
|
||||||
|
x = run_start * cell_width
|
||||||
|
y = row_index * cell_height
|
||||||
|
width = (col_index - run_start) * cell_width
|
||||||
|
parts.append(
|
||||||
|
f' <rect x="{x:.4f}" y="{y:.4f}" '
|
||||||
|
f'width="{width:.4f}" height="{cell_height:.4f}"/>'
|
||||||
|
)
|
||||||
|
|
||||||
|
parts.extend([" </g>", "</svg>", ""])
|
||||||
|
return "\n".join(parts)
|
||||||
|
|
||||||
|
|
||||||
|
def process_image(
|
||||||
|
image_path: Path,
|
||||||
|
processed_dir: Path,
|
||||||
|
comparison_dir: Path,
|
||||||
|
svg_dir: Path,
|
||||||
|
factor: int,
|
||||||
|
open_kernel_size: int,
|
||||||
|
close_kernel_size: int,
|
||||||
|
median_size: int,
|
||||||
|
) -> None:
|
||||||
|
original = read_image(image_path)
|
||||||
|
gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)
|
||||||
|
binary = binarize_foreground(gray)
|
||||||
|
cleaned = clean_mask(
|
||||||
|
binary,
|
||||||
|
open_kernel_size=open_kernel_size,
|
||||||
|
close_kernel_size=close_kernel_size,
|
||||||
|
median_size=median_size,
|
||||||
|
)
|
||||||
|
small, pixelated = pixelate(cleaned, factor=factor)
|
||||||
|
|
||||||
|
stem = image_path.stem
|
||||||
|
write_image(processed_dir / f"{stem}_cleaned.png", mask_to_display(cleaned))
|
||||||
|
write_image(processed_dir / f"{stem}_pixelated.png", mask_to_display(pixelated))
|
||||||
|
save_comparison(
|
||||||
|
comparison_dir / f"{stem}_comparison.png", original, cleaned, pixelated
|
||||||
|
)
|
||||||
|
|
||||||
|
height, width = gray.shape
|
||||||
|
svg = small_matrix_to_svg(small, width, height, stem)
|
||||||
|
(svg_dir / f"{stem}_pixelated.svg").write_text(svg, encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Clean, pixelate, and vectorize scanned seal-script characters."
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--input-dir",
|
||||||
|
type=Path,
|
||||||
|
default=Path("PreProcessing/original_characters"),
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--processed-dir",
|
||||||
|
type=Path,
|
||||||
|
default=Path("PreProcessing/processed_characters"),
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--comparison-dir",
|
||||||
|
type=Path,
|
||||||
|
default=Path("PreProcessing/comparisons"),
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--svg-dir",
|
||||||
|
type=Path,
|
||||||
|
default=Path("PreProcessing/svg_characters"),
|
||||||
|
)
|
||||||
|
parser.add_argument("--factor", type=int, default=15)
|
||||||
|
parser.add_argument("--open-kernel-size", type=int, default=2)
|
||||||
|
parser.add_argument("--close-kernel-size", type=int, default=3)
|
||||||
|
parser.add_argument("--median-size", type=int, default=5)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
for directory in (args.processed_dir, args.comparison_dir, args.svg_dir):
|
||||||
|
directory.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
images = sorted(
|
||||||
|
path
|
||||||
|
for path in args.input_dir.iterdir()
|
||||||
|
if path.is_file() and path.suffix.lower() in IMAGE_SUFFIXES
|
||||||
|
)
|
||||||
|
if not images:
|
||||||
|
raise SystemExit(f"No images found in {args.input_dir}")
|
||||||
|
|
||||||
|
for image_path in images:
|
||||||
|
process_image(
|
||||||
|
image_path=image_path,
|
||||||
|
processed_dir=args.processed_dir,
|
||||||
|
comparison_dir=args.comparison_dir,
|
||||||
|
svg_dir=args.svg_dir,
|
||||||
|
factor=args.factor,
|
||||||
|
open_kernel_size=args.open_kernel_size,
|
||||||
|
close_kernel_size=args.close_kernel_size,
|
||||||
|
median_size=args.median_size,
|
||||||
|
)
|
||||||
|
print(f"processed: {image_path.name}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
3
PreProcessing/scripts/requirements.txt
Normal file
3
PreProcessing/scripts/requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
opencv-python-headless
|
||||||
|
numpy
|
||||||
|
matplotlib
|
||||||
143
PreProcessing/svg_characters/篆文字_page_017_text_17_pixelated.svg
Normal file
143
PreProcessing/svg_characters/篆文字_page_017_text_17_pixelated.svg
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="706" height="667" viewBox="0 0 706 667" shape-rendering="crispEdges">
|
||||||
|
<title>篆文字_page_017_text_17</title>
|
||||||
|
<rect width="100%" height="100%" fill="white"/>
|
||||||
|
<g fill="black">
|
||||||
|
<rect x="45.0638" y="30.3182" width="15.0213" height="15.1591"/>
|
||||||
|
<rect x="165.2340" y="30.3182" width="15.0213" height="15.1591"/>
|
||||||
|
<rect x="390.5532" y="30.3182" width="285.4043" height="15.1591"/>
|
||||||
|
<rect x="45.0638" y="45.4773" width="300.4255" height="15.1591"/>
|
||||||
|
<rect x="390.5532" y="45.4773" width="285.4043" height="15.1591"/>
|
||||||
|
<rect x="45.0638" y="60.6364" width="285.4043" height="15.1591"/>
|
||||||
|
<rect x="390.5532" y="60.6364" width="15.0213" height="15.1591"/>
|
||||||
|
<rect x="630.8936" y="60.6364" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="45.0638" y="75.7955" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="630.8936" y="75.7955" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="45.0638" y="90.9545" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="510.7234" y="90.9545" width="165.2340" height="15.1591"/>
|
||||||
|
<rect x="45.0638" y="106.1136" width="300.4255" height="15.1591"/>
|
||||||
|
<rect x="390.5532" y="106.1136" width="285.4043" height="15.1591"/>
|
||||||
|
<rect x="45.0638" y="121.2727" width="300.4255" height="15.1591"/>
|
||||||
|
<rect x="390.5532" y="121.2727" width="240.3404" height="15.1591"/>
|
||||||
|
<rect x="645.9149" y="121.2727" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="136.4318" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="300.4255" y="136.4318" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="390.5532" y="136.4318" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="480.6809" y="136.4318" width="15.0213" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="151.5909" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="300.4255" y="151.5909" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="151.5909" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="166.7500" width="315.4468" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="166.7500" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="465.6596" y="166.7500" width="210.2979" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="181.9091" width="300.4255" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="181.9091" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="450.6383" y="181.9091" width="225.3191" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="197.0682" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="90.1277" y="197.0682" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="210.2979" y="197.0682" width="60.0851" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="197.0682" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="450.6383" y="197.0682" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="630.8936" y="197.0682" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="212.2273" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="212.2273" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="450.6383" y="212.2273" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="630.8936" y="212.2273" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="227.3864" width="75.1064" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="227.3864" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="450.6383" y="227.3864" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="630.8936" y="227.3864" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="242.5455" width="300.4255" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="242.5455" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="450.6383" y="242.5455" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="525.7447" y="242.5455" width="150.2128" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="257.7045" width="300.4255" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="257.7045" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="450.6383" y="257.7045" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="525.7447" y="257.7045" width="150.2128" height="15.1591"/>
|
||||||
|
<rect x="300.4255" y="272.8636" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="272.8636" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="450.6383" y="272.8636" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="300.4255" y="288.0227" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="288.0227" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="450.6383" y="288.0227" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="303.1818" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="300.4255" y="303.1818" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="303.1818" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="450.6383" y="303.1818" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="510.7234" y="303.1818" width="165.2340" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="318.3409" width="300.4255" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="318.3409" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="450.6383" y="318.3409" width="225.3191" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="333.5000" width="255.3617" height="15.1591"/>
|
||||||
|
<rect x="315.4468" y="333.5000" width="15.0213" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="333.5000" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="450.6383" y="333.5000" width="165.2340" height="15.1591"/>
|
||||||
|
<rect x="630.8936" y="333.5000" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="348.6591" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="348.6591" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="630.8936" y="348.6591" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="363.8182" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="363.8182" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="630.8936" y="363.8182" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="378.9773" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="90.1277" y="378.9773" width="15.0213" height="15.1591"/>
|
||||||
|
<rect x="300.4255" y="378.9773" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="378.9773" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="540.7660" y="378.9773" width="135.1915" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="394.1364" width="300.4255" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="394.1364" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="450.6383" y="394.1364" width="225.3191" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="409.2955" width="300.4255" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="409.2955" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="450.6383" y="409.2955" width="120.1702" height="15.1591"/>
|
||||||
|
<rect x="285.4043" y="424.4545" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="424.4545" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="465.6596" y="424.4545" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="285.4043" y="439.6136" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="439.6136" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="465.6596" y="439.6136" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="454.7727" width="300.4255" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="454.7727" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="465.6596" y="454.7727" width="210.2979" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="469.9318" width="300.4255" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="469.9318" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="465.6596" y="469.9318" width="210.2979" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="485.0909" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="150.2128" y="485.0909" width="120.1702" height="15.1591"/>
|
||||||
|
<rect x="285.4043" y="485.0909" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="360.5106" y="485.0909" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="465.6596" y="485.0909" width="210.2979" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="500.2500" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="500.2500" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="630.8936" y="500.2500" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="515.4091" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="375.5319" y="515.4091" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="645.9149" y="515.4091" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="530.5682" width="285.4043" height="15.1591"/>
|
||||||
|
<rect x="360.5106" y="530.5682" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="465.6596" y="530.5682" width="210.2979" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="545.7273" width="300.4255" height="15.1591"/>
|
||||||
|
<rect x="360.5106" y="545.7273" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="465.6596" y="545.7273" width="210.2979" height="15.1591"/>
|
||||||
|
<rect x="150.2128" y="560.8864" width="15.0213" height="15.1591"/>
|
||||||
|
<rect x="225.3191" y="560.8864" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="270.3830" y="560.8864" width="60.0851" height="15.1591"/>
|
||||||
|
<rect x="360.5106" y="560.8864" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="465.6596" y="560.8864" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="285.4043" y="576.0455" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="360.5106" y="576.0455" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="465.6596" y="576.0455" width="30.0426" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="591.2045" width="15.0213" height="15.1591"/>
|
||||||
|
<rect x="90.1277" y="591.2045" width="60.0851" height="15.1591"/>
|
||||||
|
<rect x="165.2340" y="591.2045" width="165.2340" height="15.1591"/>
|
||||||
|
<rect x="360.5106" y="591.2045" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="450.6383" y="591.2045" width="225.3191" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="606.3636" width="300.4255" height="15.1591"/>
|
||||||
|
<rect x="360.5106" y="606.3636" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="450.6383" y="606.3636" width="225.3191" height="15.1591"/>
|
||||||
|
<rect x="30.0426" y="621.5227" width="285.4043" height="15.1591"/>
|
||||||
|
<rect x="360.5106" y="621.5227" width="45.0638" height="15.1591"/>
|
||||||
|
<rect x="450.6383" y="621.5227" width="225.3191" height="15.1591"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 9.7 KiB |
Reference in New Issue
Block a user