рд╕реНрдХреИрдирд░ рдРрдк рдлрд╝реЛрди рдХреА рдлрд╝реЛрдЯреЛ рдХреЗ рд╕рд╛рде рддреАрди рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ: рдХрд╛рдЧрд╝рдЬрд╝ рдХреЛ рдвреВрдБрдврддрд╛ рд╣реИ, рдЙрд╕рдХреЗ рдЪрд╛рд░реЛрдВ рдХреЛрдиреЛрдВ рдХреЛ рдЦреАрдВрдЪрдХрд░ рдЖрдпрдд рдмрдирд╛рддрд╛ рд╣реИ, рдФрд░ рдирддреАрдЬреЗ рдХреЛ рд╕реНрдпрд╛рд╣реА рдФрд░ рдХрд╛рдЧрд╝рдЬрд╝ рдореЗрдВ рдмрд╛рдБрдЯ рджреЗрддрд╛ рд╣реИред рдЗрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рдХрд╛рдо рдЕрдиреЛрдЦрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рд░ рдПрдХ рдореЗрдВ рдПрдХ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдБ рд╡рд╣ рдЪреБрдкрдЪрд╛рдк рдЧрд╝рд▓рдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред osFoundry рдбреЗрд╕реНрдХрдЯреЙрдк рдРрдк рдХрд╛ PDF рдПрдбрд┐рдЯрд░ рдпрд╣ рдХрд╛рдо рдЪрд╛рд░ рдХреЛрдиреЗ рд╡рд╛рд▓реЗ рд╣реИрдВрдбрд▓ рдФрд░ рдПрдХ Black and white рдмрдЯрди рд╕реЗ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдкреЛрд╕реНрдЯ рд╡рд╣реА рдкрд╛рдЗрдкрд▓рд╛рдЗрди Python рдФрд░ OpenCV рдореЗрдВ рджреЛрдмрд╛рд░рд╛ рдмрдирд╛рдХрд░ рдЙрд╕реЗ рдирд╛рдкрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЙрд╕реЗ рд╕рдЯреАрдХ рддрд░реАрдХрд╝реЗ рд╕реЗ рдЬрд╛рдБрдЪрдиреЗ рдХрд╛ рдПрдХ рд░рд╛рд╕реНрддрд╛ рд╣реИ: рдлрд╝реЛрдЯреЛ рдореИрдВрдиреЗ рдЦрд╝реБрдж рдмрдирд╛рдИ рд╣реИ, рдЗрд╕рд▓рд┐рдП "рдЫрдкрд╛ рд╣реБрдЖ" рдкрдиреНрдирд╛ рдФрд░ рд╡реЗ рдХреЛрдиреЗ рдЬрд╣рд╛рдБ рдЙрд╕реЗ рд░рдЦрд╛ рдЧрдпрд╛, рджреЛрдиреЛрдВ рдорд╛рд▓реВрдо рд╣реИрдВред
рдЯреЗрд╕реНрдЯ рдлрд╝реЛрдЯреЛ
make_scan.py Pillow рд╕реЗ рдПрдХ рдХрд╛рд▓реНрдкрдирд┐рдХ рдХрд┐рд░рд╛рдпрд╛-рдЕрдиреБрдмрдВрдз рдХрд╛ рдкрд╣рд▓рд╛ рдкрдиреНрдирд╛ рдмрдирд╛рддрд╛ рд╣реИ (Times New Roman, 1275 ├Ч 1650, 150 dpi рдкрд░ Letter), рдФрд░ рдлрд┐рд░ рдЙрд╕рдХреА рдЖрднрд╛рд╕реА рддрд╕реНрд╡реАрд░ рдЦреАрдВрдЪрддрд╛ рд╣реИ: 1500 ├Ч 2000 рдХреЗ рдХреИрдирд╡рд╛рд╕ рдкрд░ рдкрд░реНрд╕рдкреЗрдХреНрдЯрд┐рд╡ рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдо, рд▓рдХрдбрд╝реА рдХреА рдзрд╛рд░рд┐рдпреЛрдВ рд╡рд╛рд▓реА рдореЗрдЬрд╝, рдХрд╛рдЧрд╝рдЬрд╝ рдХреЗ рдиреАрдЪреЗ рд╣рд▓реНрдХреА рдЫрд╛рдпрд╛, рдиреАрдЪреЗ-рджрд╛рдПрдБ рдХреА рдУрд░ рдШрдЯрддреА рдЪрдордХ, рдереЛрдбрд╝рд╛ рд╢реЛрд░ рдФрд░ рдХреНрд╡рд╛рд▓рд┐рдЯреА 82 рдХрд╛ JPEGред рдлрд╝реЛрдЯреЛ рдореЗрдВ 253 рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЧреНрд░реЗ рд▓реЗрд╡рд▓ рд╣реИрдВ, рдФрд░ рдЕрд╕рд▓реА рдХреЛрдиреЗ (212,236) (1318,184) (1392,1652) (150,1748) рд╣реИрдВред
рдиреАрдЪреЗ рд╕рдм рдХреБрдЫ рдЗрд╕ рдХрдорд╛рдВрдб рд╕реЗ рдЪрд▓рддрд╛ рд╣реИ:
uvx --with opencv-python-headless --with numpy --with pillow --with pymupdf python -I measure.py
OpenCV 5.0.0, NumPy 2.5.4, Python 3.12.15, Apple M1 рдкрд░ред рд╕рдордп рдПрдХ-рдПрдХ рдмрд╛рд░ рдХреЗ рд░рди рдХреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рд╕рд┐рд░реНрдлрд╝ рдореЛрдЯреЗ рдЕрдВрджрд╛рдЬрд╝реЗ рдХреА рддрд░рд╣ рдкрдврд╝реЗрдВред
рдЪрд╛рд░реЛрдВ рдХреЛрдиреЗ рдвреВрдБрдврдирд╛
рдХрд╛рдЧрд╝рдЬрд╝ рд╡рд╣ рдмрдбрд╝рд╛ рдЪрдордХреАрд▓рд╛ рдзрдмреНрдмрд╛ рд╣реИред рдлрд╝реЛрдЯреЛ рдХреЛ рдзреБрдВрдзрд▓рд╛ рдХрд░реЗрдВ рддрд╛рдХрд┐ рдЕрдХреНрд╖рд░ рдорд╛рдпрдиреЗ рди рд░рдЦреЗрдВ, Otsu рд╕реЗ рдереНрд░реЗрд╢реЛрд▓реНрдб рдЪреБрдирд╡рд╛рдПрдБ, рдЦрд╝рд╛рд▓реА рдЬрдЧрд╣реЗрдВ рднрд░ рджреЗрдВ, рдФрд░ рд╕рдмрд╕реЗ рдмрдбрд╝рд╛ рдХрдВрдЯреВрд░ рд░рдЦреЗрдВ:
blur = cv2.GaussianBlur(gray, (0, 0), 6)
t, mask = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # t = 144
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, np.ones((25, 25), np.uint8))
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
c = max(contours, key=cv2.contourArea)
hull = cv2.convexHull(c)
approxPolyDP рд╕реЗ рдХреЙрдиреНрд╡реЗрдХреНрд╕ рд╣рд▓ рдХреЛ рдЪрд╛рд░ рдмрд┐рдВрджреБрдУрдВ рдореЗрдВ рд╕рдореЗрдЯрдирд╛ рдЕрдЧрд▓рд╛ рдЖрдо рдХрд╝рджрдо рд╣реИ, рдФрд░ рдкрд╣рд▓рд╛ рдЬрд╛рд▓ рдпрд╣реАрдВ рд╣реИред рдЬрд┐рд╕ epsilon рдкрд░ рдареАрдХ рдЪрд╛рд░ рдмрд┐рдВрджреБ рдорд┐рд▓рддреЗ рд╣реИрдВ рд╡рд╣ рдлрд╝реЛрдЯреЛ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП epsilon рдХреА рдПрдХ рд░реЗрдВрдЬ рдореЗрдВ рдШреВрдореЗрдВ рдФрд░ рдЬреЛ рдкрд╣рд▓рд╛ рдЪрд╛рд░ рд▓реМрдЯрд╛рдП рдЙрд╕реЗ рд▓реЗрдВред рдлрд┐рд░ рднреА рдХреЛрдиреЗ рд╕рд┐рд░реНрдлрд╝ рдЕрдВрджрд╛рдЬрд╝рди рд╕рд╣реА рд╣реЛрддреЗ рд╣реИрдВред рдЕрд╕рд▓реА рдХреЛрдиреЛрдВ рдХреЗ рдореБрдХрд╝рд╛рдмрд▓реЗ approxPolyDP рдХреЗ рдЪрд╛рд░реЛрдВ рдмрд┐рдВрджреБ 3.0, 5.7, 9.9 рдФрд░ 6.4 px рджреВрд░ рдереЗ (рдКрдкрд░-рдмрд╛рдПрдБ, рдКрдкрд░-рджрд╛рдПрдБ, рдиреАрдЪреЗ-рджрд╛рдПрдБ, рдиреАрдЪреЗ-рдмрд╛рдПрдБ)ред 1500 px рдЪреМрдбрд╝рд╛рдИ рдореЗрдВ рдпрд╣ рдЬрд╝реНрдпрд╛рджрд╛ рдирд╣реАрдВ рд▓рдЧрддрд╛, рд▓реЗрдХрд┐рди рд╡рд╛рд░реНрдк рдХреЗ рдмрд╛рдж рддреНрд░реБрдЯрд┐ рд╕реНрдХреЗрд▓ рдлрд╝реИрдХреНрдЯрд░ рд╕реЗ рдмрдврд╝ рдЬрд╛рддреА рд╣реИ, рдФрд░ рдХреБрдЫ рдкрд┐рдХреНрд╕реЗрд▓ рдореЛрдЯреЗ рдЕрдХреНрд╖рд░ рдЙрд╕рдХреЗ рдкреНрд░рддрд┐ рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рд╣реЛрддреЗ рд╣реИрдВред
рдмреЗрд╣рддрд░ рдХреЛрдирд╛ рд╡рд╣ рд╣реИ рдЬреЛ рджреЛ рдЕрдЪреНрдЫреА рддрд░рд╣ рдлрд╝рд┐рдЯ рдХрд┐рдП рдЧрдП рдХрд┐рдирд╛рд░реЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдЪреНрдЫреЗрджрди рд╣реЛред рдореЛрдЯреЗ рдЪрддреБрд░реНрднреБрдЬ рдХреА рд╣рд░ рднреБрдЬрд╛ рдХреЗ рдкрд╛рд╕ рдХреЗ рдХрдВрдЯреВрд░ рдмрд┐рдВрджреБ рд▓реЗрдВ, рдордЬрд╝рдмреВрдд рд▓реЙрд╕ рдХреЗ рд╕рд╛рде рдЙрди рдкрд░ рд░реЗрдЦрд╛ рдлрд╝рд┐рдЯ рдХрд░реЗрдВ рддрд╛рдХрд┐ рдХреБрдЫ рднрдЯрдХреЗ рд╣реБрдП рдмрд┐рдВрджреБ рдЙрд╕реЗ рдЭреБрдХрд╛ рди рджреЗрдВ, рдФрд░ рдкрд╛рд╕-рдкрд╛рд╕ рдХреА рд░реЗрдЦрд╛рдУрдВ рдХреЛ рдХрд╛рдЯреЗрдВ:
def refine(q, pts):
lines = []
for i in range(4):
a, b = q[i], q[(i + 1) % 4]
e = (b - a) / np.linalg.norm(b - a); n = np.array([-e[1], e[0]])
along = (pts - a) @ e; dist = np.abs((pts - a) @ n); L = np.linalg.norm(b - a)
sel = pts[(dist < 12) & (along > 0.08 * L) & (along < 0.92 * L)] # skip the corners themselves
vx, vy, x0, y0 = cv2.fitLine(sel, cv2.DIST_HUBER, 0, 0.01, 0.01).ravel()
lines.append((np.array([x0, y0]), np.array([vx, vy])))
out = []
for i in range(4):
(p1, d1), (p2, d2) = lines[i - 1], lines[i]
t = np.linalg.solve(np.array([d1, -d2]).T, p2 - p1)[0]
out.append(p1 + t * d1)
return np.array(out, np.float32)
рдЕрд╕рд▓реА рдХреЛрдиреЛрдВ рдХреЗ рдореБрдХрд╝рд╛рдмрд▓реЗ рддреНрд░реБрдЯрд┐ рдШрдЯрдХрд░ 2.0, 2.2, 6.5 рдФрд░ 2.0 px рд░рд╣ рдЬрд╛рддреА рд╣реИред рдкреВрд░реА рдЦреЛрдЬ рдореЗрдВ 12 рд╕реЗ 20 ms рд▓рдЧрддреЗ рд╣реИрдВред рдЬреЛ рдПрдХ рдХреЛрдирд╛ 6.5 px рджреВрд░ рд░рд╣рддрд╛ рд╣реИ рд╡рд╣ рдиреАрдЪреЗ-рджрд╛рдПрдБ рдХрд╛ рд╣реИ, рдЬреЛ рдЗрд╕ рдлрд╝реЛрдЯреЛ рдореЗрдВ рдХрд╛рдЧрд╝рдЬрд╝ рдХреЗ рдиреАрдЪреЗ рдХреА рдЫрд╛рдпрд╛ рдХреА рдЬрдЧрд╣ рднреА рд╣реИред
рдЖрдпрдд рдореЗрдВ рд╡рд╛рд░реНрдк рдХрд░рдирд╛
getPerspectiveTransform рдЪрд╛рд░ рдХреЛрдиреЗ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рдЪрд╛рд░ рдХреЛрдиреЗ рд▓реЗрддрд╛ рд╣реИ, рдФрд░ рдмрд╛рдХрд╝реА warpPerspective рдХрд░рддрд╛ рд╣реИ:
w = round((np.linalg.norm(q[1] - q[0]) + np.linalg.norm(q[2] - q[3])) / 2)
h = round((np.linalg.norm(q[3] - q[0]) + np.linalg.norm(q[2] - q[1])) / 2)
M = cv2.getPerspectiveTransform(q, np.float32([[0, 0], [w - 1, 0], [w - 1, h - 1], [0, h - 1]]))
flat = cv2.warpPerspective(gray, M, (w, h), flags=cv2.INTER_CUBIC)
рд╡рд╛рд░реНрдк рдореЗрдВ 2 рд╕реЗ 6 ms рд▓рдЧрддреЗ рд╣реИрдВред рджреВрд╕рд░рд╛ рдЬрд╛рд▓ рдЖрдЙрдЯрдкреБрдЯ рдХрд╛ рд╕рд╛рдЗрдЬрд╝ рд╣реИред рдЖрдордиреЗ-рд╕рд╛рдордиреЗ рдХреА рднреБрдЬрд╛рдУрдВ рдХреА рд▓рдВрдмрд╛рдИ рдХрд╛ рдФрд╕рдд w рдФрд░ h рдЪреБрдирдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рд╕реАрдзрд╛ рддрд░реАрдХрд╝рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкрд░реНрд╕рдкреЗрдХреНрдЯрд┐рд╡ рдХреА рд╡рдЬрд╣ рд╕реЗ рдкрд╛рд╕ рдХреА рднреБрдЬрд╛ рджреВрд░ рд╡рд╛рд▓реА рд╕реЗ рд▓рдВрдмреА рджрд┐рдЦрддреА рд╣реИ рдФрд░ рдФрд╕рдд рдЕрд╕рд▓реА рдЖрд╕реНрдкреЗрдХреНрдЯ рд░реЗрд╢рд┐рдпреЛ рд╡рд╛рдкрд╕ рдирд╣реАрдВ рд▓рд╛рддрд╛ред рдпрд╣рд╛рдБ рдЙрд╕рдиреЗ 1174 ├Ч 1488 рджрд┐рдпрд╛, рдпрд╛рдиреА 0.789 рдХрд╛ рдЕрдиреБрдкрд╛рдд, рдЬрдмрдХрд┐ рдкрдиреНрдирд╛ рдЕрд╕рд▓ рдореЗрдВ 0.7727 (Letter) рд╣реИред рдпрд╣ 2% рдХрд╛ рдЦрд┐рдВрдЪрд╛рд╡ рд╣реИред рдЕрдЧрд░ рдХрд╛рдЧрд╝рдЬрд╝ рдХрд╛ рд╕рд╛рдЗрдЬрд╝ рдорд╛рд▓реВрдо рд╣реИ рддреЛ рд╡рд╣реА рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░реЗрдВ; рд╡рд░рдирд╛ рд╕реНрдХреИрдирд░ рдРрдк рдХреА рддрд░рд╣ рдереЛрдбрд╝рд╛ рдЦрд┐рдВрдЪрд╛ рд╣реБрдЖ рдкрдиреНрдирд╛ рдорд╛рди рд▓реЗрдВред
рдкрд╣рд▓реЗ рд╡рд╛рд░реНрдк рдХрд░рдирд╛ рд╡реИрдХрд▓реНрдкрд┐рдХ рдирд╣реАрдВ рд╣реИред рдмрд┐рдирд╛ рд╡рд╛рд░реНрдк рдХреА рдлрд╝реЛрдЯреЛ рдкрд░, рдореЗрдЬрд╝ рд╕рдореЗрдд, Otsu 42.9% рдкрд┐рдХреНрд╕реЗрд▓ рдХреЛ рд╕реНрдпрд╛рд╣реА рдорд╛рди рд▓реЗрддрд╛ рд╣реИред рд▓рдХрдбрд╝реА рдХрд╛рдЧрд╝рдЬрд╝ рд╕реЗ рдЧрд╣рд░реА рд╣реИ рдФрд░ рдЕрдХреНрд╖рд░реЛрдВ рдХреЗ рд╕рд╛рде рдЧрд┐рди рд▓реА рдЬрд╛рддреА рд╣реИред
рд╣рд┐рд╕реНрдЯреЛрдЧреНрд░рд╛рдо рдореЗрдВ рдПрдХ рд╕рд╛рдЗрдб рдЗрдлрд╝реЗрдХреНрдЯ рджрд┐рдЦрддрд╛ рд╣реИред рдлрд╝реЛрдЯреЛ рдореЗрдВ 253 рдЧреНрд░реЗ рд▓реЗрд╡рд▓ рдереЗ; рдмрд╛рдЗрдХреНрдпреВрдмрд┐рдХ рд╡рд╛рд░реНрдк рдХреЗ рдмрд╛рдж 255 рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдЗрдВрдЯрд░рдкреЛрд▓реЗрд╢рди рдкреБрд░рд╛рдиреЗ рдорд╛рдиреЛрдВ рдХреЗ рдмреАрдЪ рдирдП рдорд╛рди рдЧрдврд╝ рджреЗрддрд╛ рд╣реИред рдпрд╣ рдпрд╛рдж рджрд┐рд▓рд╛рддрд╛ рд╣реИ рдХрд┐ "рдЧреНрд░реЗ рд▓реЗрд╡рд▓ рдХреА рдЧрд┐рдирддреА" рдХрд╛ рдорддрд▓рдм рдмрд╛рдЗрдирд░рд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рдмрд╛рдж рд╣реА рдмрдирддрд╛ рд╣реИред
рдмрд╛рдЗрдирд░рд╛рдЗрдЬрд╝ рдХрд░рдирд╛
рд╕рдкрд╛рдЯ рдЧреНрд░реЗрд╕реНрдХреЗрд▓ рдкрдиреНрдиреЗ рдХреЛ рджреЛ рдорд╛рдиреЛрдВ рдореЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рддреАрди рддрд░реАрдХрд╝реЗ:
def binarize(g, how):
if how == 'global': # one threshold for the whole page
return cv2.threshold(g, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
if how == 'adaptive': # threshold relative to each pixel's neighbourhood
return cv2.adaptiveThreshold(g, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 41, 12)
if how == 'flatfield': # divide out the paper's own lighting, then one global threshold
bg = cv2.medianBlur(cv2.dilate(g, np.ones((7, 7), np.uint8)), 51)
n = np.clip(g.astype(np.float32) / np.maximum(bg, 1) * 255, 0, 255).astype(np.uint8)
return cv2.threshold(n, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
рдЗрдиреНрд╣реЗрдВ рдЬрд╛рдБрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдореИрдВрдиреЗ рд╣рд░ рдирддреАрдЬреЗ рдХреЛ рдЕрд╕рд▓реА рдкрдиреНрдиреЗ рдХреЗ рд╕рд╛рдЗрдЬрд╝ рдкрд░ рд╕реНрдХреЗрд▓ рдХрд┐рдпрд╛ рдФрд░ рд╕реНрдпрд╛рд╣реА рдХреЗ рдкрд┐рдХреНрд╕реЗрд▓ рдХреА рддреБрд▓рдирд╛ рдХреАред рдкрддрд▓реЗ рдЕрдХреНрд╖рд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдЯреАрдХ рдкрд┐рдХреНрд╕реЗрд▓-рдорд┐рд▓рд╛рди (IoU) рдХрдареЛрд░ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдПрдХ рдкрд┐рдХреНрд╕реЗрд▓ рдЦрд┐рд╕рдХреА рд░реЗрдЦрд╛ рднреА рдЪреВрдХ рдЧрд┐рдиреА рдЬрд╛рддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ 3 px рд╕рд╣рдирд╢реАрд▓рддрд╛ рдХреЗ рд╕рд╛рде precision рдФрд░ recall рднреА рд╣реИрдВ: рдЕрдиреБрдорд╛рдирд┐рдд рд╕реНрдпрд╛рд╣реА рдХрд╛ рд╡рд╣ рд╣рд┐рд╕реНрд╕рд╛ рдЬрд┐рд╕рдХреЗ 3 px рдХреЗ рднреАрддрд░ рдЕрд╕рд▓реА рд╕реНрдпрд╛рд╣реА рд╣реИ, рдФрд░ рдЕрд╕рд▓реА рд╕реНрдпрд╛рд╣реА рдХрд╛ рд╡рд╣ рд╣рд┐рд╕реНрд╕рд╛ рдЬрд┐рд╕рдХреЗ 3 px рдХреЗ рднреАрддрд░ рдЕрдиреБрдорд╛рдирд┐рдд рд╕реНрдпрд╛рд╣реА рд╣реИред рдЕрд╕рд▓реА рдкрдиреНрдиреЗ рдореЗрдВ 1.85% рд╕реНрдпрд╛рд╣реА рд╣реИред
| рддрд░реАрдХрд╝рд╛ | рд╕реНрдпрд╛рд╣реА | IoU | Precision (3 px) | Recall (3 px) | рд╕рдордп |
|---|---|---|---|---|---|
| рдЧреНрд▓реЛрдмрд▓ (Otsu) | 2.64% | 0.602 | 0.944 | 1.000 | 1.0 ms |
| рдЕрдбреИрдкреНрдЯрд┐рд╡ рдЧрд╛рдЙрд╕рд┐рдпрди | 3.15% | 0.554 | 0.948 | 1.000 | 9.1 ms |
| рдлрд╝реНрд▓реИрдЯ-рдлрд╝реАрд▓реНрдб + Otsu | 2.81% | 0.591 | 0.941 | 1.000 | 46.4 ms |
| рдРрдк рдХрд╛ рд╕реЗрд╡ рдХрд┐рдпрд╛ рдкрдиреНрдирд╛ | 2.36% | 0.633 | 1.000 | 1.000 | тАФ |
рдЗрд╕ рдлрд╝реЛрдЯреЛ рдореЗрдВ рдЗрдирдореЗрдВ рдлрд╝рд░реНрдХрд╝ рдирд╣реАрдВ рджрд┐рдЦрддрд╛ред рд╡рд╛рд░реНрдк рдХреЗ рдмрд╛рдж рдХрд╛рдЧрд╝рдЬрд╝ рд╣рд░ рдЬрдЧрд╣ рд╕реНрдпрд╛рд╣реА рд╕реЗ рдХрд╣реАрдВ рдЬрд╝реНрдпрд╛рджрд╛ рдЪрдордХреАрд▓рд╛ рд╣реИ, рдФрд░ рдПрдХ рд╣реА рдереНрд░реЗрд╢реЛрд▓реНрдб рдХрд╛рдлрд╝реА рд╣реИред рддреАрдиреЛрдВ рд╣рд░ рд░реЗрдЦрд╛ рдХреЛ рдмрдЪрд╛ рд▓реЗрддреЗ рд╣реИрдВ (recall 1.000) рдФрд░ рдЙрдиреНрд╣реЗрдВ рдереЛрдбрд╝рд╛ рдЬрд╝реНрдпрд╛рджрд╛ рдореЛрдЯрд╛ рдХрд░ рджреЗрддреЗ рд╣реИрдВ (1.85% рдХреЗ рдореБрдХрд╝рд╛рдмрд▓реЗ 2.6 рд╕реЗ 3.2% рд╕реНрдпрд╛рд╣реА)ред
рдЖрдЦрд╝рд┐рд░реА рдкрдВрдХреНрддрд┐ рд╡рд╣реА рдкрдиреНрдирд╛ рд╣реИ рдЬреЛ osFoundry рдХреЗ PDF рдПрдбрд┐рдЯрд░ рдиреЗ рдЙрд╕реА рдлрд╝реЛрдЯреЛ рдХреЗ рд▓рд┐рдП рд╕реЗрд╡ рдХрд┐рдпрд╛, рдФрд░ рдЙрд╕реЗ рдЙрд╕реА рддрд░рд╣ рдЬрд╛рдБрдЪрд╛ рдЧрдпрд╛ред рд╕реЗрд╡ рдХрд┐рдП PDF рд╕реЗ рдкрдиреНрдиреЗ рдХреА рдЗрдореЗрдЬ рдореИрдВрдиреЗ PyMuPDF рд╕реЗ рд╡рд╛рдкрд╕ рдкрдврд╝реА: рдЙрд╕рдореЗрдВ рдареАрдХ 2 рдЧреНрд░реЗ рд▓реЗрд╡рд▓ рдФрд░ 2.36% рд╕реНрдпрд╛рд╣реА рд╣реИред рдПрдбрд┐рдЯрд░ рдпрд╣ рдХреИрд╕реЗ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рдореИрдВрдиреЗ рдирд╣реАрдВ рджреЗрдЦрд╛, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдкрдВрдХреНрддрд┐ рд╕рд┐рд░реНрдлрд╝ рдирддреАрдЬреЛрдВ рдХреА рддреБрд▓рдирд╛ рд╣реИред рдпрд╣ рджрд┐рдЦрд╛рддреА рд╣реИ рдХрд┐ рдЪрд╛рд░ рдЦреАрдВрдЪрдиреЗ рд╡рд╛рд▓реЗ рд╣реИрдВрдбрд▓ рд╡рд╛рд▓реЗ рдЯреВрд▓ рдХрд╛ рдирддреАрдЬрд╛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╡рд╛рд▓реА рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдЬреИрд╕реА рд╣реА рд░реЗрдВрдЬ рдореЗрдВ рдЖрддрд╛ рд╣реИред
рдЬрдм рдЧреНрд▓реЛрдмрд▓ рдереНрд░реЗрд╢реЛрд▓реНрдб рдЯреВрдЯ рдЬрд╛рддрд╛ рд╣реИ
рдлрд╝реЛрдЯреЛ рдХреА рд░реЛрд╢рдиреА рдирд░рдо рдереА, рдФрд░ рдпрд╣реА рдЫрд┐рдкрд╛ рджреЗрддрд╛ рд╣реИ рдХрд┐ рдмрд╛рдХрд╝реА рджреЛ рддрд░реАрдХрд╝реЗ рдХреНрдпреЛрдВ рд╣реИрдВред рдЗрд╕реЗ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдореИрдВрдиреЗ рд╕рдкрд╛рдЯ рдкрдиреНрдиреЗ рдХреЛ рдПрдХ рдврд▓рд╛рди рд╕реЗ рдЧреБрдгрд╛ рдХрд┐рдпрд╛ рдЬреЛ рдиреАрдЪреЗ-рджрд╛рдПрдБ рдХреЛ 40% рдЪрдордХ рддрдХ рдЧрд╣рд░рд╛ рдХрд░ рджреЗрддреА рд╣реИ, рдЬреИрд╕реЗ рдХрд┐рд╕реА рдлрд╝реЙрд░реНрдо рдкрд░ рд╣рд╛рде рдХреА рдЫрд╛рдпрд╛, рдФрд░ рддреАрдиреЛрдВ рддрд░реАрдХрд╝реЗ рдлрд┐рд░ рдЪрд▓рд╛рдП:
| рддрд░реАрдХрд╝рд╛ | рд╕реНрдпрд╛рд╣реА | Precision (3 px) | Recall (3 px) |
|---|---|---|---|
| рдЧреНрд▓реЛрдмрд▓ (Otsu) | 49.85% | 0.072 | 1.000 |
| рдЕрдбреИрдкреНрдЯрд┐рд╡ рдЧрд╛рдЙрд╕рд┐рдпрди | 3.04% | 0.946 | 1.000 |
| рдлрд╝реНрд▓реИрдЯ-рдлрд╝реАрд▓реНрдб + Otsu | 2.81% | 0.939 | 1.000 |
рдЧреНрд▓реЛрдмрд▓ Otsu рдЫрд╛рдпрд╛ рд╡рд╛рд▓реЗ рдЖрдзреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЛ рдХрд╛рд▓рд╛ рдХрд░ рджреЗрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП recall рдкреВрд░рд╛ рд░рд╣рддрд╛ рд╣реИ рдЬрдмрдХрд┐ precision рдЧрд┐рд░рдХрд░ 0.07 рд╣реЛ рдЬрд╛рддреА рд╣реИред рдЕрдбреИрдкреНрдЯрд┐рд╡ рдФрд░ рдлрд╝реНрд▓реИрдЯ-рдлрд╝реАрд▓реНрдб рдХреЗ рдирддреАрдЬреЗ рд▓рдЧрднрдЧ рдирд╣реАрдВ рдмрджрд▓рддреЗред рдЕрдбреИрдкреНрдЯрд┐рд╡ рдХреЛ рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЖрдЬрд╝рдорд╛рдирд╛ рдЪрд╛рд╣рд┐рдП: рд╡рд╣ рдЧреНрд▓реЛрдмрд▓ рд╕реЗ рдХрд╝рд░реАрдм 8 ms рдЬрд╝реНрдпрд╛рджрд╛ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдЙрд╕реЗ рдХреЛрдИ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд╝рджрдо рдирд╣реАрдВ рдЪрд╛рд╣рд┐рдПред рдлрд╝реНрд▓реИрдЯ-рдлрд╝реАрд▓реНрдб рд▓рдЧрднрдЧ рд╡рд╣реА рдирддреАрдЬрд╛ рджреЗрддрд╛ рд╣реИ рдФрд░ рдзреАрдорд╛ рд╣реИ (рдпрд╣рд╛рдБ 46 ms), рдЗрд╕рд▓рд┐рдП рдЗрд╕ рдкрдиреНрдиреЗ рдкрд░ рдЙрд╕реЗ рдЪреБрдирдиреЗ рдХреА рдХреЛрдИ рд╡рдЬрд╣ рдирд╣реАрдВред
рдКрдкрд░ рдХрд╛ рдХреЛрдб рдкреВрд░реА рдкрд╛рдЗрдкрд▓рд╛рдЗрди рд╣реИ; рдЬрд╛рдБрдЪ рд╕рд┐рд░реНрдлрд╝ рд╕реНрдпрд╛рд╣реА рдХреЗ рдкрд┐рдХреНрд╕реЗрд▓ рдХреА рддреБрд▓рдирд╛ рдЙрд╕ рдкрдиреНрдиреЗ рд╕реЗ рдХрд░рддреА рд╣реИ рдЬрд┐рд╕рд╕реЗ рдлрд╝реЛрдЯреЛ рдмрдиреА рдереАред рдПрдбрд┐рдЯрд░ рдореБрдлрд╝реНрдд osFoundry рдбреЗрд╕реНрдХрдЯреЙрдк рдРрдк рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рдФрд░ local-first рдкреЗрдЬ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ osFoundry рдХрд╛рдо рдХреЛ рдЖрдкрдХреА рдЕрдкрдиреА рдорд╢реАрди рдкрд░ рдХреИрд╕реЗ рд░рдЦрддрд╛ рд╣реИред

Top comments (0)