Skip to content
This repository has been archived by the owner on Nov 2, 2019. It is now read-only.

Rust binding vs python #1

Closed
lefsky opened this issue Nov 6, 2015 · 21 comments
Closed

Rust binding vs python #1

lefsky opened this issue Nov 6, 2015 · 21 comments

Comments

@lefsky
Copy link

lefsky commented Nov 6, 2015

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
Copy link
Owner

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
Copy link
Author

lefsky commented Nov 6, 2015

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
Copy link
Owner

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

@lefsky
Copy link
Author

lefsky commented Nov 6, 2015

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
Copy link
Owner

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
Copy link
Author

lefsky commented Nov 11, 2015

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
#1 (comment)
.

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
Copy link
Owner

That's reasonable. See the updated README.

@lefsky
Copy link
Author

lefsky commented Nov 11, 2015

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
#1 (comment)
.

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
Copy link
Owner

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.

  1. 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
Copy link
Author

lefsky commented Nov 12, 2015

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.

  1. 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
#1 (comment)
.

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
Copy link
Owner

Sure

@lefsky
Copy link
Author

lefsky commented Nov 13, 2015

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
#1 (comment)
.

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
Copy link
Owner

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

@whitequark
Copy link
Owner

Ok, I will do this today for you.

@whitequark
Copy link
Owner

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
Copy link
Author

lefsky commented Dec 9, 2015

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::is_null::
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 #1.


Reply to this email directly or view it on GitHub
#1 (comment).

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
Copy link
Owner

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

@whitequark
Copy link
Owner

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

@lefsky
Copy link
Author

lefsky commented Dec 10, 2015

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
#1 (comment)
.

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
Copy link
Owner

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

@lefsky
Copy link
Author

lefsky commented Jul 12, 2016

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
#1 (comment),
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

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants