我有一个项目,希望在车道上检测到任何人。因此,我安装了一个小照相机,并创建了一个Python脚本,该脚本利用OpenCV使用三个不同的分类器来检测人员,汽车和两轮车。我还设置了一个“阈值”,因此检测到的物体/人实际上必须在车道上,而不仅仅是在街道上。基本上,我会检测物体/人并在其周围画一个方框。然后,我检查帧中的每个框是否都跨越水平线(阈值),如果是,则发送信号。
问题在于,车道周围有很多绿色植物,例如树木和灌木丛。脚本始终会选择其中一些作为对象或人并不断触发。我试图在对象/人员需要放置的内部设置一些垂直边界,但是由于车道的方式,此方法不起作用,因为基本上所有东西都越过了这些边界,因此系统永远不会触发。
有人知道如何防止脚本拾取树木和灌木丛,或者只是找到忽略它们的方法吗?
我知道我可以做到这一点,每年可以制作几千张照片,而不是使用它们来训练系统以免检测到树木,但这显然不是很实用,而且要花很多时间。我总是可以通过仅在系统运行时收集图像并在一年后回来进行培训来做到这一点,但目前我正在寻找一种可以在几天之内启动并运行的更快的方法。 / p>
编辑:我添加了absdiff()来排除所有绿色,因为在汽车,自行车或人们倾向于移动时,显然不会移动很多。但是,这会产生一个新问题,其中absdiff()函数创建一个图像,该图像包含之前和之后的运动部分。由于这些被覆盖,这使检测混乱。因此,我需要获得一张仅包含移动部分的图像... 我还尝试了findContours()方法,但这根本不起作用。
这是当前的python脚本:
# 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
如您所见,它被设计为在树莓派上运行,但这并不重要。
如您在这张图中所看到的,我有垂直线,它可以检测到各种各样的东西,而实际上根本不需要检测到任何东西。