OpenCV предотвращает обнаружение деревьев - PullRequest
0 голосов
/ 25 марта 2020

У меня есть проект, где я хочу обнаружить кого-нибудь на моей дороге. Поэтому я установил небольшую камеру и создал скрипт python, который использует OpenCV для обнаружения людей, автомобилей и двухколесных транспортных средств с использованием трех различных классификаторов. Я также установил «порог», поэтому обнаруженные объекты / люди должны находиться на дороге, а не только на улице. В основном я обнаруживаю объект / человека и рисую вокруг него рамку. Затем я проверяю для каждого блока в кадре, находится ли он поперек горизонтальной линии (порога), и если это так, отправляется сигнал.

Проблема в том, что вокруг подъездной дороги много зеленых деревья и кусты. Сценарий всегда выбирает некоторые из них как объекты или людей и постоянно вызывает. Я попытался установить некоторые вертикальные границы, в которых объект / человек должен находиться внутри, но из-за того, как проходит дорога, это не работает, поскольку в основном все пересекает эти границы, поэтому система никогда не срабатывает.

У кого-нибудь есть идеи, как я могу помешать сценарию подбирать деревья и кусты или просто найти способ их игнорировать?

Я знаю, что смогу сделать это, сделав пару тысяч снимков за год и затем использовать их для обучения системы, чтобы не обнаруживать деревья, но это, очевидно, не очень практично и занимает вечность. Я всегда могу сделать это, просто собирая изображения во время работы системы, возвращаясь через год и проводя обучение, но в данный момент я ищу более быстрый метод, который я мог бы запустить и запустить в течение нескольких дней.

Редактировать: я добавил absdiff (), чтобы исключить всю зеленую систему, поскольку она, очевидно, не движется много, в то время как машины, велосипеды или люди имеют тенденцию двигаться. Это, однако, создает новую проблему, когда функция absdiff () создает изображения, содержащие движущуюся часть как до, так и после. Поскольку они наложены, это портит обнаружение. Поэтому мне нужно получить изображение, которое содержит только движущуюся часть в один момент ... Я также экспериментировал с методом findContours (), но он не работал вообще.

Это текущий python script:

# OpenCV Python program to detect cars in video frame
# import libraries of python OpenCV
from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import cv2
import RPi.GPIO as GPIO


