SDK - CAMAPI Developer options
← |
⌂ Home |
→ Debugging |
Introduction
Refer to the CAMAPI technical specification for a description of each method. The specification is updated for each software release.
CAMAPI
The Camera Application Programming Interface (CAMAPI), consists of a handful of functions, summarized in the Software releases#CAMAPI documentation.
The API binding allowing remote access to CAMAPI is HTTP GET and POST with the parameters and returned data JSON encoded.
Python examples
There is a python module hcamapi.py which provides HTTP access to CAMAPI. You can browse to your camera to download the python module and example programs. The HCAMAPI supports the exactly same API as CAMAPI, with the exception you need to pass the camera's IP address or DNS name to the HCAMAPI module.
Here is a simple example:
import hcamapi cam = hcamapi.HCamapi(opts.address, logger) (state, level, flags) = cam.get_status() print "Camera state %d, level %d, flags %d" % (state, level, flags) saved_settings = cam.get_saved_settings() cam.run(saved_settings) cam.trigger()
You can browse to the camera to retrieve hcamapi.py and related example programs written in Python.
http://10.11.12.13/static/host
replacing 10.11.12.13 with your camera's IP address as necessary.
Shell script command line examples
You can create an application on your host computer to control the camera using HTTP. Here are some simple command line examples:
CAMIP=10.11.12.13 REQ='{"requested_iso":"100","requested_exposure":0.002,"requested_frame_rate":"","requested_vertical":"",\ "requested_horizontal":"","requested_duration":"","requested_pretrigger":"50","requested_subsample":false}' # simple shell function to print out the camera status information once a second # on entry - number of seconds to monitor camera monitor_cam() { SEC=$1 for A in `seq 1 $SEC` ; do curl $CAMIP/get_status echo sleep 1 done } ALLOWED=`curl -H "Content-Type: application/json; charset=utf-8" --data $REQ $CAMIP/configure_camera` echo $ALLOWED curl -H "Content-Type: application/json; charset=utf-8" --data "$ALLOWED" $CAMIP/run monitor_cam 4 curl $CAMIP/trigger monitor_cam 6 curl $CAMIP/save_stop monitor_cam 5
get_status
Please refer to the full CAMAPI documentation. What you see below is likely a bit stale. I will remove it when I verify the official documentation contains the same level of detail.
CAMAPI uses a state machine model to move from pretrigger to trigger to saving and the back to pretrigger again. While doing these three activities, there can be an amount of progress that has occurred, such as how much of the save has completed. In addition, there is device status information, in the form of flags represented as a bit-field.
get_status() returns a dictionary containing
Key | Value type | Value range | Meaning |
---|---|---|---|
state | int | 1 .. 8 | Enumeration of current state |
level | int | 0 .. 100 | Percentage full or complete. Meaning depends on the state. |
flags | int | 19 bits | bit-field encoded device status. |
The defined camera states include:
Value | Name | level | Meaning |
---|---|---|---|
1 | CAMAPI_STATE_UNCONFIGURED | N/A | CAMAPI run() method hasn't been invoked. |
2 | CAMAPI_STATE_CALIBRATING | N/A | Camera is capturing a black frame to be able to subtract the image sensor pixel bias from each video frame. When calibration is done, camera will automatically transition to filling the pretrigger buffer with video frames. |
3 | CAMAPI_STATE_RUNNING | Percentage the pretrigger buffer has filled. | The camera is capturing video frames and storing them in the pretrigger buffer. |
4 | CAMAPI_STATE_TRIGGERED | Percentage the posttrigger buffer has filled. | The camera is capturing video frames and storing them in the posttrigger buffer. When the posttrigger buffer is full, the camera will automatically transition to saving the capture video. |
5 | CAMAPI_STATE_SAVING | Percentage of captured video frames that have been saved to the file. | Camera is reading frames from the pre and posttrigger buffers, encoding the frames, and saving them to a file. |
6 | CAMAPI_STATE_RUNNING_PRETRIGGER_FULL | 100, meaning the pretrigger buffer is full. | The camera is capturing video frames and the new frames are overwriting the oldest frame in the pretrigger buffer. |
7 | CAMAPI_STATE_TRIGGER_CANCELED | N/A | User canceled the video capture after the camera was triggered. Camera is resetting and will automatically transition to again filling the pretrigger buffer with video frames. |
8 | CAMAPI_STATE_SAVE_CANCELED | N/A | User canceled the save video to file. Camera is resetting and will automatically transition to again filling the pretrigger buffer with video frames. This feature has been disabled so the CAMAPI_STATE_SAVE_CANCELED can not be reached. |
the defined camera status bit-field values are:
Bit | Name | Meaning |
---|---|---|
0 | CAMAPI_FLAG_STORAGE_FULL | Current storage device does not have room to hold another video file. |
1 | CAMAPI_FLAG_STORAGE_MISSING | No usable storage device is installed. |
2 | CAMAPI_FLAG_USB_STORAGE_INSTALLED | USB storage device is installed. |
3 | CAMAPI_FLAG_SD_CARD_STORAGE_INSTALLED | SD card is installed. |
4 | CAMAPI_FLAG_USB_STORAGE_FULL | USB storage device does not have room to hold another video file. |
5 | CAMAPI_FLAG_SD_CARD_STORAGE_FULL | SD card does not have room to hold another video file. |
6 | CAMAPI_FLAG_STORAGE_BAD | An installed storage device is returning an error. |
7 | CAMAPI_FLAG_NET_CONFIGURED | Setting to allow the camera to connect to a network file system are stored in the camera. |
8 | CAMAPI_FLAG_NET_UNMOUNTABLE | Camera attempted to use the network file system settings to mount the shared resource but the mount failed. Likely the network file system settings are incorrect. |
9 | CAMAPI_FLAG_NET_FULL | The network file system shared storage does not have room to hold more captured videos. |
18 | CAMAPI_FLAG_GENLOCK_NO_SIGNAL | The camera is configured as a genlock receiver camera and no periodic genlock start-of-exposure signal is detected. |
19 | CAMAPI_FLAG_GENLOCK_CONFIG_ERROR | The camera is configured as a genlock receiver camera and at least one frame did not have received start-of-exposure signal when expected. |
The status (really the camera state) can be obtained at any time. The follow table shows the camera's state transition diagram.
Current state | state value | Event | New state | Current state description |
---|---|---|---|---|
CAMAPI_STATE_UNCONFIGURED | 1 | run | CAMAPI_STATE_CALIBRATING | The camera has been powered on and is ready to have the camera capture parameters configured. |
CAMAPI_STATE_CALIBRATING | 2 | calibration complete |
CAMAPI_STATE_RUNNING | The camera is optimizing image quality by calibrating the sensor |
CAMAPI_STATE_RUNNING | 3 | trigger | CAMAPI_STATE_TRIGGERED | The camera is filling or overwriting the pretrigger buffer. |
pretrigger buffer full |
CAMAPI_STATE_RUNNING_PRETRIGGER_FULL | The camera has filled the pretrigger buffer. | ||
CAMAPI_STATE_TRIGGERED | 4 | posttrigger buffer full | CAMAPI_STATE_SAVING | The camera is filling the posttrigger buffer. |
cancel | CAMAPI_STATE_TRIGGER_CANCELED | The trigger has been canceled before saving video has started | ||
CAMAPI_STATE_SAVING | 5 | saving complete | CAMAPI_STATE_CALIBRATING | The camera is saving the video frames in the pretrigger and posttrigger buffers to a file. |
cancel | CAMAPI_STATE_SAVE_CANCELED | The save video operation has been canceled - no files are created. This feature has been disabled so the CAMAPI_STATE_SAVE_CANCELED state can not be reached. | ||
stop save | CAMAPI_STATE_CALIBRATING | The save video operation has been stopped with the encoded video frames saved to the file and unprocessed video frames are discarded. | ||
CAMAPI_STATE_RUNNING_PRETRIGGER_FULL | 6 | The camera is overwriting the pretrigger buffer. | ||
CAMAPI_STATE_TRIGGER_CANCELED | 7 | |||
CAMAPI_STATE_SAVE_CANCELED | 8 | This feature has been disabled so the CAMAPI_STATE_SAVE_CANCELED state can not be reached. |
Extend table to show you can call configure_camera in any state.
configure_camera
Please refer to the full CAMAPI documentation. What you see below is likely a bit stale. I will remove it when I verify the official documentation contains the same level of detail.
The configure_camera() function accepts user-supplied requested camera settings, in the form of a python dictionary, and returns a dictionary containing the allowed values. Details of the negotiation are described above.
Note: In addition to the allowed camera settings, configure_camera() also returns additional values that are expected by other CAMAPI functions. Only the values intended to be used external to CAMAPI are documented. The rest should be treated as opaque and not modified by the application using CAMAPI. The opaque values may change at any point in the future.
User settings | ||||
---|---|---|---|---|
Setting (Dict key) |
Units | Supported values | Description | |
requested_horizontal | pixels | 192 .. 1280 | Width of image to capture. | |
requested_vertical | pixels | 96 .. 1024 | Height of image to capture. | |
requested_frame_rate | frames per second | 0.1 .. 25000 | Number of frames to capture in every second. | |
requested_exposure | seconds | 0.000004 .. 0.1 | Amount of time the CMOS sensor is integrating the received light. | |
requested_duration | seconds | Limited by memory | Amount of the video to capture. | |
requested_pretrigger | percentage | 0 .. 100 | Amount of the video being captured is captured before the trigger event. | |
requested_iso | unitless | color: 100 .. 400 mono: 400 .. 1600 |
sensitivity to light. | |
requested_subsample | int enum | 0 - off 1 - on |
Controls skipping every other row and column. | |
requested_force_mono | int enum | 0 - off 1 - on |
Force color sensor video to be processed as monochrome. This is useful for high frame rates where the de-Bayering algorithm might add noise to the image. Note: this doesn't change the ISO range. This feature is not implemented. | |
requested_genlock | int enum | 0 - off 1 - source 2 - receiver |
Camera genlock configuration. Source means the camera is generating the trigger and start-of-exposure timing signals. Receiver mean cameras receiving those signals, via the external trigger connector, from the genlock source camera. Genlock Adapter can be used so one source camera can provide timing signals to multiple receiver cameras (or to extend the distance between the cameras). | |
requested_overclock | int enum | 0 - off 1 - A level 2 - B level 3 - C level 4 - D level |
Camera overclock configuration. The amount of overclocking is not specified beyond saying A is the least overclocking and D is the most overclocking. |
Run
Please refer to the full CAMAPI documentation. What you see below is likely a bit stale. I will remove it when I verify the official documentation contains the same level of detail.
Once the camera has returned a set of acceptable capture parameters, you can run the camera to activate those values. The camera will take a dark frame to maximize image quality for those particular capture parameters, then it will start filling the pretrigger buffer (if configured).
In addition to filling the pretrigger buffer, live preview is also started, meaning the JPEG file is being updated around five times a second. Other live preview options are possible.
Once the pre-trigger buffer is full, the camera will overwrite the oldest frame in the buffer with the newly captured frame until the camera is triggered.
Trigger and save
Please refer to the full CAMAPI documentation. What you see below is likely a bit stale. I will remove it when I verify the official documentation contains the same level of detail.
The following paragraphs assume the camera's save mode is set to auto, which is the easiest camera usage model if you are new to high speed camera contro.
The camera can be triggered anytime it is filling the pretrigger buffer, even if the pretrigger buffer is not full. Any future trigger requests are ignored until the camera is again filling the pretrigger buffer (which happens automatically after the save is complete).
Once the trigger occurs, the camera switches from filling the pretrigger buffer to filling the posttrigger buffer. Once the posttrigger buffer is full, the camera automatically switches from capturing video to saving the captured video. Once the video has been saved, the camera automatically switches from saving video to filling the pretrigger buffer and waiting for a trigger event. This simple flow allows the camera to be configured once and then controlled by an external trigger without requiring an external computer.
Stop
Trigger
Cancel
While in state CAMAPI_STATE_TRIGGERED, cancel() will cancel filling the posttrigger buffer.
Note: In normal operation, once the posttrigger buffer has filled, the camera will automatically transition from CAMAPI_STATE_TRIGGERED to CAMAPI_STATE_SAVING. It is possible that the cancel() may be received after this automatic transition has occurred. In that case, the cancel() will have no effect.
CAMAPI warning support
The CAMAPI configure_camera() method accepts user-supplied requested camera settings, in the form of a python dictionary, and returns a dictionary containing the allowed values. In addition, the returned dictionary contains a global warning flag, and if set, one or more setting specific warnings with text describing how to resolve the warning.
The global warning allowed dictionary key is named warning and each setting specific warning allowed dictionary key name is the setting name with _warning appended. For example, if there is a warning for the subsample the key name would be subsample_warning and the value would be a text string, such as Subsample mode may cause alaising and/or other visual artifacts.
Settings supporting warnings
The settings that generate a warning are listed below. To simplify localization, each warning value is unique.
Setting Key | Warning Key | Warning Value | Meaning |
---|---|---|---|
iso | iso_warning | 1 | High ISO settings can create increased noise, graininess or other artifacts. |
subsample | subsample_warning | 2 | Subsample mode may cause alaising and/or other visual artifacts. |
edr | edr_warning | 3 | EDR Mode is less effective at high ISO settings. |
4 | EDR Mode can cause purple color shift in bright image areas. | ||
overclock | overclock_warning | 5 | High Overclock settings may cause errors or visual artifacts. Use with caution. |
genlock | genlock_warning | 6 | In Genlock receiver mode, this camera can only be triggered through the genlock source camera and will ignore the external trigger. |
force_monochrome | force_monochrome_warning | 7 | Force Monochrome Mode is enabled. |
gamma_correction | gamma_correction_warning | 8 | Disabling Gamma may be useful for some video editing workflows, but can cause a loss of shadow detail in normal use. |
pipeline | pipeline_warning | 9 | Using a video encode pipeline other than high encode quality may result is video artifacts. |
Mac OSX SDK example usage
The camera includes some example python code and a handy host CAMAPI library (hcamapi.py) that you can use to automate camera control. You can see the python module and applications by browsing to your camera http://10.11.2.13/static/host
replacing 10.11.12.13 with your camera's IP address as necessary.
The following are some cut-and-paste commands that should work on a Mac OSX computer with no additional software being added. All commands are run in the Terminal application. To start Terminal either press the COMMAND-SPACE keys at the same time or using Finder to navigate into Applications -> Utilities -> Terminal. Once terminal is running, try out these commands
CAMIP=10.11.12.13 # set to the IP address of the edgetronic camera mkdir edgetronic cd edgetronic curl http://$CAMIP/static/host/hcamapi.py > hcamapi.py # fetch the handy host CAMAPI library curl http://$CAMIP/static/host/hcamapi_example_usage.py > hcamapi_example_usage.py # fetch example program python hcamapi_example_usage.py -a $CAMIP
Here is some of the output from running those commands:
lyre-osx:~ tfischer$ CAMIP=10.111.0.35 lyre-osx:~ tfischer$ mkdir edgetronic lyre-osx:~ tfischer$ cd edgetronic lyre-osx:edgetronic tfischer$ curl http://$CAMIP/static/host/hcamapi.py > hcamapi.py % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 21827 100 21827 0 0 533k 0 --:--:-- --:--:-- --:--:-- 710k lyre-osx:edgetronic tfischer$ curl http://$CAMIP/static/host/hcamapi_example_usage.py > hcamapi_example_usage.py % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 12469 100 12469 0 0 366k 0 --:--:-- --:--:-- --:--:-- 468k lyre-osx:edgetronic tfischer$ python hcamapi_example_usage.py -a $CAMIP Camera state 6, level 100, flags 8 Camera extended status - state 6, level 100, flags 8, IS temp (C) 31, FPGA temp (C) 33 Status string: State: Running pretrigger buffer full; Level: 100; Flags: SD card installed; Empty: 776.8 MB, Storage directory: /mnt/sdcard Directory path to active storage device: /mnt/sdcard Storage information: 814514176 / 1977286656 bytes, mount point: /mnt/sdcard Camera information: Software build date: 20140824092106 Hardware build date: 20130520 FPGA version: 70 Model Number: 1 Serial Number: 3 Hardware Revision: 3 Hardware Configuration: 0 IR Filter: installed Ethernet MAC Address: 00:1B:C5:09:60:03 Saved camera settings: Sensitivity: None Shutter: 1/500 Frame Rate: 60 Horizontal: None Vertical: None Sub-sampling: On Duration: 10 Pre-trigger: 75
There is a lot more output. The example program hcamapi_example_usage.py uses every exposed edgertronic camera API (CAMAPI).
Enhancing the Web UI look and feel using CAMAPI
Basically there is one webpage that includes a few other HTML files. The sanstreak.html includes the rest of the /home/root/ss-web/templates HTML files. The layout is a viewport for the video (video_image.html) with buttons below it (button_row.html). There are two modal dialog windows, settings (settings_modal.html) and replay (replay_modal.html). Stylesheets, located in /home/root/ss-web/static, control the overall look.
The actions (update live preview, trigger, etc) are supported by JavaScript. The JavaScript code accesses CAMAPI (described below) using JSON / HTTP calls to the caemra. The JSON / HTTP encoding is done by app.py. The source code of app.py is provided as a reference (/home/root/ss-web/static/sdk/camera/app.py).
If you want to enhance the look-and-feel, your ability to control the camera is supported by CAMAPI. First understand CAMAPI and then change the code in /home/root/ss-web to your heart's content.
Media server
GStreamer is used to get video frames from Video4Linux2 (V4L2), encode them in JPEG for live preview or H.264 when saving to file. It is a bit tricky to show the progress of the save operation by occasionally displaying a JPEG encoded frame while the save is in progress. To handle this capability, a media server is used.
← |
⌂ Home |
→ Debugging |