TheImagingSource / tiscamera

The Linux SDK for The Imaging Source cameras.
https://www.theimagingsource.com
Apache License 2.0
299 stars 148 forks source link

Java API <case:443734> #148

Closed beligum closed 6 years ago

beligum commented 6 years ago

On the website, it is mentioned there is a Java API:

For experienced programmers we offer a variety of software libraries and function calls in almost all development languages: C#, Delphi, .net, C++, Python, Java and JavaScript.

I'm looking to use the AFU420-L62 from a Java backend (on Ubuntu 16.04) and I was wondering how I could get my hands on that Java API. Or maybe a simple JNI bridge class, that would be enough.

Any thoughts?

TIS-Stefan commented 6 years ago

Hi

The text you quoted is related to MVTec Halcon Image Processing library, not to the code in the tiscamera repository.

Stefan

beligum commented 6 years ago

I see. I'll have to create one myself then. Thanks for the reply.

b.

TIS-Stefan commented 6 years ago

Hi

I see. I'll have to create one myself then.

Maybe https://github.com/gstreamer-java is a good start. So you can use our GStreamer modules to access the camera.

beligum commented 6 years ago

Yes, I've been using that with success, indeed.

TIS-Stefan commented 6 years ago

OK, then we can close that issue. If you have any questions, please come back!

Stefan

beligum commented 6 years ago

Dear Stefan,

Could you please help me with a little thing I'm trying to accomplish with the Java Gstreamer API. I've implemented this simple example that works great:

String cmd = "tcambin serial=01710176 name=src ! video/x-raw,width=1920,height=1080,framerate=20/1 ! videoconvert";
Bin bin = Bin.launch(cmd, true);

However, when I'm trying to get to the (manual) exposure property of the tcambin element as such:

Element tcamsrc = bin.getElementByName("src");
Logger.info(tcamsrc.get("Exposure"));

I'm getting an Unknown property: Exposure exception. I've found the Python example code in #134 .

When I try to list the properties of the src element as such:

Element tcamsrc = bin.getElementByName("src");
for (String prop : bin.listPropertyNames()) {
    Logger.info("Prop: " + prop);
}

I'm returned with the same properties that are exposed to gstreamer, eg. using gst-inspect-1.0:

Could you hint me towards a way to get to the manual exposure property of the tcambin (or the lower level tcamsrc for that matter)?

best,

b.

beligum commented 6 years ago

As a side note: I'm aware the tcambin element is a wrapper for the lower level tcamsrc that has a tcamautoexposure element in the pipeline and I'm able to reproduce a pipeline where the settings of tcamautoexposure (including auto-exposure, exposure-min and exposure-max) are controllable.

However, I'm wondering how the single manual exposure value of the tcambin element is implemented with regards to the other three properties of tcamautoexposure and/or if they are tied together or not.

TIS-Stefan commented 6 years ago

Hello B.

the "get" function you called does not handle properties. The following should do the job: tcamsrc.get_tcam_property("Exposure");

That is the Python code. Analogue it is tcamsrc.get_tcam_property("Exposure",3333)); for setting a value.

However, I am not sure, since I do not have JAVA installed.

Stefan

beligum commented 6 years ago

Thanks for your feedback. Since I'm using a general GStreamer Java api, I'm afraid I don't have the option of using a tcam-specific method call (the gstreamer-java project has nothing to do with TIS).

I know I'm being difficult here, trying to do it in Java, but could you point me to the implementation of get_tcam_property, so I can take a look what it does, internally, so I can maybe re-implement it with a Java call or maybe write a JNI wrapper for it?

TIS-Edgar commented 6 years ago

Hi, Since our property interface is based on gobject introspection my first approach would be the java specific language bindings. In your case something like JGIR. I have no java experience so I cannot say if that project is usable.

Another approach could be to wrap tcamprop.so to basically create your own wrapper. How feasable that approach is I don't know.

