简体   繁体   中英

OpenCV Video Capturing & playing issue in Raspberry Pi

I am trying to implement a lane tracking system using Raspberry Pi. Therefore I am processing a video inside Raspberry Pi using OpenCV library (with a python code). But when I am capturing the video, it is lagging and not playing properly. Same code is working fine on the Windows OS environment but not inside the Raspberry Pi. I'd appreciate any help.

Raspberry Pi Hardware specification

Raspberry Pi 3 Model B (1.2Ghz 1GB ram) Camera module v2 (8 megapixel)

import numpy as np
import cv2
import RPi.GPIO as GPIO
import os
import sys
import time
import picamera
import picamera.array

global motorPosition
motorPosition = 0 #1 = left, 2= right, 0= center
rightMotorPin = 17 #pin 11
leftMotorPin = 27 #pin 13
GPIO.setmode(GPIO.BCM)
GPIO.setup(rightMotorPin, GPIO.OUT) #Left
GPIO.setup(leftMotorPin, GPIO.OUT) #Right
GPIO.setwarnings(False)

motorPosition = 0
GPIO.output(leftMotorPin, GPIO.HIGH) #Left = 0
GPIO.output(rightMotorPin, GPIO.HIGH) #Right = 0

def grayscale(img):
    return cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)


def canny(img, low_threshold, high_threshold):
    return cv2.Canny(img, low_threshold, high_threshold)


def gaussian_blur(img, kernel_size):
    return cv2.GaussianBlur(img, (kernel_size, kernel_size), 0)


def region_of_interest(img, vertices):
    mask = np.zeros_like(img)

    if len(img.shape) > 2:
        channel_count = img.shape[2]
        ignore_mask_color = (255,) * channel_count
    else:
        ignore_mask_color = 255

    cv2.fillPoly(mask, vertices, ignore_mask_color)

    masked_image = cv2.bitwise_and(img, mask)
    return masked_image


def get_slope(x1, y1, x2, y2):
    return (y1 - y2) / (x1 - x2)


def draw_lines(img, lines, color=[255, 255, 0], thickness=20):
    global motorPosition
    top = 200
    bottom = 540

    left_x1 = []
    left_y1 = []
    left_x2 = []
    left_y2 = []

    right_x1 = []
    right_y1 = []
    right_x2 = []
    right_y2 = []

    for line in lines:
        for x1, y1, x2, y2 in line:

            slope = get_slope(x1, y1, x2, y2)

            if slope < 0:
                left_x1.append(x1)
                left_y1.append(y1)
                left_x2.append(x2)
                left_y2.append(y2)
            else:
                right_x1.append(x1)
                right_y1.append(y1)
                right_x2.append(x2)
                right_y2.append(y2)

    try:
        avg_right_x1 = int(np.mean(right_x1))
        avg_right_y1 = int(np.mean(right_y1))
        avg_right_x2 = int(np.mean(right_x2))
        avg_right_y2 = int(np.mean(right_y2))

        right_slope = get_slope(avg_right_x1, avg_right_y1, avg_right_x2, avg_right_y2)

        right_y1 = top
        right_x1 = int(avg_right_x1 + (right_y1 - avg_right_y1) / right_slope)
        right_y2 = bottom
        right_x2 = int(avg_right_x2 + (right_y2 - avg_right_y2) / right_slope)

        cv2.line(img, (right_x1, right_y1), (right_x2, right_y2), color, thickness)
    except ValueError:
        pass

    try:
        avg_left_x1 = int(np.mean(left_x1))
        avg_left_y1 = int(np.mean(left_y1))
        avg_left_x2 = int(np.mean(left_x2))
        avg_left_y2 = int(np.mean(left_y2))

        left_slope = get_slope(avg_left_x1, avg_left_y1, avg_left_x2, avg_left_y2)

        left_y1 = top
        left_x1 = int(avg_left_x1 + (left_y1 - avg_left_y1) / left_slope)
        left_y2 = bottom
        left_x2 = int(avg_left_x2 + (left_y2 - avg_left_y2) / left_slope)

        cv2.line(img, (left_x1, left_y1), (left_x2, left_y2), color, thickness)
    except ValueError:
        pass

    left_border = (0, left_y1)
    right_border = (img.shape[1], right_y1)

    color3 = [0, 0, 255]
    color4 = [0, 255, 0]
    thickness3 = 25

    left_diff = left_x1 - left_border[0]
    right_diff = right_border[0] - right_x1
    deviation = left_diff - right_diff

    if deviation < -13 and motorPosition != 2:
        motorPosition = 2
        GPIO.output(leftMotorPin, GPIO.HIGH) #Left = 0
        GPIO.output(rightMotorPin, GPIO.LOW) #Right = 1
        print("leaning right")
        cv2.line(img, (img.shape[1], 0), (img.shape[1], img.shape[0]), color3, thickness3)

    elif deviation > 13 and motorPosition != 1:
        motorPosition = 1
        GPIO.output(leftMotorPin, GPIO.LOW) #Left = 1
        GPIO.output(rightMotorPin, GPIO.HIGH) #Right = 0
        print("leaning left")
        cv2.line(img, (0, 0), (0, img.shape[1]), color3, thickness3)

    elif (deviation >= -15 or deviation <= 15) and motorPosition != 0:
        motorPosition = 0
        GPIO.output(leftMotorPin, GPIO.HIGH) #Left = 0
        GPIO.output(rightMotorPin, GPIO.HIGH) #Right = 0
        print("center")
        cv2.line(img, (0, 0), (0, img.shape[1]), color4, thickness3)
        cv2.line(img, (img.shape[1], 0), (img.shape[1], img.shape[0]), color4, thickness3)


