These examples demonstrate basic API usage. To build them, see the examples subdirectory in the FCam source package.
Note that this page contains only the source code of the examples. To be able to run an FCam application on Nokia N9, a syspart.conf file must always be installed onto the device with the application executable. See the instructions on main page.
#include <stdlib.h> #include <stdio.h> #include <assert.h> // Select the platform #include <FCam/N9.h> namespace Plat = FCam::N9; /***********************************************************/ /* A program that takes a single shot */ /* */ /* This example is a simple demonstration of the usage of */ /* the FCam API. */ /***********************************************************/ void errorCheck(); int main(int argc, char **argv) { char path[256]; // Make the image sensor Plat::Sensor sensor; // Explicitly power up the sensor if (sensor.initialize(0) == -1){ printf("Error powering up the sensor.\n"); return 1; } // Make a new shot FCam::Shot shot1; shot1.exposure = 66000; // 66 ms exposure shot1.gain = 1.0f; // minimum ISO // Specify the output resolution and format, and allocate storage for the resulting image shot1.image = FCam::Image(2592, 1968, FCam::UYVY); // Order the sensor to capture a shot sensor.capture(shot1); // Check for errors errorCheck(); assert(sensor.shotsPending() == 1); // There should be exactly one shot // Retrieve the frame from the sensor FCam::Frame frame = sensor.getFrame(); // This frame should be the result of the shot we made assert(frame.shot().id == shot1.id); // This frame should be valid too assert(frame.valid()); assert(frame.image().valid()); // Save the frame snprintf(path, 256, "%s/example1.jpg", getenv("HOME")); FCam::saveJPEG(frame, path); // Check that the pipeline is empty assert(sensor.framesPending() == 0); assert(sensor.shotsPending() == 0); return 0; } void errorCheck() { // Make sure FCam is running properly by looking for DriverError FCam::Event e; while (FCam::getNextEvent(&e, FCam::Event::Error)) { printf("Error: %s\n", e.description.c_str()); if (e.data == FCam::Event::DriverMissingError) { printf("example1: FCam can't find its driver. Did you install " "fcam-drivers on your platform, and reboot the device " "after installation?\n"); exit(1); } if (e.data == FCam::Event::DriverLockedError) { printf("example1: Another FCam program appears to be running " "already. Only one can run at a time.\n"); exit(1); } } }
#include <stdlib.h> #include <stdio.h> #include <assert.h> #include <FCam/N9.h> #include <linux/videodev2.h> #include <fcntl.h> #include <sys/ioctl.h> // Select the platform namespace Plat = FCam::N9; /***********************************************************/ /* Flash / No-flash */ /* */ /* This example demonstrates capturing multiple shots with */ /* possibly different settings. */ /***********************************************************/ int main(int argc, char **argv) { // Devices Plat::Sensor sensor; Plat::Flash flash; sensor.attach(&flash); // Attach the flash to the sensor // Explicitly power up the sensor if (sensor.initialize(0) == -1){ printf("Error powering up the sensor.\n"); return 1; } // Make two shots std::vector<FCam::Shot> shot(2); // Set the first shot parameters (to be done with flash) shot[0].exposure = 80000; shot[0].gain = 1.0f; shot[0].whiteBalance = 3500; shot[0].image = FCam::Image(2592, 1968, FCam::UYVY); // Set the second shot parameters (to be done without flash) shot[1].exposure = 80000; shot[1].gain = 1.0f; shot[1].whiteBalance = 3500; shot[1].image = FCam::Image(2592, 1968, FCam::UYVY); // Make an action to fire the flash Plat::Flash::FireAction fire(&flash); fire.duration = flash.minDuration(); // flash briefly fire.time = shot[0].exposure - fire.duration; // at the end of the exposure fire.brightness = flash.maxBrightness(); // at full power // Attach the action to the first shot shot[0].addAction(fire); // Order the sensor to capture the two shots sensor.capture(shot); assert(sensor.shotsPending() == 2); // There should be exactly two shots // Retrieve the first frame FCam::Frame frame = sensor.getFrame(); assert(sensor.shotsPending() == 1); // There should be one shot pending assert(frame.shot().id == shot[0].id); // Check the source of the request // Write out file if needed if (argc > 1) { FCam::saveJPEG(frame, argv[1]); } // Retrieve the second frame frame = sensor.getFrame(); assert(frame.shot().id == shot[1].id); // Check the source of the request // Write out file FCam::saveJPEG(frame, "/home/user/MyDocs/DCIM/example2.jpg"); // Check the pipeline is empty assert(sensor.framesPending() == 0); assert(sensor.shotsPending() == 0); }
#include <stdlib.h> #include <stdio.h> #include <math.h> #include <assert.h> #include <FCam/N9.h> // Select the platform namespace Plat = FCam::N9; /***********************************************************/ /* Focus sweep */ /* */ /* This example demonstrates moving the lens during an */ /* exposure via the use of Lens::FocusAction. It also */ /* shows how to use the metadata tagged by the devices. */ /* Because the lens on the N900 zooms slightly when it */ /* focuses, you'll also get a zoom-blur effect. */ /***********************************************************/ int main(int argc, char **argv) { // Devices Plat::Sensor sensor; Plat::Lens lens; // Attach the lens to the sensor sensor.attach(&lens); // Explicitly power up the sensor if (sensor.initialize(0) == -1){ printf("Error powering up the sensor.\n"); return 1; } // First focus near with maximal speed lens.setFocus(lens.nearFocus(), lens.maxFocusSpeed()); while (lens.focusChanging()) { ; } // Wait to be done // Now make a shot that will sweep the lens FCam::Shot shot1; FCam::Lens::FocusAction sweep(&lens); // Set the parameters of this action sweep.focus = lens.farFocus(); sweep.speed = lens.maxFocusSpeed(); // Calculate how long it takes to move the lens to the desired // location in microseconds float duration = 1000000.0f * (lens.nearFocus() - lens.farFocus()) / sweep.speed; printf("The lens will sweep from near to far in %f milliseconds\n", duration / 1000.0); // 30 ms exposure time shot1.exposure = 30000; shot1.gain = 1.0f; // Perform the sweep at half way through exposure sweep.time = (shot1.exposure-duration)/2; shot1.image = FCam::Image(2592, 1968, FCam::UYVY); // Attach the action to the shot shot1.addAction(sweep); // Order the sensor to capture the shot sensor.capture(shot1); assert(sensor.shotsPending() == 1); // There should be exactly one shot // Retrieve the frame FCam::Frame frame = sensor.getFrame(); assert(frame.shot().id == shot1.id); // Check the source of the request // Print out some metadata const FCam::Lens::Tags lensTags(frame); printf("Aperture : %.4f\n", lensTags.aperture); printf("Initial focus : %.4f\n", lensTags.initialFocus); printf("Final focus : %.4f\n", lensTags.finalFocus); // Save the resulting file FCam::saveJPEG(frame, "/home/user/MyDocs/DCIM/example3.jpg"); assert(sensor.framesPending() == 0); assert(sensor.shotsPending() == 0); }
#include <stdlib.h> #include <stdio.h> #include <math.h> #include <assert.h> #include <FCam/N9.h> #include <FCam/AutoExposure.h> #include <FCam/AutoWhiteBalance.h> // Select the platform namespace Plat = FCam::N9; /***********************************************************/ /* Autoexposure */ /* */ /* This example shows how to request streams and deal with */ /* the incoming frames, and also uses the provided */ /* auto-exposure and auto-white-balance routines. */ /***********************************************************/ int main(int argc, char **argv) { // Make a sensor Plat::Sensor sensor; // Explicitly power up the sensor if (sensor.initialize(0) == -1){ printf("Error powering up the sensor.\n"); return 1; } // Shot FCam::Shot stream1; // Set the shot parameters stream1.exposure = 33333; stream1.gain = 1.0f; // We don't bother to set frameTime in this example. It defaults // to zero, which the implementation will clamp to the minimum // possible value given the exposure time. // Request an image size and allocate storage stream1.image = FCam::Image(2592, 1968, FCam::UYVY); // Enable the histogram unit stream1.histogram.enabled = true; stream1.histogram.region = FCam::Rect(0, 0, 2592, 1968); // We will stream until the exposure stabilizes int count = 0; // # of frames streamed int stableCount = 0; // # of consecutive frames with stable exposure float exposure; // total exposure for the current frame (exposure time * gain) float lastExposure = 0; // total exposure for the previous frame FCam::Frame frame; do { // Ask the sensor to stream with the given parameters sensor.stream(stream1); // Retrieve a frame frame = sensor.getFrame(); assert(frame.shot().id == stream1.id); // Check the source of the request printf("Exposure time: %d, gain: %f\n", frame.exposure(), frame.gain()); // Calculate the total exposure used (including gain) exposure = frame.exposure() * frame.gain(); // Call the autoexposure algorithm. It will update stream1 // using this frame's histogram. autoExpose(&stream1, frame); // Call the auto white-balance algorithm. It will similarly // update the white balance using the histogram. autoWhiteBalance(&stream1, frame); // Increment stableCount if the exposure is within 5% of the // previous one if (fabs(exposure - lastExposure) < 0.05f * lastExposure) { stableCount++; } else { stableCount = 0; } // Update lastExposure lastExposure = exposure; } while (stableCount < 5); // Terminate when stable for 5 frames // Write out the well-exposed frame FCam::saveJPEG(frame, "/home/user/MyDocs/DCIM/example4.jpg"); // Order the sensor to stop streaming sensor.stopStreaming(); printf("Processed %d frames until stable for 5 frames!\n", count); // There may still be shots in the pipeline. Consume them. while (sensor.shotsPending() > 0) { frame = sensor.getFrame(); } // Check that the pipeline is empty assert(sensor.framesPending() == 0); assert(sensor.shotsPending() == 0); }
#include <stdlib.h> #include <stdio.h> #include <assert.h> #include <FCam/N9.h> #include <FCam/AutoFocus.h> // Select the platform namespace Plat = FCam::N9; /***********************************************************/ /* Autofocus */ /* */ /* This example shows how to request streams and deal with */ /* the incoming frames, and also uses the provided */ /* autofocus routine. */ /***********************************************************/ int main(int argc, char **argv) { // Devices Plat::Sensor sensor; Plat::Lens lens; sensor.attach(&lens); // Attach the lens to the sensor // Explicitly power up the sensor if (sensor.initialize(0) == -1){ printf("Error powering up the sensor.\n"); return 1; } // Autofocus supplied by FCam API FCam::AutoFocus autoFocus(&lens); // Shot FCam::Shot stream1; // Set the shot parameters stream1.exposure = 50000; stream1.gain = 1.0f; // Request a resolution, and allocate storage stream1.image = FCam::Image(2592, 1968, FCam::UYVY); // Enable the sharpness unit stream1.sharpness.enabled = true; // We will stream until the focus stabilizes int count = 0; // # of frames streamed // Order the sensor to stream sensor.stream(stream1); // Ask the autofocus algorithm to start sweeping the lens autoFocus.startSweep(); // Stream until autofocus algorithm completes FCam::Frame frame; do { // Retrieve a frame frame = sensor.getFrame(); assert(frame.shot().id == stream1.id); // Check the source of the request // The lens has tagged each frame with where it was focused // during that frame. Let's retrieve it so we can print it out. float diopters = frame["lens.focus"]; printf("Lens focused at %2.0f cm\n", 100/diopters); // The sensor has attached a sharpness map to each frame. // Let's sum up all the values in it so we can print out // the total sharpness of this frame. int totalSharpness = 0; for (int y = 0; y < frame.sharpness().height(); y++) { for (int x = 0; x < frame.sharpness().width(); x++) { totalSharpness += frame.sharpness()(x, y); } } printf("Total sharpness is %d\n\n", totalSharpness); // Call the autofocus algorithm autoFocus.update(frame); // Increment frame counter count++; } while (!autoFocus.idle()); printf("Autofocus chose to focus at %2.0f cm\n\n", 100/lens.getFocus()); // Write out the focused frame FCam::saveJPEG(frame, "/home/user/MyDocs/DCIM/example5.jpg"); // Order the sensor to stop streaming sensor.stopStreaming(); printf("Processed %d frames until autofocus completed!\n", count); // There may still be shots in the pipeline. Consume them. while (sensor.shotsPending() > 0) { frame = sensor.getFrame(); } // Check that the pipeline is empty assert(sensor.framesPending() == 0); assert(sensor.shotsPending() == 0); }
#include <stdlib.h> #include <stdio.h> #include <assert.h> #include <FCam/N9.h> #include "SoundPlayer.h" #include <linux/videodev2.h> #include <fcntl.h> #include <sys/ioctl.h> //SDK doesn't have these defines #ifndef V4L2_CID_FLASH_LED_MODE #define V4L2_CID_FLASH_LED_MODE 10225921 #endif #ifndef V4L2_FLASH_LED_MODE_FLASH #define V4L2_FLASH_LED_MODE_FLASH 1 #endif // Select the platform namespace Plat = FCam::N9; /***********************************************************/ /* Shutter sound */ /* */ /* This example shows how to declare and attach a device, */ /* and write the appropriate actions. In this example, the */ /* camera will trigger two actions at the beginning of the */ /* exposure: a flash, and a shutter sound. */ /* See SoundPlayer class for more information. */ /***********************************************************/ int main(int argc, char **argv) { // Devices Plat::Sensor sensor; Plat::Flash flash; // We defined a custom device to play a sound during the // exposure. See SoundPlayer.h/cpp for details. SoundPlayer audio; sensor.attach(&flash); // Attach the flash to the sensor sensor.attach(&audio); // Attach the sound player to the sensor // Explicitly power up the sensor if (sensor.initialize(0) == -1){ printf("Error powering up the sensor.\n"); return 1; } // Tell flash to use LED Flash int fd = open("/dev/v4l-subdev10", O_RDWR); struct v4l2_control ctrl; ctrl.id = V4L2_CID_FLASH_LED_MODE; ctrl.value = V4L2_FLASH_LED_MODE_FLASH; ioctl(fd, VIDIOC_S_CTRL, &ctrl); // Set the shot parameters FCam::Shot shot1; shot1.exposure = 800000; shot1.gain = 1.0f; shot1.whiteBalance = 3500; shot1.image = FCam::Image(2592, 1968, FCam::UYVY); // Action (Flash) FCam::Flash::FireAction fire(&flash); fire.duration = flash.minDuration(); fire.time = 0;//shot1.exposure - fire.duration; fire.brightness = flash.maxBrightness(); // Action (Sound) SoundPlayer::SoundAction click(&audio); click.time = 0; // Start at the beginning of the exposure click.setWavFile("/usr/share/sounds/ui-tones/snd_camera_shutter.wav"); // Attach actions shot1.addAction(fire); shot1.addAction(click); // Order the sensor to capture a shot. // The flash and the shutter sound should happen simultaneously. sensor.capture(shot1); assert(sensor.shotsPending() == 1); // There should be exactly one shot // Retrieve the frame from the sensor FCam::Frame frame = sensor.getFrame(); assert(frame.shot().id == shot1.id); // Check the source of the request // Write out the file FCam::saveJPEG(frame, "/home/user/MyDocs/DCIM/example6.jpg"); // Check that the pipeline is empty assert(sensor.framesPending() == 0); assert(sensor.shotsPending() == 0); }
Copyright (c) 2012, Nokia Corporation and/or its subsidiary(-ies). All rights reserved. See Copyright. |
MeeGo 1.2 Harmattan API
|