2017-12-14 15 views
0

그래서 매초마다 카메라에서 이미지를 가져 오는 무한 루프에서 실행되는 라즈베리 파이에 파이썬 프로그램이 있습니다.라즈베리 파이를 갑작스럽게 끄기 프로그램

매 반복마다 프로그램에서 이미지를 처리하는 스레드를 만듭니다. 이 프로세스는 다음과 같이 구성됩니다. 스크립트는 OpenCV 및 다른 스크립트를 사용하여 이미지에서 전화 화면을 추출하여 해당 화면에서 QR 코드를 추출합니다.

나는 프로그램을 사용하여 문제없이 처리하기 위해 미리 찍은 이미지를 사용했지만 연속 루프를 통해 프로그램을 넣으면 문제가 발생합니다.

반복 횟수를 반복하고 이미지 처리를 시도하면 예기치 않게 프로그램이 중단되고 Raspberry Pi가 갑작스럽게 종료됩니다. 왜 이런 일이 일어나는 지 아는 사람이 있습니까?

나는 대답을 주변에서 둘러 보았지만, 나의 의심은 스레드와 관련되어있다. 이 파이에 전원 공급 장치가 보이는 것 같습니다 아래의 코멘트에서

: 하나, 내가 CPU 나 RAM을 오버로드하고있어, 메모리 누수는 라즈베리 파이가 너무 많은 전력

편집을 사용하고있다 문제가되는 것. 나는 현재 전화 충전기 (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" 

이미지에서 QR 코드를 스캔 할 수있는 코드 :

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" 

답변

0

루프를 몇 번 반복하고 이미지를 처리하려고하면 프로그램이 예기치 않게 중단되고 내 Raspberry Pi가 갑작스럽게 종료됩니다. 왜 이런 일이 일어나는 지 아는 사람이 있습니까?

나는 비슷한 경험을했습니다. 내 프로그램 (C++) 실시간 처리 카메라 프레임이 예기치 않게 손상되었습니다. 때로는 OS 코드 내부에서 세분화 오류가 발생하고 때로는 전체 보드를 종료하는 경우도 있습니다. 때때로 프로그램 실행 파일은 단지 0 바이트가됩니다.

메모리 누수 또는 CPU 피크 또는 다른 종류의 프로그래밍 오류를 찾는 데 오랜 시간이 걸렸습니다.갑자기 전원 공급 장치가 너무 강하지 않다는 것을 깨달았습니다. 좀 더 튼튼한 새 것으로 바꿨으므로 더 이상 문제가 없습니다.

link에서 2.5A 권장 사항을 확인하고 UPS가 실제로이 요구 사항을 충족하는지 확인하십시오.

+0

예, 이것이 제 문제 일 수 있습니다 (어리석은 날). My Pi는 휴대 전화 충전기에서 5.0V, 1.0A ** 전원 공급 장치로 작동합니다. 내 게시판을 다시 켠 후에 파이썬 파일에서 0 바이트를 얻었으므로 repo를 다시 복제해야했습니다. 나는 전원 공급 장치를 바꾸고이 게시물을 결과와 함께 편집 할 것이다. 감사합니다 Doleron – EamonT22

+0

설명해 주셔서 감사합니다. 때로는 실제 2.5A를 찾는 것이 어렵습니다. 귀하의 경우, LM 2596과 같은 3V 앰프와 최대 12V 전원 공급 장치를 사용하면 최대 3 Amp의 5 V 전원 소스 인 https : //를 제공 할 수 있습니다. electronics.stackexchange.com/questions/174446/using-12v-to-supply-a-raspberry-pi-with-a-switching-regulator – Doleron

0

어쩌면 당신이 찾고있는 대답,하지만 임베디드 시스템에 OpenCV의 파이썬을 사용하는 것은 정말 아니다 좋은 생각. 필자는 임베디드 시스템에서 python을 사용할 때 많은 문제점을 경험했습니다.

파이썬 대신 C++을 사용했을 때 내가 경험 한 모든 성능 문제가 사라졌습니다. C++의 OpenCV는 꽤 견고하며 그것을 시도해 볼 것을 강력히 권장합니다.

+0

어쨌든 코드를 실행하려고합니다. 나는 현재 그것을 시도하는 나무 딸기 파이가 없지만 가능한 한 빨리 이것을 살펴볼 것입니다. –

+0

감사합니다. 머리를위한 마티아스! 이 문제를 Windows에 적용하려고합니다. – EamonT22

+0

예 내 Windows 컴퓨터에서 작동하도록 프로그램을 수정했으며 문제없이 작동합니다. 문제는 @Doleron이 지정한 전원 공급 장치에 있다고 생각합니다. 현재 전화 충전기 (5.0V, 1,0A)에서 Pi를 실행하고 있으므로 전원 공급 장치를 변경하면이 문제가 해결 될 수 있습니다. 도움 주셔서 감사합니다. – EamonT22