title: Show image stream from webcam attached to rasberry pi on Android using http server
body: <p>My team and I are working on a robotics project at university. We have a Rasberry Pi to which we attach a webcam and do image processing using OpenCV. The Rasberry Pi does some processing and communicates with an Arduino onboard and the Arduino then goes on to do something useful such as move the robot forward, turn etc. </p>
  
  <p>The project also involves making an Android app which will (amongst other things) be used to control the robot and show a feed of the camera mounted on the robot (connected to Rasberry Pi). My question involves solving the problem of -- showing images from that webcam on my Android App.</p>
  
  <p>For communication, I use bottlePy (<a href="https://bottlepy.org/docs/dev/" rel="nofollow noreferrer">https://bottlepy.org/docs/dev/</a>), a WSGI python framework. The relevant code for this (on Rasberry Pi) is:</p>
  
  <pre><code>from bottle import route, run, template
  from bottle import static_file
  
  @route('/static/&lt;filename&gt;')
  def server_static(filename):
      return static_file(filename, root='./') 
  
  run(host='0.0.0.0', port=8080)
  </code></pre>
  
  <p>This code simply returns an image when I open <a href="http://_ip_:8080/static/image.jpg" rel="nofollow noreferrer">http://<em>ip</em>:8080/static/image.jpg</a>. </p>
  
  <p>Now for getting and saving the image to disk, so that the server can pick it up, I have another script running on the Pi:</p>
  
  <pre><code>import numpy as np
  import cv2
  import time 
  
  while 1:
      cam = cv2.VideoCapture(1)
      s, img = cam.read() # captures image
      cv2.imwrite("image.jpg",img,[int(cv2.IMWRITE_JPEG_QUALITY),50])
      time.sleep(0.1)
  </code></pre>
  
  <p>This script can either be run seperately or I can move this code into my server code, but moving it to the server code gace me issues that I'll explain in a bit with my android code.</p>
  
  <p>The stream on android does not need to be very smooth. But here is what I do:</p>
  
  <p>I create a runnable and use a handler to call the runnable every 100 ms:</p>
  
  <pre><code>runnable = object : Runnable {
          override fun run() {
              /* do what you need to do */
              try {
                  val performBackgroundTask = DownloadImageTask(findViewById(R.id.imageView))
                  // PerformBackgroundTask this class is the class that extends AsynchTask
                  performBackgroundTask.execute("http://$id:8080/static/image.jpg")
              } catch (e: Exception) {
                  // TODO Auto-generated catch block
              }
              /* and here comes the "trick" */
              handler.postDelayed(this, 100)
          }
      }
  </code></pre>
  
  <p>The code for my AsyncTask:</p>
  
  <pre><code>class DownloadImageTask(val bmImage: ImageView) : AsyncTask&lt;String,Void,Bitmap&gt;() {
  
  val tag = "DownloadImageTask"
  
  override fun doInBackground(vararg urls: String?): Bitmap? {
  
      val urldisplay = urls[0]
      var mIcon11: Bitmap? = null
      try {
          val `in` = java.net.URL(urldisplay).openStream()
          if (`in` != null) {
              mIcon11 = BitmapFactory.decodeStream(`in`)
          }
      } catch (e: Exception) {
          Log.e(tag, e.message)
          e.printStackTrace()
      }
  
      return mIcon11
  }
  
  override fun onPostExecute(result: Bitmap?) {
      if (result != null)
          bmImage.setImageBitmap(result)
  }
  }
  </code></pre>
  
  <p>So I simply change the source of my image view. </p>
  
  <p>Now comes the problem, these things don't sync! I get partial images (image blacked from bottom-up to some hight). I believe this is because while the server is sending the image, the script rewrites the image. Basically, I've got a stream working, but like a fluctuation, the stream has bad images. </p>
  
  <p>I thought that I'll only save an image before sending by adding the image saving code into server_static() function. But with that, the server takes time to respond and before it can send an image, another request is added to the queue. And then when I stop the stream in the Android app, by </p>
  
  <pre><code>handler.removeCallbacks(runnable)
  </code></pre>
  
  <p>the server still keeps on sending the images for sometime and any other requests are delayed.</p>
  
  <p>I need a soultion for this or a totally another way to get this done. Help please? (Sorry for the long question)</p>