sarxos / webcam-capture

The goal of this project is to allow integrated or USB-connected webcams to be accessed directly from Java. Using provided libraries users are able to read camera images and detect motion. Main project consist of several sub projects - the root one, which contains required classes, build-in webcam driver compatible with Windows, Linux and Mac OS, which can stream images as fast as your camera can serve them (up to 50 FPS). Main project can be used standalone, but user is able to replace build-in driver with different one - such as OpenIMAJ, GStreamer, V4L4j, JMF, LTI-CIVIL, FMJ, etc.
http://webcam-capture.sarxos.pl
MIT License
2.27k stars 1.11k forks source link

Raspberry, WebcamException: Cannot execute task #192

Open andrej88 opened 10 years ago

andrej88 commented 10 years ago

Hello!

I have some question, my stand is: i'm wirting my code in Eclispe and execute it remote on raspy my lib's are:

bridj-0.7-20131007.003529-54.jar
slf4j-api-1.7.2.jar
webcam-capture-0.3.10-RC6.jar

i had a problem with "OpenIMAJGrabber.so" but solved this with

apt-cache search libv4l
sudo apt-get install libv4l-0 libv4l-dev libv4lconvert0 

my code:

public static void takePicture(String name) throws IOException{
        Webcam webcam = Webcam.getDefault();
        webcam.open(); //!!! problem -.-
        BufferedImage img = webcam.getImage();
        ImageIO.write(img, "PNG", new File(name));
}

and now i can detect my USB cam, but if i want to open it, i get errors:

Exception in thread "main" com.github.sarxos.webcam.WebcamException: Cannot execute task
        at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.process(WebcamProcessor.java:57)
        at com.github.sarxos.webcam.WebcamProcessor.process(WebcamProcessor.java:122)
        at com.github.sarxos.webcam.WebcamTask.process(WebcamTask.java:38)
        at com.github.sarxos.webcam.ds.cgt.WebcamOpenTask.open(WebcamOpenTask.java:20)
        at com.github.sarxos.webcam.Webcam.open(Webcam.java:189)
        at com.github.sarxos.webcam.Webcam.open(Webcam.java:149)
        at hello_world.takePhoto(hello_world.java:60)
        at hello_world.main(hello_world.java:48)
Caused by: java.lang.NullPointerException
        at com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber.startSession(Native Method)
        at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice.open(WebcamDefaultDevice.java:253)
        at com.github.sarxos.webcam.ds.cgt.WebcamOpenTask.handle(WebcamOpenTask.java:38)
        at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.run(WebcamProcessor.java:66)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:724)

you know a hint how i can solve this problem? and maybe you know why i can find just my usb cam, but no Raspy-Cam module?

Thanks,

andrej

sarxos commented 10 years ago

Hi @andrej88,

This is duplicate of #189, #184 and #176, but I haven't had a chance to look into it :(

and maybe you know why i can find just my usb cam, but no Raspy-Cam module

USB cams are recognized by Raspbian as video devices which can be controlled by V4L API, but RasPi camera module is complete different thing and it's controlled by MMAL API. Currently there is no capture driver able to use MMAL or raspivid/still binaries.

andrej88 commented 10 years ago

Hi! thank you for the answer! Will you look next time into it?

Or have you maybe some another idea how i can shoot image with java?

I want to make a photo directly into BufferedImage (take a picture with raspistill take unfortunately to much time). For now it doesn't matter for me if i will take picture with USBcam or Raspy-Cameramodule

Thanks,

andrej

sarxos commented 10 years ago

Hi,

I'm not really sure when I can take a look into it - I have really busy time at work and it's hard for me to manage enough time for this problem (reinstall my Pi OS, prepare dev environment for OpenIMAJ, etc), but I can assure you that this issue is on my priorities list.

I also encourage everyone who knows Java and/or C++ to take a look into this as well - the code is really nice and not hard to understand and the issue may be really trivial after someone debug it.

What I would suggest you to try (I see two options):

Create own capture driver using raspistill in looping mode

The idea is simple - you would have to write your own capture driver for Webcam Capture API and set it in your main(). This driver would simply run raspistill which will run in the looping mode (e.g. 10 FPS) and capture image from your RasPi camera module to JPEG file which is a named pipe. The pipe reader then will see the content of file as MJPEG stream. What you would have to do here is just to reuse the code I wrote some time ago for FFmpeg driver (link) - it works exactly the same way.

