This commit is contained in:
Mephimeow
2026-04-29 10:24:42 +00:00
parent 56a8bfa766
commit fe740da06b
4 changed files with 323 additions and 0 deletions
+90
View File
@@ -0,0 +1,90 @@
#!/usr/bin/env python3
"""QR/Barcode scanner using pyzbar + OpenCV for Raspberry Pi Camera Module v3."""
import cv2
from pyzbar import pyzbar
import time
def main():
# Camera Module v3 uses libcamera (not V4L2 by default)
# GStreamer pipeline for libcamera
gst_pipeline = (
"libcamerasrc ! "
"video/x-raw, format=NV12, width=1280, height=960 ! "
"videoconvert ! "
"video/x-raw, format=BGR ! "
"appsink"
)
cap = cv2.VideoCapture(gst_pipeline, cv2.CAP_GSTREAMER)
if not cap.isOpened():
# Fallback: try V4L2 if libcamera pipeline fails
print("GStreamer pipeline failed, trying /dev/video0...")
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("Error: Cannot open camera")
return
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 960)
scanned_codes = set()
print("Scanner running. Press 'q' to quit, 'r' to reset scanned codes.")
try:
while True:
ret, frame = cap.read()
if not ret:
print("Failed to grab frame")
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
codes = pyzbar.decode(gray)
for code in codes:
data = code.data.decode("utf-8")
code_type = code.type
if data not in scanned_codes:
scanned_codes.add(data)
print(f"[{code_type}] {data} (total unique: {len(scanned_codes)})")
# Draw bounding box
points = code.polygon
if len(points) == 4:
pts = [(p.x, p.y) for p in points]
for i in range(4):
cv2.line(frame, pts[i], pts[(i + 1) % 4], (0, 255, 0), 3)
# Draw data label
cv2.putText(
frame,
data[:40],
(points[0].x, points[0].y - 10),
cv2.FONT_HERSHEY_SIMPLEX,
0.5,
(0, 255, 0),
2,
)
cv2.imshow("Scanner", frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break
elif key == ord("r"):
scanned_codes.clear()
print("Scanned codes reset.")
except KeyboardInterrupt:
pass
finally:
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()