Use Mex to compile opencv in MATLAB to implement drawing board Function

Source: Internet
Author: User

Drawing is an important way to mark and visualize data.

By integrating the drawing board function in MATLAB, it can facilitate scientific computing.


1. Set MATLAB to support opencv Compilation

Operating System: Qilin 14.04 (based on Ubuntu 14.04)

Command: Mex-V

-> mexopts.sh sourced from directory (DIR = $MATLAB/bin)   FILE = /usr/local/MATLAB/R2013a/bin/mexopts.sh----------------------------------------------------------------->    MATLAB                = /usr/local/MATLAB/R2013a->    CC                    = gcc->    CC flags:         CFLAGS             = -ansi -D_GNU_SOURCE  -fexceptions -I/usr/include/opencv -fPIC -fno-omit-frame-pointer -pthread         CDEBUGFLAGS        = -g         COPTIMFLAGS        = -O -DNDEBUG         CLIBS              = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lm -lstdc++  -lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_objdetect -lopencv_ocl -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab         arguments          =  -DMX_COMPAT_32->    CXX                   = g++->    CXX flags:         CXXFLAGS           = -ansi -D_GNU_SOURCE -std=c++0x -fPIC -fno-omit-frame-pointer -pthread         CXXDEBUGFLAGS      = -g         CXXOPTIMFLAGS      = -O -DNDEBUG         CXXLIBS            = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lm  -lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_objdetect -lopencv_ocl -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab         arguments          =  -DMX_COMPAT_32->    FC                    = gfortran->    FC flags:         FFLAGS             = -fexceptions -fbackslash -fPIC -fno-omit-frame-pointer         FDEBUGFLAGS        = -g         FOPTIMFLAGS        = -O         FLIBS              = -Wl,-rpath-link,/usr/local/MATLAB/R2013a/bin/glnxa64 -L/usr/local/MATLAB/R2013a/bin/glnxa64 -lmx -lmex -lmat -lm         arguments          =  -DMX_COMPAT_32->    LD                    = gcc->    Link flags:         LDFLAGS            = -pthread -shared -Wl,--version-script,/usr/local/MATLAB/R2013a/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined         LDDEBUGFLAGS       = -g         LDOPTIMFLAGS       = -O         LDEXTENSION        = .mexa64         arguments          = ->    LDCXX                 = ->    Link flags:         LDCXXFLAGS         =          LDCXXDEBUGFLAGS    =          LDCXXOPTIMFLAGS    =          LDCXXEXTENSION     =          arguments          = 

Edit the mexopts. Sh file to compile opencv in Mex. (You must install opencv in advance)


2. Compile the drawcanvas. cpp file.