The goal of capture driver is to return abstracts for capture device - you can always return the same object representing your RasPi camera module. Here you can find example for listing video devices available for FFmpeg (the USB cameras).

Pipe creation from Java is already done in line 198

Instead of ffmpeg (line 176) you will have to start raspistill:

raspistill -w 640 -h 480 -q 5 -o /tmp/pipename.jpg -tl 100 -t 9999999 -th 0:0:0

Where:

When such driver is set in the Webcam class, you should receive MJPEG frame as a BufferedImage when calling getImage() method.

NOTE! If you like to start this path I may rework the ffmpeg-cli driver to cover raspistill ideas above and put code in separate repository. I cannot guarantee it will work just like that, but you will have some base to start working on, and later, when it's ready, we can integrate it as the official driver.

Recompile OpenIMAJGrabber and hope it will work

Webcam Capture API is using OpenIMAJ binaries to access camera device, so you can try to compile OpenIMAJGrabber and put it in your application's directory - it will be then used instead of the one embedded in JAR. By doing this you will be sure that *.so has been compiled on your environment and there is high probability it should work fine.

The native code from OpenIMAJ framework is available here.

andrej88 commented 10 years ago

Hi! thank you for your answer! Sorry for my late answer, I was working at some another edges of my project, the cam should be the last (and main) part wich I nead to make working. (It doesn't matter for me if it would be the Raspy-Cam or just a USB-cam)

It looks very hard for me, but I think i will try to write own capture driver

How to recompile OpenIMAJGrabber, I dont really know.

Thank you four your help!

sarxos commented 10 years ago

Hey,

If you don't need high FPS and can accept some disadvantages (e.g. blinking webcam diode), you can try to use new driver I wrote lately for command line tool fswebcam.

https://github.com/sarxos/webcam-capture/tree/master/webcam-capture-drivers/driver-fswebcam

And the JAR is here:

https://oss.sonatype.org/content/repositories/snapshots/com/github/sarxos/webcam-capture-driver-fswebcam/0.3.10-SNAPSHOT/webcam-capture-driver-fswebcam-0.3.10-20140314.184120-1.jar

Please note that I haven't test it yet on RasPi (cannot force it to work properly with wi-fi from my laptop's hotspot), but the code is very simple so anyone familiar with Java should be able to fix it when problem appear.

For how to compile OpenIMAJ grabber:

pi@raspberrypi ~ $ dpkg --get-selections | grep -v deinstall | grep -i v4l
libv4l-0:armhf                  install
libv4l-dev:armhf                install
libv4lconvert0:armhf            install
pi@raspberrypi ~ $ dpkg --get-selections | grep -v deinstall | grep -i jpeg
libjpeg8:armhf                  install
libjpeg8-dev:armhf              install

It will report the error:

pi@raspberrypi ~/linux $ ./build-armhf.sh 
cp: cannot create regular file `../../src/main/resources/org/openimaj/video/capture/nativelib/linux_arm32_armhf/': No such file or directory

Don't worry - you can ignore it. The file you are looking for is OpenIMAJGrabber.so. Put it in the running directory of your application - BridJ should pick it automatically instead of the one from JAR.

sarxos commented 10 years ago

Ah, and use BridJ v0.6.3 since Olivier removed ARM support from 0.7 due to some reason.

https://oss.sonatype.org/content/repositories/snapshots/com/nativelibs4java/bridj/0.6.3-SNAPSHOT/bridj-0.6.3-20130316.190111-13.jar

andrej88 commented 10 years ago

Thank you verry much for your help! With this driver i can take a picture and read a qr code from it. at my normal PC it take 20-50ms to take a picture and read a QR code, at raspy it take ~300ms At this time i'm not sure if it can be faster (i can't overclock, i nead to make it electricaly economically) (I didn't tried this thing with OpenIMAJ)

sarxos commented 10 years ago

Hi @andrej88,

Webcam Capture API users reported that they were able to get max 4-5 FPS per second using UVC camera on RasPi using default OpenIMAJ driver so your 300ms on fswebcam is very close to this range. Camera module would be faster of course (I found a note about ~10 FPS), but I do not have driver for it (nor the device itself).