whitequark / rust-touptek

Rust bindings for Touptek ToupLite image acquisition library
MIT License
6 stars 1 forks source link

Rust binding vs python #1

Closed lefsky closed 8 years ago

lefsky commented 8 years ago

I am a scientist who needs access to the touptek library but would prefer not to work through C++. I am working with a set of bindings through python but its behavior is unpredictable, possibly because the callback mechanism isn't working very well.

How stable is your set of bindings in Rust? I don't know anything about Rust but I was able to get it installed under OSX and was able to build the touptek library but when I tested it, it was unable to link to the touptek sdk library. Does it need to be in a specific directory?

whitequark commented 8 years ago

I would say the bindings are stable and pretty much finished by this point; only Toupcam_GetHistogram and Toupcam_deBayer are not exposed yet. I've used them quite a bit in an unpublished project.

I've not tested it on OS X but it will look for libtoupcam.dylib in all library directories: https://github.com/whitequark/rust-touptek/blob/master/src/lib.rs#L220; on Linux, the Toupcam SDK installs itself into /usr/lib.

lefsky commented 8 years ago

Ok, that part worked- sorry for the simple question but in the other languages I've tried (python, VS C++) it look locally.

Question two: When I build the program you have on the main rust-touptek page, it gives me the result:

nrel-lefsky2:touptest ceal$ Cargo build
   Compiling touptest v0.1.0 (file:///Users/ceal/touptest)
src/main.rs:16:14: 16:15 error: unexpected token: `,`
src/main.rs:16             },
                            ^
Could not compile `touptest`.

Ok, so remove the "," and:

