Thread: [libdc1394-devel] Camwire - generic camera API
Capture and control API for IIDC compliant cameras
Brought to you by:
ddouxchamps,
gordp
From: Johann S. <j.s...@ir...> - 2004-03-25 03:02:17
|
Hi List I have today released Camwire under LGPL: http://kauri.auck.irl.cri.nz/~johanns/software.html Camwire defines a set of C functions that provides the basic functions needed to control a digital camera from a computer. It is primarily intended for C programmers who would like to work at a higher level of abstraction than the low-level camera libraries and drivers. The main functions are: * Run/stop camera * Single-shot/continuous mode * Trigger source internal/external * External trigger polarity rising/falling * Frame rate * Shutter speed * Frame dimensions width/height/depth * Frame offset left/top * Number of frame buffers * Capture a frame by waiting/polling/copying * Get time stamp of last frame * Get serial number of last frame * Flush frame buffers * Reset camera * etc. I wrote Camwire because I found that libdc1394 is very closely wrapped around the IIDC DCAM spec and I needed something simpler. Eventually it was over 7000 lines of code. Camwire hides a lot of libdc1394's internal details. Camwire's interface is implementation-independent in the sense that the user (mostly) need not know or care whether the camera is on a Firewire, USB, CameraLink, or whatever. Of course it uses 1394 under the covers but almost nothing in the interface mentions that. Camwire reads simple text files for initial camera configurations and settings. Camwire tries to autodetect the supported formats, modes and features of the camera, and it suggests best-guess DCAM CSR configuration and camera settings. No more guessing which format/mode to try just to get a new camera going. There is an extended example of how to use Camwire in the examples subdirectory, called cammonitor. It is a command-line-based camera monitor which is useful in its own right. It even has a man page. Please send suggestions, bug reports and fixes to me. Developers are invited to extend Camwire to other buses like USB and CameraLink. If that happens we may decide to put the project on Sourceforge. Thanks to Damien Douxchamps and Dan Dennedy for applying my libdc1394 patches to get Camwire working the way I like it. Johann -- ^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^ Johann Schoonees Imaging & Sensing Team Industrial Research Limited, PO Box 2225, Auckland, New Zealand Phone +64 9 9203679 Fax +64 9 3028106 http://www.is.irl.cri.nz/ |
From: Brad <br...@je...> - 2004-03-26 02:45:29
|
I like the idea behind Camwire, but I was thinking that if you are wanting a significant base of imaging devices to interface with I could suggest a few changes that could be made. Almost all of these are based on my opinion and past experiences in working with scientifc and other types of imaging. I would like to apologise in advance if you are not wanting to get a list of what people would think an optimal API would look like in which case you may stop reading. The basis of this email is based solely on my opinion and experiences of what I would consider to be my API of choice. I'm looking at the API from the perspective that it is an API should control a Camera (Digital SLR, Scientific, Machine Vision, Microscopy, etc ...) regardless of type, feature set or interface (Firewire (IIDC, proprietary), USB, FrameGrabber, ...) with a computer. Additionally, it is my opinion that it should also be possible to extend such an API to other Operating Systems should that be a desire (Mac, Windows, VxWorks, whatever.) GENERIC CAMERA INTERFACE MODULES It would probably be a good and easy to implement style if we wrote the generic Camera API to use DSO's to call the appropriate interface types. For example, there could be an IIDC dso that knew how to talk to IIDC cameras, one for USB and so on. The Generiic Camera API could then look in a specific location (say /opt/camwire/dso) for modules that represent camera interfaces. It would make other people / parties job easier to interface their API / Camera system with the Generic Camera API without having to actually modify the API itself. SETTING AND GETTING CAMERA FEATURES / SETTINGS I believe that having seperate functions to set the different settings that the camera may be set to is a little overkill. When camera's support features like Roi's (Some Multiple Roi's), Readout Speeds, Binning Modes, Trigger Types, Shutter Modes, Image Formats (etc...) having a seperate function for each possible setting becomes a lot of work to maintain and implement, especially when you try to find what values (range or sparse) are actually supported by the camera. Myself I would structure that part of the code as a function that is able to set a structure that contains the actual settings that will be stored (should be opaque.) The actual function that sets the structure would accept an enumeration that describes which parameter or setting is being set by the function. Operating in this manner we have an API that does not have to change much as new features are supported in terms of the actual API (just add new enumerations.) Additionally, we could add a function to report the largest supported enumeration along with its textual name for user applications so that some applications (using those functions) wouldn't have to be recompiled to use new camera features as they come out and the lower layers are updated. Additionally, for settings such as Triggering I would enumerate them to allow to set the following types: Edge High, Edge Low, Pulse High, Pulse Low, Software and (None or Internal or Freerun...) intead of seperate functions to set edge state, and enable external or internal trigger (cause there are other types than just external and multiple external types.) -- Here is an example of how I would interface to settings changes // These of course will have other typed functions such as u64 and s32. set_parameter_u32 (tcamera_settings*, tcamera_parameter, uint32 parameter) get_parameter_u32 (tcamera_settings*, tcamera_parameter, uint32* parameter) is_parameter_supported_u32 (tcamera_settings*, tcamera_parameter) is_parameter_sparse_table_u32 (tcamera_settings*, tcamera_parameter) is_parameter_range_table_u32 (tcamera_settings*, tcamera_parameter) get_parameter_sparse_table_u32 (tcamera_settings*, tcamera_parameter, uint32* ptable, uint32 usize) get_parameter_range_table_u32 (tcamera_settings*, tcamera_parameter, uint32* ptable, uint32 usize) // Send the settings to the camera to be used. send_settings_to_camera (tcamera_handle, tcamera_settings*); get_default_settings (tcamera_handle, tcamera_settings*) -- End example settings interface Some cameras have things like intensity and scale of the image change from normal change as certain settings are enabled. We may want to have a function to handle that. Maybe something like get_x_scale_from_normal, get_x_intensity_from_normal or something similar would be appropriate. Settings such as Binning modify the intensity and features such as faster viewing modes (A faster view mode at a lower quality.) affects both intensity and scaleing. I have not seen any API's that have functions to support this, but have dealt with ones that state with Camera X and setting Y use scale of 1.4, but Camera Z and Setting Y use scale of 1.6. OPENING AND CLOSING CAMERAS What we could do here is have an list_cameras function that lists all cameras found on the system. (1394, USB, Framegrabber Cameras would all appear on the same list.) and the user application could select which camera to use when calling open_camera(cameraid) RETRIEVING FRAMES From your interface it looks as if Camwire owns the buffers that the frames are copied into (the number set by the calling application.) I think that it would be better if the frames were in fact owned by the calling application and that the calling application could queue frames up as it wanted. For ease of use there could be a synchronous version of the frame retrieval that could be called grab_frame or grab_frame_sync. We could then to an asynchronous version of frame retrieval that would be faster and could just use queues internally to hold onto the frame. Upon completion of the frame being filled, a callback is called. Of course we would need a function like abort_frames or cancel_frames incase the user wanted to cease operation. These are my opinions. Please let me know what you think. If you like my ideas, have questions or would like more detailed descriptions feel free to mail me on or off list. Regards, Brad (br...@je...) Johann Schoonees wrote: > Hi List > > I have today released Camwire under LGPL: > > http://kauri.auck.irl.cri.nz/~johanns/software.html > > Camwire defines a set of C functions that provides the basic functions > needed to control a digital camera from a computer. It is primarily > intended for C programmers who would like to work at a higher level of > abstraction than the low-level camera libraries and drivers. > > The main functions are: > > * Run/stop camera > * Single-shot/continuous mode > * Trigger source internal/external > * External trigger polarity rising/falling > * Frame rate > * Shutter speed > * Frame dimensions width/height/depth > * Frame offset left/top > * Number of frame buffers > * Capture a frame by waiting/polling/copying > * Get time stamp of last frame > * Get serial number of last frame > * Flush frame buffers > * Reset camera > * etc. > > I wrote Camwire because I found that libdc1394 is very closely wrapped > around the IIDC DCAM spec and I needed something simpler. Eventually > it was over 7000 lines of code. Camwire hides a lot of libdc1394's > internal details. > > Camwire's interface is implementation-independent in the sense that > the user (mostly) need not know or care whether the camera is on a > Firewire, USB, CameraLink, or whatever. Of course it uses 1394 under > the covers but almost nothing in the interface mentions that. > > Camwire reads simple text files for initial camera configurations and > settings. Camwire tries to autodetect the supported formats, modes > and features of the camera, and it suggests best-guess DCAM CSR > configuration and camera settings. No more guessing which format/mode > to try just to get a new camera going. > > There is an extended example of how to use Camwire in the examples > subdirectory, called cammonitor. It is a command-line-based camera > monitor which is useful in its own right. It even has a man page. > > Please send suggestions, bug reports and fixes to me. Developers are > invited to extend Camwire to other buses like USB and CameraLink. If > that happens we may decide to put the project on Sourceforge. > > Thanks to Damien Douxchamps and Dan Dennedy for applying my libdc1394 > patches to get Camwire working the way I like it. > > Johann > |
From: Johann S. <j.s...@ir...> - 2004-03-28 22:47:28
|
Hi Brad Thanks for your insights and comments. It's good to have someone look at it from a fresh perspective. Camwire started out as a modest little wrapper around libdc1394 for some of my colleagues who did not want to spend any time learning aobut IEEE 1394 things. So from the outset it was meant to be simple rather than comprehensive. I appreciate that your proposed changes need not add much complexity to the interface and may even simplify it in places. It will however require a major rewrite of much of the code. I don't have much time myself to extend and improve Camwire. It now does more or less what we originally wanted it to do. I suspect that it will also be sufficient for many others and that is why I made it publically available. I would be happy to implement submitted patches. I would also be happy if anyone wanted to take the code further into a bigger project. Perhaps we may decide to split the project into a keep-it-simple original-but-limited version and a more ambitious and flexible version which hides the implementation details behind DSOs. What do you think? Regards, Johann Brad wrote: > I like the idea behind Camwire, but I was thinking that if you are > wanting a significant base of imaging devices to interface with I could > suggest a few changes that could be made. Almost all of these are based > on my opinion and past experiences in working with scientifc and other > types of imaging. > > I would like to apologise in advance if you are not wanting to get a > list of what people would think an optimal API would look like in which > case you may stop reading. > > The basis of this email is based solely on my opinion and experiences of > what I would consider to be my API of choice. I'm looking at the API > from the perspective that it is an API should control a Camera (Digital > SLR, Scientific, Machine Vision, Microscopy, etc ...) regardless of > type, feature set or interface (Firewire (IIDC, proprietary), USB, > FrameGrabber, ...) with a computer. Additionally, it is my opinion that > it should also be possible to extend such an API to other Operating > Systems should that be a desire (Mac, Windows, VxWorks, whatever.) > > GENERIC CAMERA INTERFACE MODULES > It would probably be a good and easy to implement style if we wrote the > generic Camera API to use DSO's to call the appropriate interface > types. For example, there could be an IIDC dso that knew how to talk to > IIDC cameras, one for USB and so on. The Generiic Camera API could then > look in a specific location (say /opt/camwire/dso) for modules that > represent camera interfaces. It would make other people / parties job > easier to interface their API / Camera system with the Generic Camera > API without having to actually modify the API itself. > > SETTING AND GETTING CAMERA FEATURES / SETTINGS > I believe that having seperate functions to set the different settings > that the camera may be set to is a little overkill. When camera's > support features like Roi's (Some Multiple Roi's), Readout Speeds, > Binning Modes, Trigger Types, Shutter Modes, Image Formats (etc...) > having a seperate function for each possible setting becomes a lot of > work to maintain and implement, especially when you try to find what > values (range or sparse) are actually supported by the camera. > > Myself I would structure that part of the code as a function that is > able to set a structure that contains the actual settings that will be > stored (should be opaque.) The actual function that sets the structure > would accept an enumeration that describes which parameter or setting is > being set by the function. Operating in this manner we have an API that > does not have to change much as new features are supported in terms of > the actual API (just add new enumerations.) > > Additionally, we could add a function to report the largest supported > enumeration along with its textual name for user applications so that > some applications (using those functions) wouldn't have to be recompiled > to use new camera features as they come out and the lower layers are > updated. > > Additionally, for settings such as Triggering I would enumerate them to > allow to set the following types: Edge High, Edge Low, Pulse High, Pulse > Low, Software and (None or Internal or Freerun...) intead of seperate > functions to set edge state, and enable external or internal trigger > (cause there are other types than just external and multiple external > types.) > > -- Here is an example of how I would interface to settings changes > // These of course will have other typed functions such as u64 and s32. > set_parameter_u32 (tcamera_settings*, tcamera_parameter, uint32 parameter) > get_parameter_u32 (tcamera_settings*, tcamera_parameter, uint32* parameter) > is_parameter_supported_u32 (tcamera_settings*, tcamera_parameter) > is_parameter_sparse_table_u32 (tcamera_settings*, tcamera_parameter) > is_parameter_range_table_u32 (tcamera_settings*, tcamera_parameter) > get_parameter_sparse_table_u32 (tcamera_settings*, tcamera_parameter, > uint32* ptable, uint32 usize) > get_parameter_range_table_u32 (tcamera_settings*, tcamera_parameter, > uint32* ptable, uint32 usize) > > // Send the settings to the camera to be used. > send_settings_to_camera (tcamera_handle, tcamera_settings*); > get_default_settings (tcamera_handle, tcamera_settings*) > -- End example settings interface > > Some cameras have things like intensity and scale of the image change > from normal change as certain settings are enabled. We may want to have > a function to handle that. Maybe something like > get_x_scale_from_normal, get_x_intensity_from_normal or something > similar would be appropriate. Settings such as Binning modify the > intensity and features such as faster viewing modes (A faster view mode > at a lower quality.) affects both intensity and scaleing. I have not > seen any API's that have functions to support this, but have dealt with > ones that state with Camera X and setting Y use scale of 1.4, but Camera > Z and Setting Y use scale of 1.6. > > OPENING AND CLOSING CAMERAS > What we could do here is have an list_cameras function that lists all > cameras found on the system. (1394, USB, Framegrabber Cameras would all > appear on the same list.) and the user application could select which > camera to use when calling open_camera(cameraid) > > RETRIEVING FRAMES > From your interface it looks as if Camwire owns the buffers that the > frames are copied into (the number set by the calling application.) I > think that it would be better if the frames were in fact owned by the > calling application and that the calling application could queue frames > up as it wanted. > > For ease of use there could be a synchronous version of the frame > retrieval that could be called grab_frame or grab_frame_sync. > > We could then to an asynchronous version of frame retrieval that would > be faster and could just use queues internally to hold onto the frame. > Upon completion of the frame being filled, a callback is called. Of > course we would need a function like abort_frames or cancel_frames > incase the user wanted to cease operation. > > These are my opinions. Please let me know what you think. If you like > my ideas, have questions or would like more detailed descriptions feel > free to mail me on or off list. > > Regards, > Brad (br...@je...) > -- ^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^ Johann Schoonees Imaging & Sensing Team Industrial Research Limited, PO Box 2225, Auckland, New Zealand Phone +64 9 9203679 Fax +64 9 3028106 http://www.is.irl.cri.nz/ |
From: Brad <br...@je...> - 2004-03-29 22:53:54
|
I totally agree with the intent, why would you want to re-write code a bunch of times anyways right? I would tend to agree that for most users it would be sufficient. Especially, since most consumer level cameras (well that I am familiary with which isn't many) don't really support binning or any of the more advanced features I was talking about (again I am not too aware of the consumer-level offerings.) Myself, I don't have any time that I could devote to an additional project right now, I also don't have any IIDC cameras so I don't believe any of them will run under libdc. Arne's unicap API seems to do 80% of everything right now the way I would envision a common Image Capture Api (didn't read up on it until this morning.) so I'll probably continue discussions there and maybe work towards some sort of completion of an API there with additional camera drivers underneath. Regards, Brad. Johann Schoonees wrote: > Hi Brad > > Thanks for your insights and comments. It's good to have someone look > at it from a fresh perspective. > > Camwire started out as a modest little wrapper around libdc1394 for > some of my colleagues who did not want to spend any time learning > aobut IEEE 1394 things. So from the outset it was meant to be simple > rather than comprehensive. > > I appreciate that your proposed changes need not add much complexity > to the interface and may even simplify it in places. It will however > require a major rewrite of much of the code. I don't have much time > myself to extend and improve Camwire. It now does more or less what > we originally wanted it to do. I suspect that it will also be > sufficient for many others and that is why I made it publically > available. > > I would be happy to implement submitted patches. I would also be > happy if anyone wanted to take the code further into a bigger project. > Perhaps we may decide to split the project into a keep-it-simple > original-but-limited version and a more ambitious and flexible version > which hides the implementation details behind DSOs. > > What do you think? > > Regards, > Johann > > > Brad wrote: > >> I like the idea behind Camwire, but I was thinking that if you are >> wanting a significant base of imaging devices to interface with I >> could suggest a few changes that could be made. Almost all of these >> are based on my opinion and past experiences in working with >> scientifc and other types of imaging. >> >> I would like to apologise in advance if you are not wanting to get a >> list of what people would think an optimal API would look like in >> which case you may stop reading. >> >> The basis of this email is based solely on my opinion and experiences >> of what I would consider to be my API of choice. I'm looking at the >> API from the perspective that it is an API should control a Camera >> (Digital SLR, Scientific, Machine Vision, Microscopy, etc ...) >> regardless of type, feature set or interface (Firewire (IIDC, >> proprietary), USB, FrameGrabber, ...) with a computer. Additionally, >> it is my opinion that it should also be possible to extend such an >> API to other Operating Systems should that be a desire (Mac, Windows, >> VxWorks, whatever.) >> >> GENERIC CAMERA INTERFACE MODULES >> It would probably be a good and easy to implement style if we wrote >> the generic Camera API to use DSO's to call the appropriate interface >> types. For example, there could be an IIDC dso that knew how to talk >> to IIDC cameras, one for USB and so on. The Generiic Camera API >> could then look in a specific location (say /opt/camwire/dso) for >> modules that represent camera interfaces. It would make other people >> / parties job easier to interface their API / Camera system with the >> Generic Camera API without having to actually modify the API itself. >> >> SETTING AND GETTING CAMERA FEATURES / SETTINGS >> I believe that having seperate functions to set the different >> settings that the camera may be set to is a little overkill. When >> camera's support features like Roi's (Some Multiple Roi's), Readout >> Speeds, Binning Modes, Trigger Types, Shutter Modes, Image Formats >> (etc...) having a seperate function for each possible setting becomes >> a lot of work to maintain and implement, especially when you try to >> find what values (range or sparse) are actually supported by the camera. >> >> Myself I would structure that part of the code as a function that is >> able to set a structure that contains the actual settings that will >> be stored (should be opaque.) The actual function that sets the >> structure would accept an enumeration that describes which parameter >> or setting is being set by the function. Operating in this manner we >> have an API that does not have to change much as new features are >> supported in terms of the actual API (just add new enumerations.) >> >> Additionally, we could add a function to report the largest supported >> enumeration along with its textual name for user applications so that >> some applications (using those functions) wouldn't have to be >> recompiled to use new camera features as they come out and the lower >> layers are updated. >> >> Additionally, for settings such as Triggering I would enumerate them >> to allow to set the following types: Edge High, Edge Low, Pulse High, >> Pulse Low, Software and (None or Internal or Freerun...) intead of >> seperate functions to set edge state, and enable external or internal >> trigger (cause there are other types than just external and multiple >> external types.) >> >> -- Here is an example of how I would interface to settings changes >> // These of course will have other typed functions such as u64 and s32. >> set_parameter_u32 (tcamera_settings*, tcamera_parameter, uint32 >> parameter) >> get_parameter_u32 (tcamera_settings*, tcamera_parameter, uint32* >> parameter) >> is_parameter_supported_u32 (tcamera_settings*, tcamera_parameter) >> is_parameter_sparse_table_u32 (tcamera_settings*, tcamera_parameter) >> is_parameter_range_table_u32 (tcamera_settings*, tcamera_parameter) >> get_parameter_sparse_table_u32 (tcamera_settings*, tcamera_parameter, >> uint32* ptable, uint32 usize) >> get_parameter_range_table_u32 (tcamera_settings*, tcamera_parameter, >> uint32* ptable, uint32 usize) >> >> // Send the settings to the camera to be used. >> send_settings_to_camera (tcamera_handle, tcamera_settings*); >> get_default_settings (tcamera_handle, tcamera_settings*) >> -- End example settings interface >> >> Some cameras have things like intensity and scale of the image change >> from normal change as certain settings are enabled. We may want to >> have a function to handle that. Maybe something like >> get_x_scale_from_normal, get_x_intensity_from_normal or something >> similar would be appropriate. Settings such as Binning modify the >> intensity and features such as faster viewing modes (A faster view >> mode at a lower quality.) affects both intensity and scaleing. I >> have not seen any API's that have functions to support this, but have >> dealt with ones that state with Camera X and setting Y use scale of >> 1.4, but Camera Z and Setting Y use scale of 1.6. >> >> OPENING AND CLOSING CAMERAS >> What we could do here is have an list_cameras function that lists all >> cameras found on the system. (1394, USB, Framegrabber Cameras would >> all appear on the same list.) and the user application could select >> which camera to use when calling open_camera(cameraid) >> >> RETRIEVING FRAMES >> From your interface it looks as if Camwire owns the buffers that the >> frames are copied into (the number set by the calling application.) >> I think that it would be better if the frames were in fact owned by >> the calling application and that the calling application could queue >> frames up as it wanted. >> >> For ease of use there could be a synchronous version of the frame >> retrieval that could be called grab_frame or grab_frame_sync. >> >> We could then to an asynchronous version of frame retrieval that >> would be faster and could just use queues internally to hold onto the >> frame. Upon completion of the frame being filled, a callback is >> called. Of course we would need a function like abort_frames or >> cancel_frames incase the user wanted to cease operation. >> >> These are my opinions. Please let me know what you think. If you >> like my ideas, have questions or would like more detailed >> descriptions feel free to mail me on or off list. >> >> Regards, >> Brad (br...@je...) >> > |