How to use OpenCV in a C++ S-Function?

1 次查看(过去 30 天)
Hello,
I would like to use the OpenCV function cvtColor to change an image from RGB into Grayscale using a S-Function in Simulink. Like this:
In order for the input to be used with OpenCV it needs to be converted into cv::Mat, I found that this can be done with the OpenCV Interface C++ API, but I do not know exactly how to do it.
My knowledge of S-Functions is limited but, as far as I know, the conversion needs to be done inside the mdlOutputs method. Something similar to this:
static void mdlOutputs(SimStruct *S, int_T tid)
{
const uint8_T *u0 = (const uint8_T*) ssGetInputPortSignal(S,0);
uint8_T *y0 = (uint8_T*) ssGetOutputPortRealSignal(S,0);
void ocvMxArrayToImage_uint8(const mxArray *u0, cv::Mat &colourImage);
cv::cvtColor(colourImage,grayImage,CV_RGB2GRAY);
y0 *ocvMxArrayFromImage_uint8(const cv::Mat &grayImage);
}
Am I on the right track? Do you know where can I found some examples of this?
Thank you
  1 个评论
Gonzalo Salinas
Gonzalo Salinas 2018-2-8
Hi! I am currently thinking about using OpenCV with C++ inside a S-function in Simulink in order to simulate and generate C code afterwards. Did you managed to do that? Is it possible? Thanks in advance.

请先登录,再进行评论。

回答(1 个)

Prashant Arora
Prashant Arora 2017-4-28
Hi Saul,
The OpenCV Interface allows you to call OpenCV functions with mxArray. In a Simulink C-Mex S-function, real_T is basically double and not mxArray. You will need to first create a mxArray using the input from Simulink.
To achieve your use-case in an easier way, I would recommend using the following workflow:
1) Create a MATLAB mex file (not a Simulink S-function) which calls OpenCV Functions in MATLAB. You can refer to the following link for doing that.
2) Use a MATLAB function block to call this mex file in Simulink.
  2 个评论
Saul Armendariz
Saul Armendariz 2017-5-8
Hi Prashant,
Thank you fro your quick answer. I want to use S-Function, because I intend to use MATLAB Coder to convert my Simulink model into C Code.
I have made some modification to the code after some reading, but I have not being able to make it work. As soon as the simulation start Matlab crashes and I get the following error:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Fault Count: 1
Assertion in void __cdecl `anonymous-namespace'::error(const struct `anonymous-namespace'::header const ,const unsigned __int64,const void *const ,const unsigned __int64,const class boost::basic_format<char,struct std::char_traits<char>,class std::allocator<char> > &) at b:\matlab\foundation_libraries\src\fl\mem\alignment.cpp line 323: The pointer passed to 'vector_check' is invalid and does not appear to have come from any of the following routines: vector_malloc, vector_calloc, vector_realloc mxMalloc, mxCalloc*, mxRealloc*
This suggests one of the following has happened:
  • the pointer has already been freed
  • the pointer came from an incompatible allocator (e.g. new, malloc, utMalloc)
  • the pointer didn't come from any allocator (e.g. the stack, uninitialized memory)
  • a memory corruption destroyed the pointer or its header
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
My new code is:
static void mdlOutputs(SimStruct *S, int_T tid)
{
uint8_T *u0 = (uint8_T*) ssGetInputPortSignal( S,0);
uint8_T *y0 = (uint8_T*) ssGetOutputPortSignal( S,0);
// channels = Number of dimensions; size = Dimensions
mxArray *A = mxCreateNumericArray(channels,size,mxUINT8_CLASS,mxREAL);
mxSetData(A,u0);
cv::Ptr<cv::Mat> imgOriginal = ocvMxArrayToImage_uint8(A, true);
cv::Mat imgGray(width,height,CV_8UC2);
cv::cvtColor(*imgOriginal,imgGray,CV_BGR2GRAY);
mxArray *B = mxCreateNumericArray(channels,size,mxUINT8_CLASS,mxREAL);
B = ocvMxArrayFromImage_uint8(imgGray);
y0 = (uint8_T *)mxGetData(B);
} /* end mdlOutputs */
Any idea of what is wrong?
Michele Mondini
Michele Mondini 2018-2-23
Hi Prashant Arora,
I'm struggling with a similar problem. What do you mean with: "Use a MATLAB function block to call this mex file in Simulink"? Can you explain more precisely please?
I tried to do that but I found out an incompatibility between mxArrays data type, required for Mex functions, and standard data in simulink (e.g. double and uint8 image data matrices).
Thanks in advance!

请先登录,再进行评论。

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by