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

10 vues (au cours des 30 derniers jours)
Saul Armendariz
Saul Armendariz le 26 Avr 2017
Commenté : Michele Mondini le 23 Fév 2018
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 commentaire
Gonzalo Salinas
Gonzalo Salinas le 8 Fév 2018
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.

Connectez-vous pour commenter.

Réponses (1)

Prashant Arora
Prashant Arora le 28 Avr 2017
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 commentaires
Saul Armendariz
Saul Armendariz le 8 Mai 2017
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 le 23 Fév 2018
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!

Connectez-vous pour commenter.

Community Treasure Hunt

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

Start Hunting!

Translated by