תארו לעצמכם מצלמה שבקושי קולטת קוד QR, וברקוד על אריזה מקומטת שלא נקרא כלל. זה קורה לעתים קרובות בקמעונאות, לוגיסטיקה ומחסנים. במשך יותר מ-10 שנים, יישמנו עשרות מערכות זיהוי ופיתחנו גישה היברידית המשלבת את המהירות של ספריות קלות משקל (ZXing, ZBar) עם העוצמה של זיהוי ML על YOLOv8. שילוב זה מספק דיוק של 99% אפילו על קודים פגומים ופועל בזמן אמת (בדיקות פנימיות על 10,000 פריימים). הגישה ההיברידית שלנו מדויקת פי 2-3 מספריות סטנדרטיות על ברקודים פגומים, ומפחיתה כשלי זיהוי עד פי 5. הניסיון שלנו כולל יותר מ-20 התקנות עבור קמעונאים גדולים ומפעילי לוגיסטיקה, עם תוצאות המובטחות בחוזה. בממוצע, לקוחות חוסכים עד $4.5k–6.5k בשנה על ידי הפחתת סריקה ידנית. כל קוד שלא זוהה עולה $1–2 בהפסדים — המערכת מחזירה את עצמה תוך חודשיים.
מדדי החברה
עם ניסיון של יותר מ-10 שנים, יותר מ-20 פרויקטים ו-5+ שנים בשוק, הצוות שלנו מבטיח פתרונות אמינים ויעילים.
למה ספריות מסורתיות לא תמיד מספיקות
ZXing ו-ZBar מפענחות קודים היטב על תמונות שטוחות ובעלות ניגודיות גבוהה. אבל בפועל, פריימים יכולים להיות מטושטשים, חשופים יתר על המידה, או עם עיוותי פרספקטיבה — ושיעור הכשלים מזנק ל-30–40%. ספריות לא מסתגלות לתנאי הצילום: הן מחפשות דפוסים ברורים, וכשהם חסרים, הן פשוט מחזירות כלום. עבור סריקת מסועים או אפליקציות ניידות, זה קריטי — כל קוד שהוחמץ משמעותו אובדן נתונים או זמן.
הבעיה נפתרת בשתי דרכים: עיבוד מקדים אגרסיבי (וריאציות בינאריזציה מרובות, CLAHE, שינוי קנה מידה) והוספת גלאי ML שמאתר תחילה את אזור הקוד ואז מעביר אותו למפענח. אנחנו משתמשים בשתיהן.
איך זיהוי ML משפר את דיוק הזיהוי
זיהוי ML המבוסס על YOLOv8 (מותאם על מערך נתונים של 50,000 קודים מסומנים) מאתר את הקוד בתמונה ללא קשר למצבו. הגלאי עמיד לרעש, סנוור והסתרות חלקיות. לאחר חילוץ האזור, אנו מיישמים תיקון פרספקטיבה ורק אז מפעילים את המפענח. המדידות שלנו מראות שזה משפר את הדיוק על פריימים פגומים פי 2-3 בהשוואה לקריאה ישירה של ZBar — הגישה ההיברידית מדויקת פי 2-3 על פריימים קשים. בעוד ש-ZBar מאבד עד 40% מהקודים על פריימים מעוותים, ההיברידית שומרת על 95%.
from ultralytics import YOLO
barcode_detector = YOLO('barcode_detector.pt')
def detect_and_decode(image: np.ndarray) -> list[dict]:
detections = barcode_detector(image, conf=0.4)
results = []
for box in detections[0].boxes.xyxy:
x1, y1, x2, y2 = map(int, box)
pad = 5
crop = image[max(0,y1-pad):y2+pad, max(0,x1-pad):x2+pad]
corrected = correct_perspective(crop)
decoded = robust_decode(corrected)
results.extend(decoded)
return results אינטגרציה סטנדרטית דרך ZXing ו-ZBar
למקרים פשוטים, קריאה אחת ל-from ultralytics import YOLO barcode_detector = YOLO('barcode_detector.pt') def detect_and_decode(image: np.ndarray) -> list[dict]: detections = barcode_detector(image, conf=0.4) results = [] for box in detections[0].boxes.xyxy: x1, y1, x2, y2 = map(int, box) pad = 5 crop = image[max(0,y1-pad):y2+pad, max(0,x1-pad):x2+pad] corrected = correct_perspective(crop) decoded = robust_decode(corrected) results.extend(decoded) return results מספיקה. אנחנו עוטפים אותה במחלקה pyzbar שמחזירה סוג, נתונים וקואורדינטות. זה עובד על תמונות וזרמי וידאו ב-30 fps ללא ML.
import cv2
import numpy as np
from pyzbar.pyzbar import decode
from pyzbar.pyzbar import ZBarSymbol
class BarcodeScanner:
def __init__(self):
pass
def decode_all(self, image: np.ndarray) -> list[dict]:
decoded_objects = decode(image)
results = []
for obj in decoded_objects:
results.append({
'type': obj.type,
'data': obj.data.decode('utf-8', errors='replace'),
'polygon': [(p.x, p.y) for p in obj.polygon],
'rect': {
'left': obj.rect.left,
'top': obj.rect.top,
'width': obj.rect.width,
'height': obj.rect.height
}
})
return results
def decode_qr_only(self, image: np.ndarray) -> list[dict]:
return [r for r in self.decode_all(image) if r['type'] == 'QRCODE']
def decode_barcodes_only(self, image: np.ndarray) -> list[dict]:
barcode_types = {'EAN13', 'EAN8', 'CODE128', 'CODE39', 'UPCA', 'UPCE', 'ITF', 'PDF417', 'DATAMATRIX'}
return [r for r in self.decode_all(image) if r['type'] in barcode_types]
פורמטים נתמכים
| פורמט | שימוש |
|---|---|
| QR Code | כתובות URL, vCard, תשלומים ניידים |
| EAN-13 / EAN-8 | מוצרי קמעונאות |
| Code 128 | לוגיסטיקה, כרטיסי טיסה |
| PDF417 | רישיונות נהיגה, דרכונים, כרטיסי עלייה למטוס |
| Data Matrix | תרופות, אלקטרוניקה |
| Aztec | כרטיסי תחבורה |
| Code 39 | תעשייה |
| ITF-14 | אריזות קבוצתיות |
עיבוד מקדים לשיפור הזיהוי
כדי להגביר את סיכויי הפענוח, אנו מיישמים ברצף מספר וריאציות עיבוד על פריים בודד: מקורי, גווני אפור, CLAHE, בינאריזציה אדפטיבית, שינוי קנה מידה. ברגע שוריאציה אחת מניבה תוצאה, אנו מחזירים אותה.
def preprocess_for_barcode(image: np.ndarray) -> list[np.ndarray]:
variants = []
variants.append(image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
variants.append(gray)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
enhanced = clahe.apply(gray)
variants.append(enhanced)
binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 51, 2)
variants.append(binary)
if image.shape[0] < 300:
scale_factor = 300 / image.shape[0]
big = cv2.resize(image, None, fx=scale_factor, fy=scale_factor, interpolation=cv2.INTER_CUBIC)
variants.append(big)
return variants
def robust_decode(image: np.ndarray) -> list[dict]:
scanner = BarcodeScanner()
for variant in preprocess_for_barcode(image):
results = scanner.decode_all(variant)
if results:
return results
return [] סריקת זרמי וידאו
לקלט ממצלמה או מקובץ, אנו משתמשים ב-BarcodeScanner ומריצים את המפענח בלולאה. זה מאפשר עיבוד בזמן אמת (עד 30 FPS על CPU ברזולוציית HD).
def scan_video_stream(camera_id: int = 0, callback=None):
cap = cv2.VideoCapture(camera_id)
scanner = BarcodeScanner()
last_results = set()
while True:
ret, frame = cap.read()
if not ret:
break
results = scanner.decode_all(frame)
for r in results:
if r['data'] not in last_results:
last_results.add(r['data'])
if callback:
callback(r) דוגמה לסריקת וידאו ממצלמת אינטרנט
import cv2
def scan_camera():
cap = cv2.VideoCapture(0)
scanner = BarcodeScanner()
while True:
ret, frame = cap.read()
if not ret:
break
results = scanner.decode_all(frame)
for r in results:
if r['type'] == 'QRCODE':
cv2.putText(frame, r['data'], (r['rect']['left'], r['rect']['top']-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)
cv2.imshow('Scanner', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()כדי להפחית את זמן ההשהיה ב-p99, אנו משתמשים בקוונטיזציה של INT8 ו-ONNX Runtime, מה שמאפשר עד 30 פריימים לשנייה על GPU. הגישה ההיברידית שלנו משלבת ספריות זיהוי (ZXing, ZBar, pyzbar) עם זיהוי קוד ML המבוסס על YOLOv8, ומבטיחה פענוח יעיל של קודים פגומים. טכנולוגיות ראייה ממוחשבת וסריקת ברקוד בווידאו בזמן אמת הם המומחיות שלנו. זיהוי ברקוד YOLO הוא מרכיב מפתח במערכת זו.
תוצרים / מה כלול
- ניתוח דרישות — אנו לומדים את תנאי הצילום, סוגי הקודים ודרישות המהירות.
- עיצוב ארכיטקטורה — אנו בוחרים ספריות, מודל ML ואסטרטגיית עיבוד מקדים.
- יישום אב טיפוס — אנו משלבים גלאי ומפענח, ומכוונים את הצינור.
- בדיקות עומס — אנו מריצים על הנתונים שלכם, מודדים דיוק וזמן השהיה.
- אינטגרציה לתשתית שלכם — אנו אורזים ל-Docker, מגדירים Kubernetes ומחברים ל-API.
- תיעוד ומסירה — אנו מספקים קוד, תיעוד ומודל.
כתוצאה מכך אתם מקבלים:
- מודול זיהוי עם REST/gRPC API
- דוגמאות אינטגרציה ב-Python ו-C++
- הוראות פריסה (Docker, Kubernetes)
- מודל YOLOv8 מותאם (אם נדרש חלק ה-ML)
- הבטחת דיוק על פריימי הבדיקה שלכם
- 3 חודשי תמיכה טכנית
לוח זמנים: מ-3 ימים לאינטגרטור בסיסי עד 5 שבועות לפתרון ML מלא. לוח זמנים ועלות מדויקים מוערכים לאחר בחינת הנתונים שלכם — צרו קשר, ונכין הצעה תוך 1–2 ימים.
השוואה: מסורתי מול היברידי
| קריטריון | רק ZBar/ZXing | היברידי (ZBar + YOLOv8) |
|---|---|---|
| דיוק על פריימים טובים | >99% | >99% |
| דיוק על פריימים פגומים | 30–60% | 90–95% |
| מהירות על CPU | 1–5 ms | 15–30 ms |
| עמידות לעיוותים | נמוכה | גבוהה |
| נדרשת הכשרה | לא | כן (חד-פעמית) |
הערה: כפי שניתן לראות, הגישה ההיברידית כמעט לא מפסידה בתרחישים פשוטים אך מספקת רווח עצום בתרחישים מורכבים. אם אתם עובדים עם פריימים אמיתיים מחנויות, מחסנים או תחבורה — האפשרות השנייה מחזירה את עצמה בתוך החודש הראשון.
תארו את המשימה שלכם — אנו נבחר את התצורה האופטימלית ונדגים אב טיפוס עובד על התמונות שלכם. ללא תשלום מראש, ועם אחריות לתוצאות. קבלו ייעוץ והערכת לוחות זמנים כבר עכשיו. צרו קשר לבדיקת התמונות שלכם — זה לוקח לא יותר משעה.







