-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
cuixing158
committed
Aug 12, 2023
0 parents
commit b67dd16
Showing
7 changed files
with
204 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
%================================================================ | ||
% This class abstracts the API to an external OpenCV library. | ||
% It implements static methods for updating the build information | ||
% at compile time and build time. | ||
|
||
classdef OpenCV_API < coder.ExternalDependency | ||
%#codegen | ||
|
||
methods (Static) | ||
|
||
function bName = getDescriptiveName(~) | ||
bName = 'OpenCV_API'; | ||
end | ||
|
||
function tf = isSupportedContext(buildContext) | ||
myTarget = {'mex','rtw'};% 验证代码生成目标为mex或者dll,lib,exe | ||
if buildContext.isCodeGenTarget(myTarget) | ||
tf = true; | ||
else | ||
error('OpenCV_API only supported for mex, lib, exe, dll'); | ||
end | ||
|
||
% hw = buildContext.getHardwareImplementation(); | ||
|
||
end | ||
|
||
function updateBuildInfo(buildInfo, buildContext) | ||
% 输入buildInfo请参考:RTW.BuildInfo | ||
% 输入buildContext请参考:coder.BuildConfig class | ||
% | ||
% Get file extensions for the current platform | ||
% [~, linkLibExt, execLibExt, ~] = buildContext.getStdLibInfo(); | ||
|
||
% Code to run on Linux platform | ||
includeFilePath = fullfile("E:\opencv4_4_0\opencv\MinGW64_v8_OpenCV4_4_Contrib_install\include"); | ||
buildInfo.addIncludePaths(includeFilePath); | ||
|
||
% Link files | ||
libPath = fullfile("E:\opencv4_4_0\opencv\MinGW64_v8_OpenCV4_4_Contrib_install\x64\mingw\lib"); | ||
linkFiles = "libopencv_world440.dll.a"; | ||
linkPath = libPath; | ||
linkPriority = ""; | ||
linkPrecompiled = true; | ||
linkLinkOnly = true; | ||
group = ''; | ||
buildInfo.addLinkObjects(linkFiles, linkPath, ... | ||
linkPriority, linkPrecompiled, linkLinkOnly, group); | ||
|
||
% include and source path | ||
% buildInfo.addIncludePaths("./"); | ||
% buildInfo.addSourcePaths("./"); | ||
end | ||
|
||
%API for library function 'imread' | ||
function outImg = imread(imagePath) | ||
arguments | ||
imagePath (1,1) string | ||
end | ||
|
||
outImg = coder.nullcopy(zeros(480,640,3,"uint8")); | ||
if coder.target('MATLAB') | ||
% running in MATLAB, use built-in addition | ||
outImg = imread_opencv_mex(imagePath); | ||
else | ||
% Add the required include statements to the generated function code | ||
coder.cinclude('opencvAPI.h'); | ||
% include external C++ functions | ||
coder.updateBuildInfo('addSourceFiles', "opencvAPI.cpp"); | ||
|
||
% 调用OpenCV C++代码包装器 | ||
imgPath = [char(imagePath),0]; | ||
coder.ceval('imreadOpenCV', coder.rref(imgPath),coder.wref(outImg)); | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# MATLAB MEX file For C/C++ code generation | ||
|
||
![logo](images/logo.PNG) | ||
|
||
## OverView | ||
|
||
In order to call external C/C++ library functions, it is generally recommended to use the [mex](https://ww2.mathworks.cn/help/matlab/ref/mex.html) built-in function to compile the source code into a mex executable file, but the disadvantage is that it is not easy to generate C/C++ code in turn if there are other matlab code mixed in. This example is just to show how to use [codegen](https://ww2.mathworks.cn/help/coder/ref/codegen.html) two-way through this process, not limited to the example itself, is a general method, another advantage is not limited to the code generation of various restrictions, fully integrated with C/C++ programming. | ||
|
||
## Requirements | ||
|
||
- MATLAB | ||
- Matlab Coder toolbox | ||
- [Supported and Compatible Compilers](https://ww2.mathworks.cn/en/support/requirements/supported-compilers.html) | ||
- Your External C/C++ Library(This example uses OpenCV as an example) | ||
|
||
## How to setup | ||
|
||
### 1.Configuring the compiler | ||
|
||
In the command window,configure your complier. | ||
|
||
```matlab | ||
mex -setup C++ | ||
``` | ||
|
||
### 2.Source Code Preparation | ||
|
||
Prepare your C/C++ code and MATLAB entry-point function.Prepare the implementation of the `updateBuildInfo(buildInfo, buildContext)` member function, rewritten according to the path of the external library. (header files and library files). | ||
|
||
### 3.Generate or Compile | ||
|
||
Generate or compile the files you want with the `codegen` command. | ||
For example: | ||
|
||
```matlab | ||
imagePath = "./test_480x640x3.jpg"; | ||
input1 = coder.typeof(imagePath); | ||
input1.StringLength=inf; | ||
codegen -config:mex imread_opencv -args {input1} -lang:c++ -report | ||
``` |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
function outImg = imread_opencv(imagePath)%#codegen | ||
% Brief: Write a function imreadOpencv that calls the external library function. | ||
% Details: | ||
% Read a uint8 image of size 480*640 | ||
% | ||
% Syntax: | ||
% outImg = imread_opencv(imagePath) | ||
% | ||
% Inputs: | ||
% imagePath - [1,1] size,[string] type,image path | ||
% | ||
% Outputs: | ||
% outImg - [480,640] size,[uint8] type,Description | ||
% | ||
% codegen command: | ||
% imagePath = "./test_480x640_uint8.jpg"; | ||
% input1 = coder.typeof(imagePath); | ||
% input1.StringLength=inf; | ||
% | ||
% codegen -config:mex imread_opencv -args {input1} -lang:c++ -report | ||
% | ||
% Usage Example: | ||
% imagePath = "./test_480x640_uint8.jpg"; | ||
% result = imread_opencv(imagePath); | ||
% | ||
% | ||
% Example: | ||
% None | ||
% | ||
% See also: None | ||
|
||
|
||
arguments | ||
imagePath (1,1) string | ||
end | ||
outImg = OpenCV_API.imread(imagePath); | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#include "opencvAPI.h" | ||
|
||
// 对应OpenCV的cv::Mat转MATLAB uint8类型或logical图像 | ||
void convertCVToMatrix(cv::Mat &srcImg, int rows, int cols, int channels, unsigned char dst[]) { | ||
CV_Assert(srcImg.type() == CV_8UC1 || srcImg.type() == CV_8UC3); | ||
size_t elems = rows * cols; | ||
if (channels == 3) { | ||
cv::Mat channels[3]; | ||
cv::split(srcImg.t(), channels); | ||
|
||
memcpy(dst, channels[2].data, elems * sizeof(unsigned char)); //copy channel[2] to the red channel | ||
memcpy(dst + elems, channels[1].data, elems * sizeof(unsigned char)); // green | ||
memcpy(dst + 2 * elems, channels[0].data, elems * sizeof(unsigned char)); // blue | ||
} else { | ||
srcImg = srcImg.t(); | ||
memcpy(dst, srcImg.data, elems * sizeof(unsigned char)); | ||
} | ||
} | ||
|
||
|
||
void imreadOpenCV(const char *imagePath, unsigned char outImg[]) { | ||
std::string imgPath(imagePath); | ||
cv::Mat srcImg = cv::imread(imgPath, cv::IMREAD_COLOR); | ||
if (srcImg.empty()) { | ||
std::runtime_error("read image is empty!"); | ||
} | ||
|
||
convertCVToMatrix(srcImg, srcImg.rows, srcImg.cols, srcImg.channels(), outImg); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
|
||
#ifndef _OPENCVAPI_ALLPLATFORM_ | ||
#define _OPENCVAPI_ALLPLATFORM_ | ||
|
||
// base | ||
#include <iostream> | ||
#include <string> | ||
#include <fstream> | ||
#include <vector> | ||
|
||
// OpenCV | ||
#include <opencv2/core.hpp> | ||
#include <opencv2/imgcodecs.hpp> | ||
#include <opencv2/imgproc.hpp> | ||
|
||
|
||
// "marshalling" | ||
void convertCVToMatrix(cv::Mat &srcImg, int rows, int cols, int channels, unsigned char dst[]); | ||
|
||
void imreadOpenCV(const char *imagePath, unsigned char outImg[]); | ||
|
||
#endif |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.