如何将输入值从PHP传递到Python文件?

时间:2019-05-09 14:23:31

标签: php python

我目前正在使用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()函数如何真正与输入参数一起使用??

1 个答案:

答案 0 :(得分:0)

Python

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])

PHP

echo "valeur envoye ".$class;

应该是

echo "valeur envoye ".$classe;