Loading...
Logo
Processing Forum
I have an application that needs to pull an image from a webcam.

Copy code
  1. PImage img;

  2. void setup(){
  3.   size(500,500);
  4. }

  5. void draw(){
  6. background(0);  
  7.   img = loadImage("http://10.0.1.4/Jpeg/CamImg0.jpg");
  8.   image(img,0,0);
  9.   
  10. }
When I run it on the desktop it works fine. But if I compile it for Android it seems to slow down a lot. If I add additional elements like 

Copy code
  1. ellipse(mouseX,mouseY,20,20);
they run slowly and don't move very quickly. 

How can I fix this code to make it run more efficient. I'm thinking running on a  different thread or something but the examples I found were too complicated. 

Any ideas?

Thanks

Replies(9)

Put your loadImage in setup - even in Desktop mode.
The way you have it now means you're loading your image every frame.
You only need to load it once, then its set in memory already and you can place it wherever you want with an image() call..
I fully agree with Jesse Scott's advice, but in the case of a webcam, I suppose you want to update the value. Still don't do that on each frame, I don't think you need 60 updates per second. Use millis() to control the interval between two updates.
I need to constantly be updating the image. I set the the frame rate at: frameRate(30).

I tried the mills() option but it still seemed to slow the code. I will post more of the relevant code to make assistance easier. 

Copy code
  1. int timer;
  2. int timerRun = 0;

  3. void draw(){
  4. if (millis() - timer > 500) {
  5. timer = millis();
  6. timerRun = 1;
  7.     }else{
  8.      timerRun = 0;
  9.     }
  10.     
  11.     
  12.     if (timerRun == 1){  
  13. try{
  14.     img = loadImage("http://10.0.1.4/Jpeg/CamImg0.jpg");
  15.       if (img != null) {
  16. img.resize(width,height);
  17.     image(img,0,0);
  18.     }catch (Exception e){
  19.         println("No Video Image");
  20.       }
  21.     }
  22. }
After this code I am trying to control my webcam (Robot) with code like this:

Copy code
  1.  if ((mousePressed) && (mouseX < (width/2)-20) & (mouseX >  (width/2-60)) && (mouseY < (height/2)+20) && (mouseY > (height/2)-20) ){
  2.   println("LEFT"); 
  3.   txt = "cmd: LEFT";
  4.   try {
  5.       client.execute(new HttpGet("http://10.0.1.4:80/rev.cgi?Cmd=nav&action=18&drive=5&speed=5"));
  6. } catch (Exception e) {
  7.       }
  8. }
If I comment out the image part, everything works well and fast. If I leave it in, it becomes slow and almost unusable. 


Hmmm... sorry, I didn't notice the webcam part... skimmed it.
Not really sure about threading on Android either, you'd have to set a new Activity I guess... 

What's your hardware ?
Hardware in what means?

I am programming this all in eclipse so making a new activity may not be so hard. I would have to lookup how to do that though so that I can still use the processing code in it. 
I mean, which device do you have? What is the processor? 
I can see some Android devices being able to handle this better than others... 

What frameRate are you reaching vs. what you are aiming for at 30fps ?

Also, try to test fetching the image without displaying it, and see if that changes your performance - the bottleneck may be the net connection rather than loading the image... 

Alternatively, try to load an image from your data folder every frame in draw, and see if you get the same performance drop without the internet fetching at all...

Run your DDMS debugger ( under /AndroidSDK/tools) while launching and running the sketch too, and it can give you some more verbose console output... 

I would try to place it on a new Activity (but Im just guessing that is how you would thread in Android, i've not tried yet)... but are you currently running everything in Eclipse, with Processing already?
My devices specs are:

Application processor: ARM11 dynamically clocking up to 667 MHz. We also have a micro-controller that powers the screen and accelerometer when the unit is in Standby mode.

Internal flash: 512MB

mDDR: 256MB

DRAM: 128MB

I am not sure what frame rate I was getting, I would assume around less than 10. I am trying to get as fast as it allows me for both control and video. The faster the app is, the easier it is to control the webcam robot. 

I will try the debugging steps later today and let you know how they go. I am also going to try to decrease the cameras image size setting to see if this helps. What should I be looking for in the ddms?

Lastly I am running everything in eclipse already. I am just using the processing Applet so I can write the code using the processing language rather than normal java. I can use normal java for the additional threads/activities if necessary.

I have finally figured out a method that works. I added in a separate thread to handle the fetching of the image. This dramatically sped up the application and unfroze the UI. 

For others with similar ideas, here is some code.

Assuming you have a PImage called img: 

In the Draw() add:
Copy code
  1.    (new ImageLoaderThread()).start();

  2.   if (img!=null){
  3.   image(img, 0, 0);
  4.    }
Then add a new class:

Copy code
  1. class ImageLoaderThread extends Thread
  2. {

  3. public void run()
  4. {
  5.   try{
  6. String imgURL = ("http://cameraIP:port/getsnapshot");
  7.     img = loadImage(imgURL);
  8.     }catch (Exception e){
  9.         println("No Video Image: "+ e);
  10.       }
  11. }
  12. }
Now your url image is constantly updated without slowing up the rest of your application. 
Awesome news! Wasn't sure if threading would work the same way on Android, but good to know!


~ J