I am building a robot. Pretty much all my code has been copied from other people's projects on tutorials.
我正在建造一个机器人。几乎所有的代码都是从其他人的教程项目中复制过来的。
I'm using a Raspberry Pi camera to detect faces, and I have this electric Nerf gun, that I want to fire, ONLY after opencv detects a face. Right now, my code fires the Nerf gun no matter if a face is detected or not. Please tell me what I have done wrong? I think the problem is in the if len(faces) > 0
area. Here is all my code.
我正在使用Raspberry Pi相机来检测面部,而且我只有在opencv检测到一张脸后,我才会发射这种电动Nerf枪。现在,无论是否检测到脸,我的代码都会发射Nerf枪。请告诉我我做错了什么?我认为问题出在if len(faces)> 0区域。这是我的所有代码。
program 1, called cbcnn.py
import RPi.GPIO as gpio
import time
def init():
gpio.setmode(gpio.BOARD)
gpio.setup(22, gpio.OUT)
def fire(tf):
init()
gpio.output(22, True)
time.sleep(tf)
gpio.cleanup()
print 'fire'
fire(3)
program 2, called cbfd2.py
程序2,名为cbfd2.py
import io
import picamera
import cv2
import numpy
from cbcnn import fire
#Create a memory stream so photos doesn't need to be saved in a file
stream = io.BytesIO()
#Get the picture (low resolution, so it should be quite fast)
#Here you can also specify other parameters (e.g.:rotate the image)
with picamera.PiCamera() as camera:
camera.resolution = (320, 240)
camera.vflip = True
camera.capture(stream, format='jpeg')
#Convert the picture into a numpy array
buff = numpy.fromstring(stream.getvalue(), dtype=numpy.uint8)
#Now creates an OpenCV image
image = cv2.imdecode(buff, 1)
#Load a cascade file for detecting faces
face_cascade = cv2.CascadeClassifier('/home/pi/cbot/faces.xml /haarcascade_frontalface_default.xml')
#Convert to grayscale
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
#Look for faces in the image using the loaded cascade file
faces = face_cascade.detectMultiScale(gray, 1.1, 5)
print "Found "+str(len(faces))+" face(s)"
if len(faces) > 0:
("fire")
#Draw a rectangle around every found face
for (x,y,w,h) in faces:
cv2.rectangle(image,(x,y),(x+w,y+h),(255,0,0),2)
#Save the result image
cv2.imwrite('result.jpg',image)
3 个解决方案
#1
1
It fires because you have a fire(3)
right after you defined the fire(tf)
function. And the command below only creates a tuple with 1 string value: ("fire")
. It doesn't call the fire function.
它会在您定义fire(tf)函数后立即触发(3)。并且下面的命令只创建一个带有1个字符串值的元组:(“fire”)。它不会调用fire功能。
if len(faces) > 0:
("fire")
If you want to fire only when faces are detected, move that fire(3)
under this IF and remove it from the top.
如果您只想在检测到面部时触发,请在此IF下移动火焰(3)并将其从顶部移除。
BTW you're importing another thing here: from cbcnn import fire
with the same name as your function. This will overwrite your function name and if you put fire(3) below your import line it probably throws an error. Either change you fire function fire(tf)
to fire_rocket(tf)
and change your fire(3)
to fire_rocket(3)
under the IF.
Or add this on your import line (which you actually aren't even using!) and you can keep your fire function name as is:
顺便说一句,你在这里导入另一件事:来自cbcnn import fire,其功能与你的功能相同。这将覆盖您的函数名称,如果您将fire(3)置于导入行下方,则可能会抛出错误。要么将火灾功能火灾(tf)更改为fire_rocket(tf),要将火灾(3)更改为IF下的fire_rocket(3)。或者在你的导入行中添加它(你实际上甚至没有使用它!),你可以保持你的fire函数名称:
from cbcnn import fire as Fire
Edit after question was changed:
Fix the IF I mentioned above and put fire(some number) in there.
The reason it fires is because when you import something from another program it runs the whole script. Because fire(3) is on there it will automatically call the function when you import it.
To avoid this you have to either:
问题改变后编辑:修复上面提到的IF并将火(某些数字)放在那里。它触发的原因是因为当你从另一个程序导入一些东西时它会运行整个脚本。因为fire(3)在那里,它会在你导入时自动调用该函数。要避免这种情况,您必须:
- remove other parts from your cbcnn.py:
print
andfire(3)
从cbcnn.py中删除其他部分:print and fire(3)
Or
-
put those parts in this IF statement to only run them when you actually run cbcnn.py yourself, and not by importing it:
将这些部分放在这个IF语句中,只在你自己实际运行cbcnn.py时运行它们,而不是通过导入它:
if __name__=='__main__': print(fire) fire(3)
#2
0
I already answer you in another post but, where you are putting:
我已经在另一篇文章中回答你了,但是,你要放在哪里:
cv2.rectangle(image,(x,y),(x+w,y+h),(255,0,0),2)
There you can put whatever you want, if you go into the for loop, it means you have detected a face. As you can see on the code you posted, in that case their a drawing a rectangle, but you can do anything there, the x,y,w and h are giving you the coordinates and size of the detected face.
在那里你可以放任何你想要的东西,如果你进入for循环,这意味着你已经检测到了一张脸。正如您在所发布的代码中看到的那样,在这种情况下,他们的绘图是一个矩形,但您可以在那里做任何事情,x,y,w和h将为您提供检测到的面部的坐标和大小。
#3
0
import io
import picamera
import cv2
import numpy
import RPi.GPIO as gpio
import time
#Create a memory stream so photos doesn't need to be saved in a file
stream = io.BytesIO()
#Get the picture (low resolution, so it should be quite fast)
#Here you can also specify other parameters (e.g.:rotate the image)
with picamera.PiCamera() as camera:
camera.resolution = (320, 240)
camera.vflip = True
camera.capture(stream, format='jpeg')
#Convert the picture into a numpy array
buff = numpy.fromstring(stream.getvalue(), dtype=numpy.uint8)
#Now creates an OpenCV image
image = cv2.imdecode(buff, 1)
#Load a cascade file for detecting faces
face_cascade = cv2.CascadeClassifier('/home/pi/cbot/faces.xml/haarcascade_frontalface_default.xml')
#Convert to grayscale
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
#Look for faces in the image using the loaded cascade file
faces = face_cascade.detectMultiScale(gray, 1.1, 5)
print "Found "+str(len(faces))+" face(s)"
#Draw a rectangle around every found face
for (x,y,w,h) in faces:
cv2.rectangle(image,(x,y),(x+w,y+h),(255,0,0),2)
def init():
gpio.setmode(gpio.BOARD)
gpio.setup(22, gpio.OUT)
def fire(tf):
init()
gpio.output(22, True)
time.sleep(tf)
gpio.cleanup()
print 'fire'
fire(3)
#Save the result image
cv2.imwrite('result.jpg',image)
#1
1
It fires because you have a fire(3)
right after you defined the fire(tf)
function. And the command below only creates a tuple with 1 string value: ("fire")
. It doesn't call the fire function.
它会在您定义fire(tf)函数后立即触发(3)。并且下面的命令只创建一个带有1个字符串值的元组:(“fire”)。它不会调用fire功能。
if len(faces) > 0:
("fire")
If you want to fire only when faces are detected, move that fire(3)
under this IF and remove it from the top.
如果您只想在检测到面部时触发,请在此IF下移动火焰(3)并将其从顶部移除。
BTW you're importing another thing here: from cbcnn import fire
with the same name as your function. This will overwrite your function name and if you put fire(3) below your import line it probably throws an error. Either change you fire function fire(tf)
to fire_rocket(tf)
and change your fire(3)
to fire_rocket(3)
under the IF.
Or add this on your import line (which you actually aren't even using!) and you can keep your fire function name as is:
顺便说一句,你在这里导入另一件事:来自cbcnn import fire,其功能与你的功能相同。这将覆盖您的函数名称,如果您将fire(3)置于导入行下方,则可能会抛出错误。要么将火灾功能火灾(tf)更改为fire_rocket(tf),要将火灾(3)更改为IF下的fire_rocket(3)。或者在你的导入行中添加它(你实际上甚至没有使用它!),你可以保持你的fire函数名称:
from cbcnn import fire as Fire
Edit after question was changed:
Fix the IF I mentioned above and put fire(some number) in there.
The reason it fires is because when you import something from another program it runs the whole script. Because fire(3) is on there it will automatically call the function when you import it.
To avoid this you have to either:
问题改变后编辑:修复上面提到的IF并将火(某些数字)放在那里。它触发的原因是因为当你从另一个程序导入一些东西时它会运行整个脚本。因为fire(3)在那里,它会在你导入时自动调用该函数。要避免这种情况,您必须:
- remove other parts from your cbcnn.py:
print
andfire(3)
从cbcnn.py中删除其他部分:print and fire(3)
Or
-
put those parts in this IF statement to only run them when you actually run cbcnn.py yourself, and not by importing it:
将这些部分放在这个IF语句中,只在你自己实际运行cbcnn.py时运行它们,而不是通过导入它:
if __name__=='__main__': print(fire) fire(3)
#2
0
I already answer you in another post but, where you are putting:
我已经在另一篇文章中回答你了,但是,你要放在哪里:
cv2.rectangle(image,(x,y),(x+w,y+h),(255,0,0),2)
There you can put whatever you want, if you go into the for loop, it means you have detected a face. As you can see on the code you posted, in that case their a drawing a rectangle, but you can do anything there, the x,y,w and h are giving you the coordinates and size of the detected face.
在那里你可以放任何你想要的东西,如果你进入for循环,这意味着你已经检测到了一张脸。正如您在所发布的代码中看到的那样,在这种情况下,他们的绘图是一个矩形,但您可以在那里做任何事情,x,y,w和h将为您提供检测到的面部的坐标和大小。
#3
0
import io
import picamera
import cv2
import numpy
import RPi.GPIO as gpio
import time
#Create a memory stream so photos doesn't need to be saved in a file
stream = io.BytesIO()
#Get the picture (low resolution, so it should be quite fast)
#Here you can also specify other parameters (e.g.:rotate the image)
with picamera.PiCamera() as camera:
camera.resolution = (320, 240)
camera.vflip = True
camera.capture(stream, format='jpeg')
#Convert the picture into a numpy array
buff = numpy.fromstring(stream.getvalue(), dtype=numpy.uint8)
#Now creates an OpenCV image
image = cv2.imdecode(buff, 1)
#Load a cascade file for detecting faces
face_cascade = cv2.CascadeClassifier('/home/pi/cbot/faces.xml/haarcascade_frontalface_default.xml')
#Convert to grayscale
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
#Look for faces in the image using the loaded cascade file
faces = face_cascade.detectMultiScale(gray, 1.1, 5)
print "Found "+str(len(faces))+" face(s)"
#Draw a rectangle around every found face
for (x,y,w,h) in faces:
cv2.rectangle(image,(x,y),(x+w,y+h),(255,0,0),2)
def init():
gpio.setmode(gpio.BOARD)
gpio.setup(22, gpio.OUT)
def fire(tf):
init()
gpio.output(22, True)
time.sleep(tf)
gpio.cleanup()
print 'fire'
fire(3)
#Save the result image
cv2.imwrite('result.jpg',image)