From 2d8d3a289550207ce3b3ff97d275353cc947b0fe Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Sun, 16 Oct 2016 22:10:20 -0400 Subject: [PATCH] Added simple C binding --- src/CMakeLists.txt | 8 +++ src/bindings/c/CMakeLists.txt | 24 ++++++++ src/bindings/c/alpr_c.cpp | 105 ++++++++++++++++++++++++++++++++++ src/bindings/c/alpr_c.h | 70 +++++++++++++++++++++++ src/bindings/c/alprc_test.c | 80 ++++++++++++++++++++++++++ 5 files changed, 287 insertions(+) create mode 100644 src/bindings/c/CMakeLists.txt create mode 100644 src/bindings/c/alpr_c.cpp create mode 100644 src/bindings/c/alpr_c.h create mode 100644 src/bindings/c/alprc_test.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 38d8120..f90a8e3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -47,6 +47,10 @@ if ( NOT DEFINED WITH_BINDING_JAVA ) SET(WITH_BINDING_JAVA ON) ENDIF() +if ( NOT DEFINED WITH_BINDING_C ) + SET(WITH_BINDING_C ON) +ENDIF() + if ( NOT DEFINED WITH_BINDING_PYTHON ) SET(WITH_BINDING_PYTHON ON) ENDIF() @@ -203,6 +207,10 @@ ENDIF() if (WITH_BINDING_PYTHON) add_subdirectory(bindings/python) ENDIF() + +if (WITH_BINDING_C) +add_subdirectory(bindings/c) +ENDIF() if (WITH_BINDING_GO) set(OPENALPR_LIB_GO openalprgo) diff --git a/src/bindings/c/CMakeLists.txt b/src/bindings/c/CMakeLists.txt new file mode 100644 index 0000000..25d08e2 --- /dev/null +++ b/src/bindings/c/CMakeLists.txt @@ -0,0 +1,24 @@ + +cmake_minimum_required (VERSION 2.6) + + +include_directories(../../openalpr/) + + +set(alprc_source + alpr_c.cpp +) + + +add_library(openalprc SHARED ${alprc_source}) + +set_target_properties(openalprc PROPERTIES SOVERSION ${OPENALPR_MAJOR_VERSION}) + +TARGET_LINK_LIBRARIES(openalprc openalpr) + + +add_executable(alprc_test alprc_test.c) +TARGET_LINK_LIBRARIES(alprc_test openalprc) + +install (TARGETS openalprc DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) +install (FILES alpr_c.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include) diff --git a/src/bindings/c/alpr_c.cpp b/src/bindings/c/alpr_c.cpp new file mode 100644 index 0000000..3ef6192 --- /dev/null +++ b/src/bindings/c/alpr_c.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2016 OpenALPR Technology, Inc. + * Open source Automated License Plate Recognition [http://www.openalpr.com] + * + * This file is part of OpenALPR. + * + * OpenALPR is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License + * version 3 as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +#include "alpr_c.h" +#include +#include +#include + +OPENALPR* openalpr_init(const char* country, const char* configFile, const char* runtimeDir) +{ + alpr::Alpr* alpr_inst = new alpr::Alpr(country, configFile, runtimeDir); + + return (OPENALPR*) alpr_inst; +} + +// Set the country used for plate recognition +void openalpr_set_country(OPENALPR* instance, const char* country) +{ + ((alpr::Alpr*) instance)->setCountry(country); +} + +// Update the prewarp setting without reloading the library +void openalpr_set_prewarp(OPENALPR* instance, const char* prewarp_config) +{ + ((alpr::Alpr*) instance)->setPrewarp(prewarp_config); +} + +// Update the detection mask without reloading the library +void openalpr_set_mask(OPENALPR* instance, unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight) +{ + ((alpr::Alpr*) instance)->setMask(pixelData, bytesPerPixel, imgWidth, imgHeight); +} + +// Enable/disable region detection. Pass a 0 or 1 +void openalpr_set_detect_region(OPENALPR* instance, int detectRegion) +{ + ((alpr::Alpr*) instance)->setDetectRegion(detectRegion); +} + +void openalpr_set_topn(OPENALPR* instance, int topN) +{ + ((alpr::Alpr*) instance)->setTopN(topN); +} + +void openalpr_set_default_region(OPENALPR* instance, const char* region) +{ + ((alpr::Alpr*) instance)->setDefaultRegion(region); +} + + + +// Recognizes the provided image and responds with JSON. +// Caller must call free() on the returned object +char* openalpr_recognize_rawimage(OPENALPR* instance, unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight, AlprCRegionOfInterest roi) +{ + std::vector rois; + alpr::AlprRegionOfInterest cpproi(roi.x, roi.y, roi.width, roi.height); + rois.push_back(cpproi); + + alpr::AlprResults results = ((alpr::Alpr*) instance)->recognize(pixelData,bytesPerPixel, imgWidth, imgHeight, rois); + std::string json_string = alpr::Alpr::toJson(results); + + char* result_obj = strdup(json_string.c_str()); + + return result_obj; + +} + +char* openalpr_recognize_encodedimage(OPENALPR* instance, unsigned char* bytes, long long length, AlprCRegionOfInterest roi) +{ + std::vector rois; + alpr::AlprRegionOfInterest cpproi(roi.x, roi.y, roi.width, roi.height); + rois.push_back(cpproi); + + std::vector byte_vector(length); + memcpy(&byte_vector[0], bytes, length*sizeof(char)); + + alpr::AlprResults results = ((alpr::Alpr*) instance)->recognize(byte_vector, rois); + std::string json_string = alpr::Alpr::toJson(results); + + char* result_obj = strdup(json_string.c_str()); + + return result_obj; +} + +void openalpr_cleanup(OPENALPR* instance) +{ + delete ((alpr::Alpr*) instance); +} \ No newline at end of file diff --git a/src/bindings/c/alpr_c.h b/src/bindings/c/alpr_c.h new file mode 100644 index 0000000..a357488 --- /dev/null +++ b/src/bindings/c/alpr_c.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016 OpenALPR Technology, Inc. + * Open source Automated License Plate Recognition [http://www.openalpr.com] + * + * This file is part of OpenALPR. + * + * OpenALPR is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License + * version 3 as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + + +#ifndef ALPR_C_H +#define ALPR_C_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void OPENALPR; + +struct AlprCRegionOfInterest +{ + int x; + int y; + int width; + int height; +}; + +// Initializes the openALPR library and returns a pointer to the OpenALPR instance +OPENALPR* openalpr_init(const char* country, const char* configFile, const char* runtimeDir); + +// Set the country used for plate recognition +void openalpr_set_country(OPENALPR* instance, const char* country); + +// Update the prewarp setting without reloading the library +void openalpr_set_prewarp(OPENALPR* instance, const char* prewarp_config); +// Update the detection mask without reloading the library +void openalpr_set_mask(OPENALPR* instance, unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight); + +// Enable/disable region detection. Pass a 0 or 1 +void openalpr_set_detect_region(OPENALPR* instance, int detectRegion); +void openalpr_set_topn(OPENALPR* instance, int topN); +void openalpr_set_default_region(OPENALPR* instance, const char* region); + +// Recognizes the provided image and responds with JSON. +// Image is expected to be raw pixel data (BGR, 3 channels) +// Caller must call free() on the returned object +char* openalpr_recognize_rawimage(OPENALPR* instance, unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight, struct AlprCRegionOfInterest roi); + +// Recognizes the encoded (e.g., JPEG, PNG) image. bytes are the raw bytes for the image data. +char* openalpr_recognize_encodedimage(OPENALPR* instance, unsigned char* bytes, long long length, struct AlprCRegionOfInterest roi); + +void openalpr_cleanup(OPENALPR* instance); + + +#ifdef __cplusplus +} +#endif + +#endif /* ALPR_C_H */ + diff --git a/src/bindings/c/alprc_test.c b/src/bindings/c/alprc_test.c new file mode 100644 index 0000000..f6b9f8b --- /dev/null +++ b/src/bindings/c/alprc_test.c @@ -0,0 +1,80 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: alprc_test.c + * Author: mhill + * + * Created on October 16, 2016, 11:09 AM + */ + +#include +#include +#include "alpr_c.h" + +void ReadFile(const char *name, char** buffer, size_t* size) +{ + FILE *file; + + //Open file + file = fopen(name, "rb"); + if (!file) + { + fprintf(stderr, "Unable to open file %s", name); + return; + } + + //Get file length + fseek(file, 0, SEEK_END); + *size=ftell(file); + fseek(file, 0, SEEK_SET); + + //Allocate memory + *buffer=(char *)malloc(*size+1); + if (!(*buffer)) + { + fprintf(stderr, "Memory error!"); + fclose(file); + return; + } + + //Read file contents into buffer + fread(*buffer, *size, 1, file); + fclose(file); + +} + +/* + * + */ +int main(int argc, char** argv) { + + OPENALPR* openalpr = openalpr_init("us", "/etc/openalpr/openalpr.conf", "/usr/share/openalpr/runtime_data/"); + + const char* IMAGE_FILE="/storage/projects/alpr/samples/testing/car1.jpg"; + size_t size; + char* buffer; + printf("Loading image: %s\n", IMAGE_FILE); + ReadFile(IMAGE_FILE, &buffer, &size); + + struct AlprCRegionOfInterest roi; + roi.x = 0; + roi.y = 0; + roi.width = 1024; + roi.height = 768; + + printf("Recognizing plates\n"); + printf("Image size: %lu\n", (long) size); + char* plate_json = openalpr_recognize_encodedimage(openalpr, buffer, size, roi); + printf("results:\n%s\n", plate_json); + free(plate_json); + free(buffer); + + openalpr_cleanup(openalpr); + + return (EXIT_SUCCESS); +} +