8000 Add a simple C++ wrapper for ACF Detector by zeyuanxy · Pull Request #5 · pdollar/toolbox · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add a simple C++ wrapper for ACF Detector #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion detector/acfDetect.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function bbs = acfDetect( I, detector, fileName )
function bbs = acfDetect( I, detectorFileName, fileName )
% Run aggregate channel features object detector on given image(s).
%
% The input 'I' can either be a single image (or filename) or a cell array
Expand Down Expand Up @@ -37,6 +37,8 @@

% run detector on every image
if(nargin<3), fileName=''; end; multiple=iscell(I);
if(isempty(detectorFileName) || ~exist(detectorFileName)), bbs = 1; return; end
t = load(detectorFileName); detector = t.detector;
if(~isempty(fileName) && exist(fileName,'file')), bbs=1; return; end
if(~multiple), bbs=acfDetectImg(I,detector); else
n=length(I); bbs=cell(n,1);
Expand Down
39 changes: 39 additions & 0 deletions detector/cpp_wrapper/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Use the C++ Wrapper for ACF Detector

We will illustrate how to use the simple C++ wrapper for the ACF detector.

###Compile

See http://blogs.mathworks.com/loren/2011/02/03/creating-c-shared-libraries-and-dlls/ for how to compile the cpp files.

The sample `main.cpp` contains the simple detection function that runs the detector on a sample image. You can easily modify it to fit for detecting more images.

```sh
mwArray I("test.png");
mwArray detectorFileName("../models/AcfInriaDetector.mat");
mwArray fileName("output.txt");
mwArray bbs;
acfDetect(1, bbs, I, detectorFileName, fileName);
cout << bbs << endl;
```

Please note that here I modify the original `acfDetect.m` to provide more flexibility. The followings are the code added by me.

```
if(isempty(detectorFileName) || ~exist(detectorFileName)), bbs = 1; return; end
t = load(detectorFileName); detector = t.detector;
```

###Run

To deploy the binary file to the group of machines, you do not need to install the heavy-weighted MATLAB. But you need to install the **MATLAB Compiler Runtime** at http://www.mathworks.com/products/compiler/mcr/index.html. We recommend you choose the version corresponding to your compiled files.

After installing the **MATLAB Compiler Runtime**, you need to add its paths to the environments of the system. You can add the following snippets to your `.bashrc` or `.zshrc`. The variable `MCR_ROOT` specifies the directory where you install the **MATLAB Compiler Runtime**.

```sh
export $MCR_ROOT=/home/szy/MCR
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MCR_ROOT/v84/runtime/glnxa64:$MCR_ROOT/v84/bin/glnxa64:$MCR_ROOT/v84/sys/os/glnxa64:$MCR_ROOT/v84/sys/opengl/lib/glnxa64
export XAPPLRESDIR=$MCR_ROOT/v84/X11/app-defaults
```

Then you can just execute the binary file and make the great object detection algorithm to be able to used in C++.
122 changes: 122 additions & 0 deletions detector/cpp_wrapper/libacf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
//
// MATLAB Compiler: 5.2 (R2014b)
// Date: Fri May 22 15:12:12 2015
// Arguments: "-B" "macro_default" "-v" "-W" "cpplib:libacf" "-T" "link:lib"
// "acfDetect.m"
//

#include <stdio.h>
#define EXPORTING_libacf 1
#include "libacf.h"

static HMCRINSTANCE _mcr_inst = NULL;


#ifdef __cplusplus
extern "C" {
#endif

static int mclDefaultPrintHandler(const char *s)
{
return mclWrite(1 /* stdout */, s, sizeof(char)*strlen(s));
}

#ifdef __cplusplus
} /* End extern "C" block */
#endif

#ifdef __cplusplus
extern "C" {
#endif

static int mclDefaultErrorHandler(const char *s)
{
int written = 0;
size_t len = 0;
len = strlen(s);
written = mclWrite(2 /* stderr */, s, sizeof(char)*len);
if (len > 0 && s[ len-1 ] != '\n')
written += mclWrite(2 /* stderr */, "\n", sizeof(char));
return written;
}

#ifdef __cplusplus
} /* End extern "C" block */
#endif

/* This symbol is defined in shared libraries. Define it here
* (to nothing) in case this isn't a shared library.
*/
#ifndef LIB_libacf_C_API
#define LIB_libacf_C_API /* No special import/export declaration */
#endif

LIB_libacf_C_API
bool MW_CALL_CONV libacfInitializeWithHandlers(
mclOutputHandlerFcn error_handler,
mclOutputHandlerFcn print_handler)
{
int bResult = 0;
if (_mcr_inst != NULL)
return true;
if (!mclmcrInitialize())
return false;
{
mclCtfStream ctfStream =
mclGetEmbeddedCtfStream((void *)(libacfInitializeWithHandlers));
if (ctfStream) {
bResult = mclInitializeComponentInstanceEmbedded( &_mcr_inst,
error_handler,
print_handler,
ctfStream);
mclDestroyStream(ctfStream);
} else {
bResult = 0;
}
}
if (!bResult)
return false;
return true;
}

LIB_libacf_C_API
bool MW_CALL_CONV libacfInitialize(void)
{
return libacfInitializeWithHandlers(mclDefaultErrorHandler, mclDefaultPrintHandler);
}

LIB_libacf_C_API
void MW_CALL_CONV libacfTerminate(void)
{
if (_mcr_inst != NULL)
mclTerminateInstance(&_mcr_inst);
}