#include <stdlib.h>#include <mex.h>#include <matrix.h>#include "opencv2/opencv.hpp"#include <vector>#include <string> using namespace cv;#define max(a, b) ((a) > (b) ? (a) : (b))const char *commands[] = {"lines", "circles", "rectangles", "texts"};void drawLines(Mat& mat, int nrhs, const mxArray *prhs[]) {//linesxy_4_columns, linecolor, linewidth,if (nrhs != 5) {mexErrMsgTxt("Error usage for draw lines: drawcanvas(img, cmd, pts_4_column, color, width)\n");return;}double *lines = mxGetPr(prhs[2]);int lrows = mxGetM(prhs[2]),lcols = mxGetN(prhs[2]);if (lcols != 4) {mexErrMsgTxt("Error parameters for lines: it should be a mat with 4 columns.\n");return;}double *Color = mxGetPr(prhs[3]);if (mxGetNumberOfElements(prhs[3]) != 3) {mexErrMsgTxt("Error: line color should be a mat with 3 columns indicating RGB.\n");return;}Scalar color;color[0] = Color[0];color[1] = Color[1];color[2] = Color[2];int thickness = mxGetScalar(prhs[4]);int linetype = CV_AA;CvPoint startpt, endpt;for(int i = 0; i < lrows; i++) {startpt = Point(lines[i], lines[i + lrows]);endpt = Point(lines[i + 2 * lrows], lines[i + 3 * lrows]);line( mat, startpt, endpt, color, thickness, linetype );}}void drawCircles(Mat& mat, int nrhs, const mxArray *prhs[]) {//linesxy_4_columns, linecolor, linewidth,if (nrhs != 5) {mexErrMsgTxt("Error usage for draw circles: drawcanvas(img, cmd, circle_mat[x y r;], color, line_thickness)\n");return;}double *circles = mxGetPr(prhs[2]);int crows = mxGetM(prhs[2]),ccols = mxGetN(prhs[2]);if (ccols != 3) {mexErrMsgTxt("Error parameters for circles: it should be a mat with 3 columns[cx cy r;].\n");return;}double *Color = mxGetPr(prhs[3]);if (mxGetNumberOfElements(prhs[3]) != 3) {mexErrMsgTxt("Error: circle color should be a mat with 3 columns indicating RGB.\n");return;}Scalar color;color[0] = Color[0];color[1] = Color[1];color[2] = Color[2];int thickness = mxGetScalar(prhs[4]);int linetype = CV_AA;CvPoint cpt;double radius;for(int i = 0; i < crows; i++) {cpt = Point(circles[i + crows], circles[i]);radius = circles[i + 2 * crows];circle( mat, cpt, (int)radius, color, thickness, linetype, 0);}}void drawRectanges(Mat& mat, int nrhs, const mxArray *prhs[]) {//linesxy_4_columns, linecolor, linewidth,if (nrhs != 5) {mexErrMsgTxt("Error usage for draw lines: drawcanvas(img, cmd, rects_4_column, color, width)\n");return;}double *rects = mxGetPr(prhs[2]);int lrows = mxGetM(prhs[2]),lcols = mxGetN(prhs[2]);if (lcols != 4) {mexErrMsgTxt("Error parameters for lines: it should be a mat with 4 columns.\n");return;}double *Color = mxGetPr(prhs[3]);if (mxGetNumberOfElements(prhs[3]) != 3) {mexErrMsgTxt("Error: line color should be a mat with 3 columns indicating RGB.\n");return;}Scalar color;color[0] = Color[0];color[1] = Color[1];color[2] = Color[2];int thickness = mxGetScalar(prhs[4]);int linetype = CV_AA;CvPoint startpt, endpt;for(int i = 0; i < lrows; i++) {startpt = Point(rects[i], rects[i + lrows]);endpt = Point(rects[i + 2 * lrows], rects[i + 3 * lrows]);rectangle( mat, startpt, endpt, color, thickness, linetype );}}void drawTexts(Mat& mat, int nrhs, const mxArray *prhs[]) {//linesxy_4_columns, linecolor, linewidth,if (nrhs != 7) {mexErrMsgTxt("Error usage for draw texts: drawcanvas(img, cmd, sliced_text_with_#, points, fontScale, thickness, color)\n");return;}vector<string> strings;unsigned char *ptr0 = (unsigned char *)mxGetPr(prhs[2]), *ptr1 = ptr0;char *buf = mxArrayToString(prhs[2]);   //注意:Matlab的字符串类型如何转换为C的字符串类型int len = strlen(buf);char tmp[256];int cnt = 0;for(int i = 0; i < len; i++) {if (buf[i] == '#') {strings.push_back(string(tmp));//mexPrintf("%s\n", strings[strings.size()-1].c_str());cnt = 0;}else {  if (cnt < 255) {  tmp[cnt++] = buf[i];  tmp[cnt] = '\0';  }}}if (cnt > 0)strings.push_back(string(tmp));if (buf)mxFree(buf);//debug/*for(int i = 0; i < strings.size(); i++)mexPrintf("*%s\n", strings[i].c_str());return;*/double *points = (double *)mxGetPr(prhs[3]);int prows = mxGetM(prhs[3]), pcols = mxGetN(prhs[3]);if (prows != strings.size()) {mexErrMsgTxt("Error: the numbers of parsed text and pointers are not equal.\n");return;}int fontFace =  FONT_HERSHEY_PLAIN;int fontScale = mxGetScalar(prhs[4]);int thickness = max(1, mxGetScalar(prhs[5]));int linetype = CV_AA;if (fontScale <= 0) {mexErrMsgTxt("Error: fontsize is less than or equal to 0.\n");return;}double *Color = mxGetPr(prhs[6]);if (mxGetNumberOfElements(prhs[6]) != 3) {mexErrMsgTxt("Error: text color should be a mat with 3 columns indicating RGB.\n");return;}Scalar color;color[0] = Color[0];color[1] = Color[1];color[2] = Color[2];CvPoint startpt;string str;Size sz;int baseLine = 0;for(int i = 0; i < prows; i++) {startpt = Point(points[i], points[i + prows]);str = strings[i];//sz = getTextSize(str, fontFace, fontScale, thickness, &baseLine);putText( mat, str.c_str(), startpt, fontFace, fontScale, color, thickness, linetype );}}string transClassID(mxClassID id) {  switch (id) {  case mxLOGICAL_CLASS: return "mxLOGICAL_CLASS";  case mxDOUBLE_CLASS: return "mxDOUBLE_CLASS";  case mxSINGLE_CLASS: return "mxSINGLE_CLASS";  case mxINT8_CLASS: return "mxINT8_CLASS";  case mxUINT8_CLASS: return "mxUINT8_CLASS";  case mxINT16_CLASS: return "mxINT16_CLASS";  case mxUINT16_CLASS: return "mxUINT16_CLASS";  case mxINT32_CLASS: return "mxINT32_CLASS";  case mxUINT32_CLASS: return "mxUINT32_CLASS";  case mxINT64_CLASS: return "mxINT64_CLASS";  case mxUINT64_CLASS: return "mxUINT64_CLASS";  default: return "unknown";  }}void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {mxClassID classID = mxGetClassID(prhs[0]);//mexPrintf("%d --> %s\n", classID, transClassID(classID).c_str());if (classID != mxINT8_CLASS && classID != mxUINT8_CLASS) {mexErrMsgTxt("Error: input image should be uint8 type with 3 channels.\n");return;}    char buf[256];    int cmdidx = -1;mxGetString(prhs[1], buf, 255);    for(int i = 0; i < 4; i++) {    if (strcmp(buf, commands[i]) == 0)     {    cmdidx = i;    break;    }    }        if (cmdidx == -1)    {    mexErrMsgTxt("Error: command can not be recognized correctly.\n");    return;    }        const int *dims = mxGetDimensions(prhs[0]);    int height = dims[0], width = dims[1], channels = dims[2];    //mexPrintf("%d %d %d\n", height, width, channels);        if (channels != 3) {    mexErrMsgTxt("Error: input image should be of 3 channels.\n");    return;    }    if (height <= 0 || width <= 0) {    mexErrMsgTxt("Error: Wrong canvas sizes information.\n");    return;    }        //转换Matlab图像到Opencv图像    Mat mat = Mat::zeros(height, width, CV_8UC3);    char *inVals = (char *)mxGetPr(prhs[0]);    Vec3b vals;    for(int i = 0; i < mat.rows; i++)    for(int j = 0; j < mat.cols; j++) {    for(int c = 0; c < 3; c++)    vals[c] = inVals[c * mat.rows * mat.cols + j * mat.rows + i];    mat.at<Vec3b>(i, j) = vals;    }        switch(cmdidx) {    case 0: drawLines(mat, nrhs, prhs); break;    case 1: drawCircles(mat, nrhs, prhs); break;    case 2: drawRectanges(mat, nrhs, prhs); break;    case 3: drawTexts(mat, nrhs, prhs); break;    default: return;    };        nlhs = 1;    plhs[0] = mxCreateNumericArray(3, dims, mxUINT8_CLASS, mxREAL);char *outVals = (char *)mxGetPr(plhs[0]);        //转换Opencv图像到matlab图像    for(int i = 0; i < mat.rows; i++)    for(int j = 0; j < mat.cols; j++) {    vals = mat.at<Vec3b>(i, j);    for(int c = 0; c < 3; c++)    outVals[c * mat.rows * mat.cols + j * mat.rows + i] = vals[c];    }}