The last thing that comes to mind is to go the ugly route and call tcam-ctrl through a subprocess. Something that can be used as a last resort.

beligum commented 6 years ago

Great, thanks for the options, I'll give it a try and let you know.

beligum commented 6 years ago

Please let me come back to this. I've managed to port large parts of the C++ driver to Java using the JavaCPP project.

For now, I'm not using any GStreamer API, but I'm directly interfacing with the C++ library. Everything works okay, but I get random crashes when I try to do some work in ImageSink's callback code. It seems like the MemoryBuffer object (which I can read out just fine in Java) gets corrupted along the way, especially under heavy load.

Since I'm unfamiliar with the TIS driver, I'm digging through the code, but it would help me a lot if someone more experienced could shed a light on why this is happening. AFAIK, I'm not tampering with the MemoryBuffer object (or it's pointer), i'm just reading out the buffer data. It seems to be a synchronization issue, but I'm not sure.

Could you tell the me "best practice" what to do with the MemoryBuffer object in the sink_callback implementation? (I mean, locking, processing, timing, etc) It would help me a lot.

TIS-Stefan commented 6 years ago

Hello

it can happen under heavy load , that you do not get complete images. The tiscamera modules should drop these incomplete frames, but sometimes, this may fail. Then you can get a segmentation fault.

Do you have an idea, where the error exactly occurs?

Stefan

beligum commented 6 years ago

Hi Stefan,

This is the output i'm getting when things get rough. When this happens, nothing is sent back anymore...

18599242   <WARNING> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:746: Image buffer does not contain enough data. Dropping frame...
18883220   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:914: Can not get buffer to fill with image data. Aborting libusb callback.
19010983   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:914: Can not get buffer to fill with image data. Aborting libusb callback.
19012350   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:914: Can not get buffer to fill with image data. Aborting libusb callback.
19013394   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:914: Can not get buffer to fill with image data. Aborting libusb callback.
19017796   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:914: Can not get buffer to fill with image data. Aborting libusb callback.
19042747   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:914: Can not get buffer to fill with image data. Aborting libusb callback.
19045003   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:914: Can not get buffer to fill with image data. Aborting libusb callback.
19045651   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:914: Can not get buffer to fill with image data. Aborting libusb callback.
19046301   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:914: Can not get buffer to fill with image data. Aborting libusb callback.
19046914   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:914: Can not get buffer to fill with image data. Aborting libusb callback.
19074762   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:914: Can not get buffer to fill with image data. Aborting libusb callback.
0885383   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:865: transfer status 1
40889490   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:865: transfer status 1
40893581   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:865: transfer status 1
40897672   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:865: transfer status 1
40897754   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:865: transfer status 1
40901846   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:865: transfer status 1
40905921   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:865: transfer status 1
40909986   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:865: transfer status 1
40914153   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:865: transfer status 1
40918215   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:865: transfer status 1
40922296   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:865: transfer status 1
40926370   <ERROR> /home/bram/temp/tis/tiscamera_build/src/libusb/AFU420Device.cpp:865: transfer status 1

After that, I receive a device_lost_callback. I guess this means I'm processing too slow, right?

TIS-Stefan commented 6 years ago

Hello

we have a branch "afu420-improvements". You may check that out and try it.

Stefan

beligum commented 6 years ago

Cool, thank you for the feedback. Also, you might be interested in my (native) Java port of your C++ API using the java-cpp framework: https://github.com/beligum/javacpp-presets/tree/master/tiscamera

It's being used in production, so it's quite stable (although the connection with the camera is lost from time to time).

best,

b.

TIS-Stefan commented 6 years ago

Hi b.

Thank you for the feedback and it is good to know, that you got it working.

However, the camera should not disconnect. You may have a look on the cables. Also maybe there is pattern for the disconnect, e.g. vibration or a motor starts or another process arround generates an EMP.

Stefan