ScanditNativeBarcodeScannerCameraDemo.c

Detecting Barcodes in a camera image stream

This example uses the Scandit SDK to detect barcodes in frames from a camera.

This demo is currently limited to GNU/Linux systems with a Vidoe4Linux2 camera.

#include <signal.h>
#include <stdio.h>
// Please insert your app key here:
#define SCANDIT_SDK_LICENSE_KEY "-- INSERT YOUR LICENSE KEY HERE --"
// Please insert the desired camera resolutoin here:
#define CAMERA_WIDTH 1280
#define CAMERA_HEIGHT 720
static volatile ScBool process_frames;
static void catch_exit(int signo) {
printf("SIGINT received.\n");
process_frames = SC_FALSE;
}
int main() {
// handle ctrl+c events
if (signal(SIGINT, catch_exit) == SIG_ERR) {
printf("Could not set up signal handler.\n");
return -1;
}
// Create the camera object.
// When no parameters are given, the camera is automatically detected.
// See sc_camera_new_from_path for more options.
ScCamera *camera = sc_camera_new();
if (camera == NULL) {
printf("No camera available.\n");
return -1;
}
// Get the supported resolutions and check
// if the desired resolution is supported
ScBool supported = SC_FALSE;
const uint32_t resolutions_size = 30;
ScSize resolutions[resolutions_size];
int32_t resolutions_found;
switch (resm) {
// The camera supports a small set of predefined resolutions
resolutions_found = sc_camera_query_supported_resolutions(camera, &resolutions[0], resolutions_size);
if (!resolutions_found) {
printf("There was an error getting the discrete resolution capabilities of the camera.\n");
return -1;
}
for (int i = 0; i < resolutions_found; i++) {
if (resolutions[i].width == CAMERA_WIDTH &&
resolutions[i].height == CAMERA_HEIGHT) {
supported = SC_TRUE;
break;
}
}
break;
// The camera supports a wide range of resolutions that are
// generated step-wise. Refer to documentation for further
// explanation.
printf("There was an error getting the stepwise resolution capabilities of the camera.\n");
return -1;
}
if (swres.min_width <= CAMERA_WIDTH &&
CAMERA_WIDTH <= swres.max_width &&
swres.min_height <= CAMERA_HEIGHT &&
CAMERA_HEIGHT <= swres.max_height &&
CAMERA_WIDTH % swres.step_width == 0 &&
CAMERA_HEIGHT % swres.step_height == 0
) {
supported = SC_TRUE;
}
break;
default:
printf("Could not get camera resolution mode.\n");
return -1;
}
// Set the resolution
if (!supported) {
printf("%dx%d is not supported by this camera.\nPlease specify a supported resolution in the source code.\n", CAMERA_WIDTH, CAMERA_HEIGHT);
return -1;
}
ScSize desired_resolution;
desired_resolution.width = CAMERA_WIDTH;
desired_resolution.height = CAMERA_HEIGHT;
if (!sc_camera_request_resolution(camera, desired_resolution)) {
printf("Setting resolution failed.\n");
return -1;
}
// Start streaming.
if (!sc_camera_start_stream(camera)) {
printf("Start the camera failed.\n");
return -1;
}
// Create the recognition context.
sc_recognition_context_new(SCANDIT_SDK_LICENSE_KEY, "/tmp", NULL);
if (context == NULL) {
printf("Could not initialize context.\n");
return -1;
}
// Create barcode scanner with EAN13/UPCA and QR code scanning enabled.
if (settings == NULL) {
return -1;
}
// We want to scan at most one code per frame.
// We favor the center area of the image for scanning.
ScRectangleF code_location = { .position.x = 0.f, .position.y = 0.4f,
.size.width = 1.0f, .size.height = 0.2f };
// We want to scan in the whole image.
// Our camera has no auto-focus.
// Codes are most likely oriented from left to right.
// Create a barcode scanner for our context and settings.
if (scanner == NULL) {
return -1;
}
// The scanner is setup asynchronous.
// We could wait here using sc_barcode_scanner_wait_for_setup_completed if needed.
// Access the barcode scanner session. It collects all the results.
// Signal a new frame sequence to the context.
// Create an image description that is reused for every frame.
process_frames = SC_TRUE;
while (process_frames) {
// Get the latest camera frame data and description
const uint8_t *image_data = sc_camera_get_frame(camera, image_descr);
if (image_data == NULL) {
printf("Frame access failed. Existing.\n");
break;
}
// Process the frame.
ScProcessFrameResult result = sc_recognition_context_process_frame(context, image_descr, image_data);
printf("Processing frame failed with error %d: '%s'\n", result.status,
}
// Get the results. If there is a barcode, print it!
int code_count = sc_barcode_array_get_size(new_codes);
for (int i = 0; i < code_count; i++) {
const ScBarcode * code = sc_barcode_array_get_item_at(new_codes, i);
printf("Barcode found: '%s'\n", data.str);
}
// Signal the camera that we are done reading the image buffer.
sc_camera_enqueue_frame_data(camera, image_data);
// Cleanup the memory we used.
}
// Signal to the context that the frame sequence is finished.
// Cleanup all objects.
}