【发布时间】:2017-12-14 22:50:11
【问题描述】:
所以我的 Raspberry Pi 上有一个 Python 程序,它在无限循环中运行,每秒从相机中获取一张图像。
每次迭代时,程序都会创建一个使用图像进行处理的线程。该过程包括:一个脚本使用 OpenCV 从图像中提取手机屏幕,另一个脚本从该屏幕中提取 QR 码。
我使用该程序使用预先拍摄的图像来毫无问题地处理它们,但如果我让程序通过一个连续循环,它只会窒息。
经过几次循环迭代并尝试处理图像后,程序意外中断,我的 Raspberry Pi 突然关闭。有谁知道为什么会这样?
我一直在寻找答案,但我的怀疑与线程有关。要么,我的 CPU 或 RAM 超载,内存泄漏,Raspberry Pi 耗电过多
编辑:
从下面的 cmets 看来,Pi 的电源似乎是问题所在。我目前正在使用手机充电器(5.0v,1.0A),它(非常)低于 5.0v,2.5A 推荐的电源,真烦我。当我得到一个新的电源并测试代码时,我会更新这篇文章。
此外,在我的 Windows 笔记本电脑上运行该程序完全没有问题。
这是我的主要脚本:
import picamera
import threading
import time
from processing.qr import get_qr_code
from processing.scan import scan_image
# Thread method
def extract_code(file):
print 'Thread for: ' + file
# Scans image to extract phone screen from image and then gets QR code from it
scan_image(file)
get_qr_code(file)
return
# End methods
camera = picamera.PiCamera()
while True:
time.sleep(1)
# Make epoch time as file name
time_epoch = str(int(time.time()))
image_path = "images/" + time_epoch + ".jpg"
print "Taking photo: " + str(image_path)
camera.capture(image_path)
# Create thread to start processing image
t = threading.Thread(target=extract_code, args=[time_epoch])
t.start()
下面是扫描图像的脚本(scan.py) 简而言之,它会拍摄一张图像,对其进行模糊处理、寻找边缘并绘制轮廓,检查是否有一个矩形(例如手机屏幕),然后将其转换并扭曲成一个只有手机屏幕的新图像。
from transform import four_point_transform
import imutils
import numpy as np
import argparse
import cv2
import os
def scan_image(file):
images_dir = "images/"
scans_dir = "scans/"
input_file = images_dir + file + ".jpg"
print "Scanning image: " + input_file
# load the image and compute the ratio of the old height
# to the new height, clone it, and resize it
image = cv2.imread(input_file)
ratio = image.shape[0] / 500.0
orig = image.copy()
image = imutils.resize(image, height = 500)
# convert the image to grayscale, blur it, and find edges
# in the image
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(gray, 75, 200)
# show the original image and the edge detected image
print "STEP 1: Edge Detection"
# find the contours in the edged image, keeping only the
# largest ones, and initialize the screen contour
_, cnts, _ = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:5]
screenCnt = 0
# loop over the contours
for c in cnts:
# approximate the contour
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
# if our approximated contour has four points, then we
# can assume that we have found our screen
if len(approx) == 4:
screenCnt = approx
break
# show the contour (outline) of the piece of paper
print "STEP 2: Find contours of paper"
# if screenCnt > 0 :
# cv2.drawContours(image, [screenCnt], -1, (0, 255, 0), 2)
# apply the four point transform to obtain a top-down
# view of the original image
if screenCnt > 0:
warped = four_point_transform(orig, screenCnt.reshape(4, 2) * ratio)
print "STEP 3: Apply perspective transform"
output = scans_dir + file + "-result.png"
if not os.path.exists(scans_dir):
os.makedirs(scans_dir)
cv2.imwrite(output, imutils.resize(warped, height = 650))
else:
print "No screen detected"
这是从图像中扫描二维码的代码:
import os
from time import sleep
def get_qr_code(image_name):
scans_dir = "scans/"
codes_dir = "codes/"
input_scan_path = scans_dir + image_name + "-result.png"
output_qr_path = codes_dir + image_name + "-result.txt"
if not os.path.exists(codes_dir):
os.makedirs(codes_dir)
if os.path.exists(input_scan_path):
os.system("zbarimg -q " + input_scan_path + " > " + output_qr_path)
if os.path.exists(output_qr_path):
strqrcode = open(output_qr_path, 'r').read()
# print strqrcode
print "Results for " + image_name + ": " + strqrcode
else:
print "File does not exist"
【问题讨论】:
标签: python multithreading opencv raspberry-pi computer-vision