3. MATLAB Testing Program

mex drawcanvas.cpp;img = im2uint8(zeros(500, 500, 3));close all;tic;%绘制线%drawcanvas(img, cmd, pts_4_column, color, width)img = drawcanvas(img, 'lines', rand(300, 4) * 500, [255 0 255], 1);%绘制圆%drawcanvas(img, cmd, circle_mat[x y r;], color, line_thickness)xy = rand(30, 2) * 450 + 50;r = rand(30, 1) .* (30 + rand(30, 1) * 100);circles = [xy r];img = drawcanvas(img, 'circles', circles, [0 0 255], 2);%绘制实心圆--thickness=-1img = drawcanvas(img, 'circles', [200 200 50], [0 255 255], -1);  %绘制矩形%drawcanvas(img, cmd, rects_4_column, color, width)img = drawcanvas(img, 'rectangles', rand(30, 4) * 200 + 100, [255 0 0], 1);%绘制英文字符数组,用#分割不同数组%drawcanvas(img, cmd, sliced_text_with_#\\n, points, fontScale, thickness, color)img = drawcanvas(img, 'texts', 'Hello#world', [30 200; 200 250], 4, 4, [0 255 0]);tocimshow(img);imwrite(img, 'canvas.png', 'png');



4. Running result


Use Mex to compile opencv in MATLAB to implement drawing board Function

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.