LIB_libacf_C_API
void MW_CALL_CONV libacfPrintStackTrace(void)
{
char** stackTrace;
int stackDepth = mclGetStackTrace(&stackTrace);
int i;
for(i=0; i<stackDepth; i++)
{
mclWrite(2 /* stderr */, stackTrace[i], sizeof(char)*strlen(stackTrace[i]));
mclWrite(2 /* stderr */, "\n", sizeof(char)*strlen("\n"));
}
mclFreeStackTrace(&stackTrace, stackDepth);
}


LIB_libacf_C_API
bool MW_CALL_CONV mlxAcfDetect(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
{
return mclFeval(_mcr_inst, "acfDetect", nlhs, plhs, nrhs, prhs);
}

LIB_libacf_CPP_API
void MW_CALL_CONV acfDetect(int nargout, mwArray& bbs, const mwArray& I, const mwArray&
detectorFileName, const mwArray& fileName)
{
mclcppMlfFeval(_mcr_inst, "acfDetect", nargout, 1, 3, &bbs, &I, &detectorFileName, &fileName);
}

112 changes: 112 additions & 0 deletions detector/cpp_wrapper/libacf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
//
// MATLAB Compiler: 5.2 (R2014b)
// Date: Fri May 22 15:12:12 2015
// Arguments: "-B" "macro_default" "-v" "-W" "cpplib:libacf" "-T" "link:lib"
// "acfDetect.m"
//

#ifndef __libacf_h
#define __libacf_h 1

#if defined(__cplusplus) && !defined(mclmcrrt_h) && defined(__linux__)
# pragma implementation "mclmcrrt.h"
#endif
#include "mclmcrrt.h"
#include "mclcppclass.h"
#ifdef __cplusplus
extern "C" {
#endif

#if defined(__SUNPRO_CC)
/* Solaris shared libraries use __global, rather than mapfiles
* to define the API exported from a shared library. __global is
* only necessary when building the library -- files including
* this header file to use the library do not need the __global
* declaration; hence the EXPORTING_<library> logic.
*/

#ifdef EXPORTING_libacf
#define PUBLIC_libacf_C_API __global
#else
#define PUBLIC_libacf_C_API /* No import statement needed. */
#endif

#define LIB_libacf_C_API PUBLIC_libacf_C_API

#elif defined(_HPUX_SOURCE)

#ifdef EXPORTING_libacf
#define PUBLIC_libacf_C_API __declspec(dllexport)
#else
#define PUBLIC_libacf_C_API __declspec(dllimport)
#endif

#define LIB_libacf_C_API PUBLIC_libacf_C_API


#else

#define LIB_libacf_C_API

#endif

/* This symbol is defined in shared libraries. Define it here
* (to nothing) in case this isn't a shared library.
*/
#ifndef LIB_libacf_C_API
#define LIB_libacf_C_API /* No special import/export declaration */
#endif

extern LIB_libacf_C_API
bool MW_CALL_CONV libacfInitializeWithHandlers(
mclOutputHandlerFcn error_handler,
mclOutputHandlerFcn print_handler);

extern LIB_libacf_C_API
bool MW_CALL_CONV libacfInitialize(void);

extern LIB_libacf_C_API
void MW_CALL_CONV libacfTerminate(void);



extern LIB_libacf_C_API
void MW_CALL_CONV libacfPrintStac 9E88 kTrace(void);

extern LIB_libacf_C_API
bool MW_CALL_CONV mlxAcfDetect(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);


#ifdef __cplusplus
}
#endif

#ifdef __cplusplus

/* On Windows, use __declspec to control the exported API */
#if defined(_MSC_VER) || defined(__BORLANDC__)

#ifdef EXPORTING_libacf
#define PUBLIC_libacf_CPP_API __declspec(dllexport)
#else
#define PUBLIC_libacf_CPP_API __declspec(dllimport)
#endif

#define LIB_libacf_CPP_API PUBLIC_libacf_CPP_API

#else

#if !defined(LIB_libacf_CPP_API)
#if defined(LIB_libacf_C_API)
#define LIB_libacf_CPP_API LIB_libacf_C_API
#else
#define LIB_libacf_CPP_API /* empty! */
#endif
#endif

#endif

extern LIB_libacf_CPP_API void MW_CALL_CONV acfDetect(int nargout, mwArray& bbs, const mwArray& I, const mwArray& detectorFileName, const mwArray& fileName);

#endif
#endif
Binary file added detector/cpp_wrapper/libacf.so
Binary file not shown.
30 changes: 30 additions & 0 deletions detector/cpp_wrapper/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "libacf.h"
#include <iostream>

using namespace std;

int main(int argc, char* argv[]) {
// Initialize the MATLAB Compiler Runtime global state
if (!mclInitializeApplication(NULL, 0)) {
cerr << "Could not initialize the application properly."
<< std::endl;
return -1;
}
// Initialize the ACF library
if (!libacfInitialize()) {
std::cerr << "Could not initialize the library properly."
<< std::endl;
return -1;
}

mwArray I("test.png");
mwArray detectorFileName("../models/AcfInriaDetector.mat");
mwArray fileName("output.txt");
mwArray bbs;
acfDetect(1, bbs, I, detectorFileName, fileName);
cout << bbs << endl;

// Shut down the library and the application global state.
libacfTerminate();
mclTerminateApplication();
}
9 changes: 9 additions & 0 deletions detector/cpp_wrapper/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
343.1,176.44,97.918,238.82,107.26
85.188,196.06,148.72,362.74,97.651
432.71,170.06,105.8,258.06,84.546
205.86,179.72,81.683,199.23,76.498
563.07,185.98,97.918,238.82,73.746
620.22,198.61,177.14,432.05,64.181
505.14,179.45,89.569,218.46,54.661
295.67,188.2,89.569,218.46,46.424
254.1,191.7,68.84,167.9,31.968
Binary file added detector/cpp_wrapper/test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
0