nrel-lefsky2:touptest ceal$ Cargo build
   Compiling touptest v0.1.0 (file:///Users/ceal/touptest)
src/main.rs:5:9: 22:6 error: no method named `start` found for type `core::option::Option<touptek::Toupcam>` in the current scope
src/main.rs: 5     cam.start(
src/main.rs: 6         |event| {
src/main.rs: 7             match event {
src/main.rs: 8                 touptek::Event::Image => {
src/main.rs: 9                     let image = cam.pull_image(8);
src/main.rs:10                     println!("captured a {}x{} image",
               ...
src/main.rs:9:37: 9:50 error: no method named `pull_image` found for type `core::option::Option<touptek::Toupcam>` in the current scope
src/main.rs:9                     let image = cam.pull_image(8);
                                                  ^~~~~~~~~~~~~
src/main.rs:11:30: 11:41 error: the type of this value must be known in this context
src/main.rs:11                              image.width, image.height);
                                            ^~~~~~~~~~~
<std macros>:2:25: 2:56 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
src/main.rs:10:21: 11:57 note: in this expansion of println! (defined in <std macros>)
error: aborting due to 3 previous errors
Could not compile `touptest`.

I looked for obvious errors in the rust-touptek source but didn't find them. Can you assist?

whitequark commented 8 years ago

I forgot to update README after some API changes--should be fixed now.

lefsky commented 8 years ago

Ok, this solved the compiling and running but when I run it there is no output- by putting in println! statements, it seems the Match event... line is never reached.

Short of learning Rust and figuring out how to debug this (which I don't have the time for) do you have any suggestions? It seems the event it is looking for isn't appearing. Is there a simple way to figure out what events (if any) are being

whitequark commented 8 years ago

I'm really sorry--I should have tested it before committing. I've now verified that the example works with a real camera. Otherwise, you can replace the _ => () line with event => println!("{:?}", event).

lefsky commented 8 years ago

The code appears to be working now, but I can't be sure because I can't see the images it is producing. If it isn't too much to ask, could you show me how to export the image to a standard image format (e.g. png)?

On Fri, Nov 6, 2015 at 7:58 PM, whitequark notifications@github.com wrote:

I'm really sorry--I should have tested it before committing. I've now verified that the example works with a real camera. Otherwise, you can replace the _ => () line with event => println!("{:?}", event).

— Reply to this email directly or view it on GitHub https://github.com/whitequark/rust-touptek/issues/1#issuecomment-154607402 .

Michael Lefsky Center for Ecological Applications of Lidar College of Natural Resources Colorado State University http://www.researcherid.com/rid/A-7224-2009

If I were creating the world I wouldn't mess about with butterflies and daffodils. I would have started with lasers, eight o'clock, Day One! - Time Bandits

whitequark commented 8 years ago

That's reasonable. See the updated README.

lefsky commented 8 years ago

Mr. Quark,

Thanks for updating the program- it seems to be working (although I need to go to my office to turn on the illumination to make sure).

Based on what I've seen on your website, it seems you are heavily involved in software development and the fact that you were working with a microscope camera suggests you have some interest in scientific applications.

I have a modest sized project that could use your rust interface to control a series of touptek cameras. I'd like to gauge your interest in working with me, but before I describe it, I want to say upfront that if you were interested in contributing that I would want to compensate you in some way.

The project involves the building of a scanner for aerial photography. I am a forest ecologist and remote sensing scientist by training and I want to make historic aerial photos available to a wider audience. The use of aerial photos is limited by the absence of a manufacturer of aerial film scanners capable of the high geometric precision required for photogrammetric applications. The few manufacturers who build these scanners have all discontinued them, and the cost of used scanners is prohibitive- $50K and up. I have a design for a scanner that can be built for $5k with performance equal to that of these used systems. I have experience in scientific programming and image processing, but not in the programming required to work at the level required to interface with the cameras.

I have been using a set of python bindings to the touptek library that Jake Ross put together as part of a larger project ( https://github.com/NMGRL/pychron). In general, the bindings are stable but the drawback to python is that the callback mechanism in python is slow and so the time it takes to capture a single image is high- about 1 image per second. Most of that time is spent setting up the callback and waiting for a response. Your implementation seems to be running at a small fraction of a second, but it is too fast for me to know exactly.

I can think of two ways that your rust program could be integrated with my existing work in a simple way:

1) It seems to me that I could adjust most of the camera level settings (i.e. contrast) using the python interface and then pass the handle and a pointer to a buffer for the resulting image to a rust library that would use the handle to retrieve the image and put it in the buffer.

2) My other idea is that a self-contained rust program could be used that would take a text file of image settings and execute the requested image captures.

But honestly, I don't have the background to evaluate these ideas properly.

Is this something you would consider participating in? In any case, thanks again for your generosity with your time.

Michael

On Wed, Nov 11, 2015 at 3:37 AM, whitequark notifications@github.com wrote:

That's reasonable. See the updated README.

— Reply to this email directly or view it on GitHub https://github.com/whitequark/rust-touptek/issues/1#issuecomment-155730555 .

Michael Lefsky Center for Ecological Applications of Lidar College of Natural Resources Colorado State University http://www.researcherid.com/rid/A-7224-2009

If I were creating the world I wouldn't mess about with butterflies and daffodils. I would have started with lasers, eight o'clock, Day One! - Time Bandits

whitequark commented 8 years ago

On 2015-11-11 20:23, lefsky wrote:

Mr. Quark,

Thanks for updating the program- it seems to be working (although I need to go to my office to turn on the illumination to make sure).

I've tested the very example code with my camera and it correctly captures images, although it is certainly not inconceivable that something could go wrong with your one.

Based on what I've seen on your website, it seems you are heavily involved in software development and the fact that you were working with a microscope camera suggests you have some interest in scientific applications.

True. In fact I am currently working on software and firmware for quantum computers on a NIST grant.

[snip] I have been using a set of python bindings to the touptek library that Jake Ross put together as part of a larger project ( https://github.com/NMGRL/pychron). In general, the bindings are stable but the drawback to python is that the callback mechanism in python is slow and so the time it takes to capture a single image is high- about 1 image per second. Most of that time is spent setting up the callback and waiting for a response. Your implementation seems to be running at a small fraction of a second, but it is too fast for me to know exactly.

This is to be expected. In fact the Rust bindings used to run about as slowly in debug mode, though for completely different reasons, and it took me a patch to the compiler1 to make them fast enough to actually debug.

The application that I am using these bindings for can stream imagery and display it using OpenGL essentially in realtime; during my tests I have more often bumped into the exposure time limit than processing performance.

I can think of two ways that your rust program could be integrated with my existing work in a simple way:

1) It seems to me that I could adjust most of the camera level settings (i.e. contrast) using the python interface and then pass the handle and a pointer to a buffer for the resulting image to a rust library that would use the handle to retrieve the image and put it in the buffer.

This is possible, but fragile and fairly contrived, as well as nonportable and hard to debug.

2) My other idea is that a self-contained rust program could be used that would take a text file of image settings and execute the requested image captures.

This would be much simpler, and the time required to implement and verify this program is at most a few hours. I can write it for you free of charge if you provide a specification of the input data (it's not really worth bothering with payment for something so trivial).

whitequark

lefsky commented 8 years ago

Thank you for your offer. Before we proceed, I verified that your program is working however, it is taking 3-4 seconds to run. I ran perf and "libz" is accounting for 80%+ of the time required. I assume this is for compression of the png. Is it possible to have the image written in an uncompressed format?

M

On Wed, Nov 11, 2015 at 10:42 AM, whitequark notifications@github.com wrote:

On 2015-11-11 20:23, lefsky wrote:

Mr. Quark,

Thanks for updating the program- it seems to be working (although I need to go to my office to turn on the illumination to make sure).

I've tested the very example code with my camera and it correctly captures images, although it is certainly not inconceivable that something could go wrong with your one.

Based on what I've seen on your website, it seems you are heavily involved in software development and the fact that you were working with a microscope camera suggests you have some interest in scientific applications.

True. In fact I am currently working on software and firmware for quantum computers on a NIST grant.

[snip] I have been using a set of python bindings to the touptek library that Jake Ross put together as part of a larger project ( https://github.com/NMGRL/pychron). In general, the bindings are stable but the drawback to python is that the callback mechanism in python is slow and so the time it takes to capture a single image is high- about 1 image per second. Most of that time is spent setting up the callback and waiting for a response. Your implementation seems to be running at a small fraction of a second, but it is too fast for me to know exactly.

This is to be expected. In fact the Rust bindings used to run about as slowly in debug mode, though for completely different reasons, and it took me a patch to the compiler1 to make them fast enough to actually debug.

The application that I am using these bindings for can stream imagery and display it using OpenGL essentially in realtime; during my tests I have more often bumped into the exposure time limit than processing performance.

I can think of two ways that your rust program could be integrated with my existing work in a simple way:

1) It seems to me that I could adjust most of the camera level settings (i.e. contrast) using the python interface and then pass the handle and a pointer to a buffer for the resulting image to a rust library that would use the handle to retrieve the image and put it in the buffer.

This is possible, but fragile and fairly contrived, as well as nonportable and hard to debug.

2) My other idea is that a self-contained rust program could be used that would take a text file of image settings and execute the requested image captures.

This would be much simpler, and the time required to implement and verify this program is at most a few hours. I can write it for you free of charge if you provide a specification of the input data (it's not really worth bothering with payment for something so trivial).

whitequark

— Reply to this email directly or view it on GitHub https://github.com/whitequark/rust-touptek/issues/1#issuecomment-155858177 .

Michael Lefsky Center for Ecological Applications of Lidar College of Natural Resources Colorado State University http://www.researcherid.com/rid/A-7224-2009

If I were creating the world I wouldn't mess about with butterflies and daffodils. I would have started with lasers, eight o'clock, Day One! - Time Bandits

whitequark commented 8 years ago

Sure

lefsky commented 8 years ago

I think I can make do with just a few changes and specified parameters.

  1. I need to be able to select the camera by index. This is an undocumented function that is referenced in toupcam.h:

toupcam_ports(HToupCam) Toupcam_OpenByIndex(unsigned index);

  1. I need to be able to manipulate the exposure time and gain:

    fn Toupcam_put_ExpoTime(h: mut Handle, Time: c_uint) -> HRESULT; fn Toupcam_put_ExpoAGain(h: mut Handle, AGain: c_ushort) -> HRESULT;

So I'd like to pass a text file with the following fields:

camera_index, ExpoTime, ExpoAGain, Filename

and return an uncompressed image.

I hope this is enough information.

M

On Wed, Nov 11, 2015 at 5:07 PM, whitequark notifications@github.com wrote:

Sure

— Reply to this email directly or view it on GitHub https://github.com/whitequark/rust-touptek/issues/1#issuecomment-155952673 .

Michael Lefsky Center for Ecological Applications of Lidar College of Natural Resources Colorado State University http://www.researcherid.com/rid/A-7224-2009

If I were creating the world I wouldn't mess about with butterflies and daffodils. I would have started with lasers, eight o'clock, Day One! - Time Bandits

whitequark commented 8 years ago

Yeah that would be enough. I'll do it once I have time.

whitequark commented 8 years ago

Ok, I will do this today for you.

whitequark commented 8 years ago

Done: https://github.com/whitequark/touptek-acquire.

Please file any remaining issues at that repository.

Note that I've moved and no longer have access to a Touptek camera, so I could not run the program to verify that it works (but it should).

lefsky commented 8 years ago

The program does work and appears to be robust.

Unfortunately, it is taking about 2 seconds per image rather than the 1 second that your previous version of the program achieved. Whereas "perf" indicated that the old version spent the majority of running time doing the work of image compression, I don't see where there is any obvious task that takes the majority of time with the new version:

33.34% touptek-acquire touptek-acquire [.] slice::IterMut$LT$$u27$a$C$$u2 31.22% touptek-acquire libtoupcam.so [.] 0x00000000004ba81f 11.11% touptek-acquire touptek-acquire [.] ptr::_$BP$mut$u20$T::isnull:: 7.34% touptek-acquire touptek-acquire [.] ptr::$BP$mut$u20$T::offset::h 5.07% touptek-acquire touptek-acquire [.] vec::Vec$LT$T$GT$.Drop::drop::

1/3 of the time is in libtoupcam.so (which isn't under your control) and another 1/3 of the time is spent doing "slice".

Is there some obvious way to accelerate the program? If not, then what you've done is enough for me to move forward.

Thanks.

M

On Thu, Nov 26, 2015 at 7:34 PM, whitequark notifications@github.com wrote:

Closed #1 https://github.com/whitequark/rust-touptek/issues/1.

— Reply to this email directly or view it on GitHub https://github.com/whitequark/rust-touptek/issues/1#event-475977368.

Michael Lefsky Center for Ecological Applications of Lidar College of Natural Resources Colorado State University http://www.researcherid.com/rid/A-7224-2009

If I were creating the world I wouldn't mess about with butterflies and daffodils. I would have started with lasers, eight o'clock, Day One! - Time Bandits

whitequark commented 8 years ago

Are you sure you've built it with optimizations (cargo run --release)?

whitequark commented 8 years ago

Ah, of course not, since that's what I wrote in README. I have updated that.

lefsky commented 8 years ago

Mr. Quark,

Just cut the time in half, and 78% of the time is spend in the libtoupcam.so library! That's efficiency for sure!

Thanks so much for all your help

M

On Wed, Dec 9, 2015 at 7:24 PM, whitequark notifications@github.com wrote:

Ah, of course not, since that's what I wrote in README. I have updated that.

— Reply to this email directly or view it on GitHub https://github.com/whitequark/rust-touptek/issues/1#issuecomment-163465657 .

Michael Lefsky Center for Ecological Applications of Lidar College of Natural Resources Colorado State University http://www.researcherid.com/rid/A-7224-2009

If I were creating the world I wouldn't mess about with butterflies and daffodils. I would have started with lasers, eight o'clock, Day One! - Time Bandits

whitequark commented 7 years ago

@lefsky Did you ever use this code for something interesting? I am curious.

lefsky commented 7 years ago

I adapted your code to run multiple cameras with the ability to read in a setup file and output a "metadata" file on the resulting image. I am hoping to keep using your program for communication with the cameras for some time.

I'll let you judge if that's interesting.

M

On Tue, Jul 12, 2016 at 8:52 AM, whitequark notifications@github.com wrote:

@lefsky https://github.com/lefsky Did you ever use this code for something interesting? I am curious.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/whitequark/rust-touptek/issues/1#issuecomment-232072723, or mute the thread https://github.com/notifications/unsubscribe/AMRY5NvqS2CEOvBZXClKqpP2A0qxUEs4ks5qU6pHgaJpZM4GdIAz .

Michael Lefsky Center for Ecological Applications of Lidar College of Natural Resources Colorado State University http://www.researcherid.com/rid/A-7224-2009

If I were creating the world I wouldn't mess about with butterflies and daffodils. I would have started with lasers, eight o'clock, Day One! - Time Bandits