def hough_lines(img, rho, theta, threshold, min_line_len, max_line_gap):
    lines = cv2.HoughLinesP(img, rho, theta, threshold, np.array([]), minLineLength=min_line_len,
                            maxLineGap=max_line_gap)
    line_img = np.zeros((img.shape[0], img.shape[1], 3), dtype=np.uint8)
    draw_lines(line_img, lines)
    return line_img


def weighted_img(img, initial_img, a=0.8, b=1.0, g=0.0):
    return cv2.addWeighted(initial_img, a, img, b, g)


def process_image(image):
    kernel_size = 5

    low_threshold = 200
    high_threshold = 210

    gray = grayscale(image)
    blur = gaussian_blur(gray, kernel_size)
    edges = canny(blur, low_threshold, high_threshold)

    rho = 2
    theta = np.pi / 180
    threshold = 20
    min_line_len = 7
    max_line_gap = 10
    line_image = hough_lines(edges, rho, theta, threshold, min_line_len, max_line_gap)
    result = weighted_img(line_image, image)

    return result
with picamera.PiCamera() as camera:
    with picamera.array.PiRGBArray(camera) as output:
        camera.resolution = (320, 240)
        camera.framerate = 80
        while(1):
            print "\n\n------------------\n\n"
            camera.capture(output, 'bgr')
            try:
                img = output.array
                cv2.waitKey(1)
                output.truncate(0)                

                if 0xFF & cv2.waitKey(5) == 27:
                    break
            except KeyboardInterrupt:
                pass
                print ('KB interrupted')
                print ('Process Aborted!')
                break
            except Exception as e:
                exc_type, exc_obj, tb = sys.exc_info()
                lineno = tb.tb_lineno
                print ('Error : ' + str(e) + " @ line " + str(lineno))
            finally:
                pass
                GPIO.cleanup()
cv2.destroyAllWindows()
GPIO.cleanup()
print ('Aborted')

I reduced the resolution and frame rate and now its working fine

camera.resolution = (176, 144)
camera.framerate = 30

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM