udacity / CarND-Behavioral-Cloning-P3

Starting files for the Udacity CarND Behavioral Cloning Project
https://www.udacity.com/drive
MIT License
438 stars 1.71k forks source link

Video error: AttributeError: 'numpy.ndarray' object has no attribute 'save' #11

Closed timtobey closed 7 years ago

timtobey commented 7 years ago

As I wanted to get a video of my finished project. When I run : python drive.py model.h5

Everything runs with no errors

When I run: python drive.py model.h5 run1

I get the following, no images recorded:

Using TensorFlow backend. Creating image folder at run1 RECORDING THIS RUN ... (13220) wsgi starting up on http://0.0.0.0:4567 (13220) accepted ('127.0.0.1', 56919) connect 76398ec1054e40a585d1dbb386eafad8 -0.12403745949268341 0.2 Traceback (most recent call last): File "C:\ProgramData\Anaconda3\envs\carnd-term1\lib\site-packages\eventlet\wsgi.py", line 481, in handle_one_response result = self.application(self.environ, start_response) File "C:\ProgramData\Anaconda3\envs\carnd-term1\lib\site-packages\engineio\middleware.py", line 47, in call return self.engineio_app.handle_request(environ, start_response) File "C:\ProgramData\Anaconda3\envs\carnd-term1\lib\site-packages\socketio\server.py", line 332, in handle_request return self.eio.handle_request(environ, start_response) File "C:\ProgramData\Anaconda3\envs\carnd-term1\lib\site-packages\engineio\server.py", line 230, in handle_request transport, b64) File "C:\ProgramData\Anaconda3\envs\carnd-term1\lib\site-packages\engineio\server.py", line 334, in _handle_connect return s.handle_get_request(environ, start_response) File "C:\ProgramData\Anaconda3\envs\carnd-term1\lib\site-packages\engineio\socket.py", line 80, in handle_get_request start_response) File "C:\ProgramData\Anaconda3\envs\carnd-term1\lib\site-packages\engineio\socket.py", line 119, in _upgrade_websocket return ws(environ, start_response) File "C:\ProgramData\Anaconda3\envs\carnd-term1\lib\site-packages\engineio\async_eventlet.py", line 14, in call return super(WebSocketWSGI, self).call(environ, start_response) File "C:\ProgramData\Anaconda3\envs\carnd-term1\lib\site-packages\eventlet\websocket.py", line 127, in call self.handler(ws) File "C:\ProgramData\Anaconda3\envs\carnd-term1\lib\site-packages\engineio\socket.py", line 185, in _websocket_handler self.receive(pkt) File "C:\ProgramData\Anaconda3\envs\carnd-term1\lib\site-packages\engineio\socket.py", line 49, in receive async=self.server.async_handlers) File "C:\ProgramData\Anaconda3\envs\carnd-term1\lib\site-packages\engineio\server.py", line 357, in _trigger_event return self.handlersevent File "C:\ProgramData\Anaconda3\envs\carnd-term1\lib\site-packages\socketio\server.py", line 489, in _handle_eio_message self._handle_event(sid, pkt.namespace, pkt.id, pkt.data) File "C:\ProgramData\Anaconda3\envs\carnd-term1\lib\site-packages\socketio\server.py", line 428, in _handle_event self._handle_event_internal(self, sid, data, namespace, id) File "C:\ProgramData\Anaconda3\envs\carnd-term1\lib\site-packages\socketio\server.py", line 431, in _handle_event_internal r = server._trigger_event(data[0], namespace, sid, data[1:]) File "C:\ProgramData\Anaconda3\envs\carnd-term1\lib\site-packages\socketio\server.py", line 460, in _trigger_event return self.handlers[namespace][event](args) File "drive.py", line 60, in telemetry image.save('{}.jpg'.format(image_filename)) AttributeError: 'numpy.ndarray' object has no attribute 'save'

domluna commented 7 years ago

@timtobey can I see your drive.py file? Looks like you need to convert image back to an PIL image, my guess is you overrode the image variable with a numpy array. I think image = Image.fromarray(image) or something along those lines should work.

timtobey commented 7 years ago

Thanks Dom, here you go:

drive.zip

domluna commented 7 years ago

Yeah, you are indeed turning the image variable into a numpy array. I'm guessing you want to record the initial image received in that case I would do something like:

        image = Image.open(BytesIO(base64.b64decode(imgString)))
        #crop the image to match model
        width = image.size[0]
        height = image.size[1]
        # Notice we're using image2 here instead of image here
        image2 = image.crop((
            width - 320,
            height - 100,
            width,
            height))
        image2 = np.array(image2)
        #resize image to match model
        image2 = cv2.resize(image2, (80, 25))

        image_array = np.asarray(image2)
        steering_angle = float(model.predict(image_array[None, :, :, :], batch_size=1))

This way image will stay as the original image sent back from the simulator and calling image.save should work as intended.

timtobey commented 7 years ago

Thanks this fixes my problem, the video now works.