我目前正在使用Pepper Robot拍照,该照片用于通过Windows 10计算机上的yolov3算法(https://github.com/qqwweee/keras-yolo3)从coco_classs中检测对象。我制作了一个可以在Pepper Tablet上使用响应式(html,bootstrap,php,...)的应用程序,以选择要识别的对象。我正在努力将类名值从php传递到名为yolo_video.py的python文件,这很不幸,因为我真的希望机器人指出可以识别的对象,所以我需要与此Python文件进行交互。
要知道的一件事是,我使用Anaconda调用脚本并具有GPU加速功能。
我尝试了每一个命令,将一个值从PHP传递给Python,有时它可以工作,但是在这种情况下,脚本不能完成任务(这很奇怪,因为从命令提示符处调用它可以正常工作)。没有输入,即使从php调用,代码也可以正常工作。
我尝试使用exec()命令,因为它返回了类似数组的值,我可以用来取回python脚本的最后一个打印元素(女巫是需要机器人指向对象的角度信息)
这是yolo_detect.php:
<?php
$classe = $_GET ["choice"];
exec("C:/Anaconda/Scripts/activate yolo && cd C:/wamp64/www/app/projetba3/ && python yolo_video.py --image $who", $value);
echo "valeur envoye ".$class;
var_dump ($value)
?>
您可以看到在使用参数--image激活yolo环境后,我尝试调用yolo_video.py(因为我对机器人拍摄的一张图像进行了识别)。我不知道该论点是否会引起问题?
Yolo_video.py:
import sys
import argparse
from yolo import YOLO, detect_video
from PIL import Image
def detect_img(yolo):
while True:
img = "C:\wamp64\www\App\projetba3\camImage.png"
try:
image = Image.open(img)
except:
print('Open Error! Try again!')
continue
else:
r_image, angle = yolo.detect_image(image,str(classe)) #img passe dans le réseau de neurone
print(angle)
#r_image.show()
r_image.save("C:\wamp64\www\App\projetba3\camerapepper.png")
break;
yolo.close_session()
FLAGS = None
if __name__ == '__main__':
classe = sys.argv[1]
print(sys.argv[1])
# class YOLO defines the default value, so suppress any default here
parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
'''
Command line options
'''
parser.add_argument(
'--model', type=str,
help='path to model weight file, default ' + YOLO.get_defaults("model_path")
)
parser.add_argument(
'--anchors', type=str,
help='path to anchor definitions, default ' + YOLO.get_defaults("anchors_path")
)
parser.add_argument(
'--classes', type=str,
help='path to class definitions, default ' + YOLO.get_defaults("classes_path")
)
parser.add_argument(
'--gpu_num', type=int,
help='Number of GPU to use, default ' + str(YOLO.get_defaults("gpu_num"))
)
parser.add_argument(
'--image', default=True, action="store_true",
help='Image detection mode, will ignore all positional arguments'
)
'''
Command line positional arguments -- for video detection mode
'''
parser.add_argument(
"--input", nargs='?', type=str,required=False,default='./path2your_video',
help = "Video input path"
)
parser.add_argument(
"--output", nargs='?', type=str, default="",
help = "[Optional] Video output path"
)
FLAGS = parser.parse_args()
if FLAGS.image:
"""
Image detection mode, disregard any remaining command line arguments
"""
print("Image detection mode")
if "input" in FLAGS:
print(" Ignoring remaining command line arguments: " + FLAGS.input + "," + FLAGS.output)
detect_img(YOLO(**vars(FLAGS)))
elif "input" in FLAGS:
detect_video(YOLO(**vars(FLAGS)), FLAGS.input, FLAGS.output)
else:
print("Must specify at least video_input_path. See usage with --help.")
您可以看到我使用简单的sys.argv [1]将值放在classe变量中。该值被传输到函数yolo.detect_image(image,str(classe))中的另一个python文件yolo.py。我在函数中添加了我需要的机器人位置的计算。这是函数:
def detect_image(self, image, classe):
start = timer()
if self.model_image_size != (None, None):
assert self.model_image_size[0]%32 == 0, 'Multiples of 32 required'
assert self.model_image_size[1]%32 == 0, 'Multiples of 32 required'
boxed_image = letterbox_image(image, tuple(reversed(self.model_image_size)))
else:
new_image_size = (image.width - (image.width % 32),
image.height - (image.height % 32))
boxed_image = letterbox_image(image, new_image_size)
image_data = np.array(boxed_image, dtype='float32')
print(image_data.shape)
image_data /= 255.
image_data = np.expand_dims(image_data, 0) # Add batch dimension.
out_boxes, out_scores, out_classes = self.sess.run(
[self.boxes, self.scores, self.classes],
feed_dict={
self.yolo_model.input: image_data,
self.input_image_shape: [image.size[1], image.size[0]],
K.learning_phase(): 0
})
print('Found {} boxes for {}'.format(len(out_boxes), 'img'))
font = ImageFont.truetype(font='font/FiraMono-Medium.otf',
size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32'))
thickness = (image.size[0] + image.size[1]) // 300
angle = (0,0)
for i, c in reversed(list(enumerate(out_classes))):
predicted_class = self.class_names[c]
box = out_boxes[i]
score = out_scores[i]
label = '{} {:.2f}'.format(predicted_class, score)
draw = ImageDraw.Draw(image)
label_size = draw.textsize(label, font)
top, left, bottom, right = box
top = max(0, np.floor(top + 0.5).astype('int32'))
left = max(0, np.floor(left + 0.5).astype('int32'))
bottom = min(image.size[1], np.floor(bottom + 0.5).astype('int32'))
right = min(image.size[0], np.floor(right + 0.5).astype('int32'))
print(label, (left, top), (right, bottom))
if str(predicted_class)== classe :
ite =+ 1
if ite == 1 :
centresofa = (left+(right-left)/2,top+(bottom-top)/2)
print (centresofa)
anglehor = 55.2*(centresofa[0]/640)
print (anglehor)
if anglehor > 27.2 :
anglehor = anglehor - 27.2
if anglehor < 27.2 :
anglehor = -(27.2 - anglehor)
else :
anglehor = 0
anglever = 44.3*(centresofa[1]/480)
print(anglever)
if anglever < 22.15 :
anglever = 22.15-anglever
if anglever > 22.15 :
anglever = -(anglever-22.15)
else :
anglever = 0
print ("angle horizontal "+str(anglehor)+"angle vertical "+str(anglever))
angle = (anglehor,anglever)
if top - label_size[1] >= 0:
text_origin = np.array([left, top - label_size[1]])
else:
text_origin = np.array([left, top + 1])
# My kingdom for a good redistributable image drawing library.
for i in range(thickness):
draw.rectangle(
[left + i, top + i, right - i, bottom - i],
outline=self.colors[c])
draw.rectangle(
[tuple(text_origin), tuple(text_origin + label_size)],
fill=self.colors[c])
draw.text(text_origin, label, fill=(0, 0, 0), font=font)
del draw
end = timer()
print(end - start)
return image, angle
我应该将值带回到var_dump($ values)的最后一个元素中,相反,它只向我显示print(sys.argv [1])值,而没有其他显示(表明脚本在启动后就停止了) 。一个更奇怪的事实是他的值是“ --image”(我函数的参数)。我该如何解决这个大问题? exec()函数如何真正与输入参数一起使用??
答案 0 :(得分:0)
python yolo_video.py --image $who
sys.argv[0] = yolo_video.py
sys.argv[1] = --image
sys.argv[2] = $who (classname)
我相信您应该在传递argv[1]
时传递argv[2]
“ --image”作为类名
https://www.pythonforbeginners.com/argv/more-fun-with-sys-argv
此外,您正在尝试将classe
用作detect_img()
中的全局变量。这不是一个好方法,您必须添加一个global
关键字才能使其正常工作。
将detect_img(yolo)
更改为detect_img(yolo, classe)
并将实际的classe变量通过sys.argv[2]
传递给函数
Line 83: detect_img(YOLO(**vars(FLAGS)), sys.argv[2])
echo "valeur envoye ".$class;
应该是
echo "valeur envoye ".$classe;