try:
    #how long the relay stays on:
    OnTime = 5
    #how long to wait until the next recognition:
    WaitTime = 10
    #line hight
    LineHight = 135
    #From Xmin to Xmax
    Xmin = 0
    Xmax = 320

    first = 1
    hasImage = 0

    #initialize the GPIO-Pins
    GPIO.setmode(GPIO.BCM)
    LED_GRN = 2
    LED_RED = 3
    Relay = 4
    GPIO.setup(LED_GRN, GPIO.OUT)
    GPIO.setup(LED_RED, GPIO.OUT)
    GPIO.setup(Relay, GPIO.OUT)

    GPIO.output(LED_GRN, 0)
    GPIO.output(LED_RED, 0)
    GPIO.output(Relay, 0)

    outC = 0
    out = 0
    present = 0
    i = 0
    numImg = 0

    #initialize the camera
    camera = PiCamera()
    camera.resolution = (320, 240)
    camera.framerate = 32
    rawCapture = PiRGBArray(camera, size=(320, 240))

    # Trained XML classifiers describes some features of some object we want to detect
    car_cascade = cv2.CascadeClassifier('cars.xml')
    bike_cascade = cv2.CascadeClassifier('two_wheeler.xml')
    person_cascade = cv2.CascadeClassifier('pedestrian.xml')

    time.sleep(0.1)

    GPIO.output(LED_GRN, 1)

    # loop runs if capturing has been initialized.
    for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
        if hasImage == 0:
            frame1 = frame.array
            rawCapture.truncate(0)
            hasImage = 1
            continue

        # reads frames from a video
        frame2 = frame.array

        # convert both to gray
        gray1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
        gray2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)

        # get difference
        diff = cv2.absdiff(frame2, frame1)
        #print("Diff")

        # just so I don't need to replace all the names
        gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)


        # Detects cars of different sizes in the input image
        cars = car_cascade.detectMultiScale(gray, 1.1, 1)
        bikes = bike_cascade.detectMultiScale(gray, 1.1, 1)
        persons = person_cascade.detectMultiScale(gray, 1.1, 1)

        present = 0

        # To draw a rectangle in each cars
        for (x,y,w,h) in cars:
            cv2.rectangle(frame1,(x,y),(x+w,y+h),(0,0,255),2)
            if (y < LineHight < (y+h)):
                if (x > Xmin):
                    if ((x+w) < Xmax):
                        present = 1

        for (x,y,w,h) in bikes:
            cv2.rectangle(frame1,(x,y),(x+w,y+h),(0,0,255),2)
            if (y < LineHight < (y+h)):
                if (x > Xmin):
                    if ((x+w) < Xmax):
                        present = 1

        for (x,y,w,h) in persons:
            cv2.rectangle(frame1,(x,y),(x+w,y+h),(0,0,255),2)
            if (y < LineHight < (y+h)):
                if (x > Xmin):
                    if ((x+w) < Xmax):
                        present = 1

        cv2.line(frame1, (0,LineHight), (640,LineHight),(0,255,0), 2)
        cv2.line(frame1, (Xmin,0), (Xmin,320), (255,0,0), 2)
        cv2.line(frame1, (Xmax,0), (Xmax,320), (255,0,0), 2)
        cv2.putText(frame1, "Present: " + str(present), (1, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

        if present == 1:
            i = i + 1
            print(str(i) + ": Object/Person detected!")
            GPIO.output(Relay, 1)
            GPIO.output(LED_RED, 1)
            out = 1
            print("Out = 1")
            if i < 100:
                cv2.imwrite("images/image-" + str(i) + ".png", frame1)
                cv2.imwrite("images/image-" + str(i) + "-diff.png", gray)
            else:
                i = 0
        if first == 1:
            cv2.imwrite("images/image-0.png", frame1)
            cv2.imwrite("images/image-0-diff.png", gray)
            print("Wrote first Image!")
            first = 0

        if out == 1:
            outC = outC + 1

        if outC == OnTime:
            outC = 0
            out = 0
            GPIO.output(Relay, 0)
            GPIO.output(LED_RED, 0)
            print("Out = 0")
            time.sleep(WaitTime)

        # Display frames in a window
        #cv2.imshow('Frame', frame1)
        #cv2.imshow('Difference', diff)
        #cv2.imshow('Contours', gray)

        #cv2.imwrite("temp-img/image-" + str(numImg) + ".png", frame1)
        #cv2.imwrite("temp-img/image-" + str(numImg) + "-diff.png", diff)
        #cv2.imwrite("temp-img/image-" + str(numImg) + "-cont.png", gray)
        #numImg = numImg + 1
        #if(numImg > 10):
        #    numImg = 0


        rawCapture.truncate(0)

        frame1 = frame2

        # Wait for Esc key to stop
        if cv2.waitKey(33) == 27:
            GPIO.cleanup()
            break

    # De-allocate any associated memory usage
    cv2.destroyAllWindows()

except KeyboardInterrupt:
    print("Keyboard Interrupt! \nShutting down gracefully...")
except:
    #e = sys.exc_info()[0]
    print("Exception occured! \nSomething probably went wrong! \nShutting down gracefully...")
    raise
finally:
    GPIO.cleanup() #make sure everything is terminated safely

Как видите, он предназначен для работы на малиновом пи, но здесь это не имеет значения.

А вот изображение, созданное системой :

Как вы можете видеть на этом рисунке, у меня есть вертикальные линии, и он обнаруживает все виды вещей, где на самом деле нет ничего, что должно быть обнаружено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...