python - 通过 zbar 和 Raspicam 模块扫描二维码

标签 python raspberry-pi qr-code zbar

我想用我的 raspi cam 模块扫描二维码。 为了检测和解码二维码,我想使用 zbar。 我当前的代码:

import io
import time
import picamera
import zbar
import Image

if len(argv) < 2: exit(1)

# Create an in-memory stream
my_stream = io.BytesIO()
with picamera.PiCamera() as camera:
    camera.start_preview()
    # Camera warm-up time
    time.sleep(2)
    camera.capture(my_stream, 'jpeg')

scanner = zbar.ImageScanner()
scanner.parse_config('enable')   

pil = Image.open(argv[1]).convert('L')
width, height = pil.size
raw = pil.tostring()

my_stream = zbar.Image(width, height, 'Y800', raw) 

scanner.scan(image)

for symbol in image:
    print 'decoded', symbol.type, 'symbol', '"%s"' % symbol.data

如您所见,我想创建一个图片流,将这个流发送到zbar,以检查图片中是否包含二维码。 我无法运行这段代码,结果是这个错误:

Segmentation fault

------------------ (program exited with code: 139) Press return to continue

我没有找到任何解决方案来修复这个错误,有什么想法吗?

亲切的问候;

最佳答案

所有其他答案的不足之处在于它们有大量的延迟 - 例如,它们正在扫描并显示在屏幕上的实际上是几秒钟前拍摄的帧等等。

这是由于 Raspberry Pi 的 CPU 速度慢所致。所以 frame-rate 比我们的软件可以读取和扫描的速率要大得多。

经过一番努力,我终于做出了这段代码,它有LITTLE DELAY。所以当你给它一个二维码/条码时,它会在不到一秒钟的时间内给你一个结果。

代码中解释了我使用的技巧。

import cv2
import cv2.cv as cv
import numpy
import zbar
import time
import threading

'''
LITTLE-DELAY BarCodeScanner
Author: Chen Jingyi (From FZYZ Junior High School, China)
PS. If your pi's V4L is not available, the cv-Window may have some error sometimes, but other parts of this code works fine.
'''
class BarCodeScanner(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

        self.WINDOW_NAME = 'Camera'
        self.CV_SYSTEM_CACHE_CNT = 5 # Cv has 5-frame cache
        self.LOOP_INTERVAL_TIME = 0.2

        cv.NamedWindow(self.WINDOW_NAME, cv.CV_WINDOW_NORMAL)
        self.cam = cv2.VideoCapture(-1)

    def scan(self, aframe):
        imgray = cv2.cvtColor(aframe, cv2.COLOR_BGR2GRAY)
        raw = str(imgray.data)

        scanner = zbar.ImageScanner()
        scanner.parse_config('enable')          

        #print 'ScanZbar', time.time()
        width = int(self.cam.get(cv.CV_CAP_PROP_FRAME_WIDTH))
        height = int(self.cam.get(cv.CV_CAP_PROP_FRAME_HEIGHT))
        imageZbar = zbar.Image(width, height,'Y800', raw)
        scanner.scan(imageZbar)
        #print 'ScanEnd', time.time()

        for symbol in imageZbar:
            print 'decoded', symbol.type, 'symbol', '"%s"' % symbol.data

    def run(self):
        #print 'BarCodeScanner run', time.time()
        while True:
            #print time.time()
            ''' Why reading several times and throw the data away: I guess OpenCV has a `cache-queue` whose length is 5.
            `read()` will *dequeue* a frame from it if it is not null, otherwise wait until have one.
            When the camera has a new frame, if the queue is not full, the frame will be *enqueue*, otherwise be thrown away.
            So in this case, the frame rate is far bigger than the times the while loop is executed. So when the code comes to here, the queue is full.
            Therefore, if we want the newest frame, we need to dequeue the 5 frames in the queue, which is useless because it is old. That's why.
            '''
            for i in range(0,self.CV_SYSTEM_CACHE_CNT):
                #print 'Read2Throw', time.time()
                self.cam.read()
            #print 'Read2Use', time.time()
            img = self.cam.read()
            self.scan(img[1])

            cv2.imshow(self.WINDOW_NAME, img[1])
            cv.WaitKey(1)
            #print 'Sleep', time.time()
            time.sleep(self.LOOP_INTERVAL_TIME)

        cam.release()

scanner = BarCodeScanner()
scanner.start()

关于python - 通过 zbar 和 Raspicam 模块扫描二维码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23538522/

相关文章:

linux - 嵌入式Linux : Hardware access

qr-code - AVCaptureMetadataOutputObjectsDelegate 未在 Swift 4 中为 QR 扫描仪调用

android - android 中使用 Zxing 库生成二维码版本 2 和二维码版本 4 的区别

c# - 从多个文本框创建 QR 码并将其解码回文本框

python - 如何将 python 的 subprocess.Call 方法输出重定向到文件而不是控制台?

python - 如何扩展 CKAN API?

docker - 在 Intel 机器 (Mac) 上构建 ARM 架构的 Docker 镜像

python - 使用 Raspberry Pi 和 Python 控制连续伺服电机

python - 使用 Python 的 Sublime Text 中的进度条

python - 字符串模式匹配python