Background: In my personal Qt project, I need a picture segmentation algorithm. This algorithm has been implemented on Matlab before, and it is a bit troublesome to convert it into a C++ version, so try to realize this function by combining Qt and Matlab programming.
Note: All the following functions and configuration process, the required software has been installed successfully by default
environment
Win10
Qt 5.12.10 (MSVC 2017 64 bit)
Matlab R2022b
Matlab function implementation
Write the function image_segment.m about image segmentation in Matlab, assuming its code is as follows:
// 具体代码略去,函数的主要格式如下,必须是带参数的函数而不是脚本,否则会报错
function image_segment(rgb_path)
close all;
%UNTITLED7 Summary of this function goes here
% Detailed explanation goes here
I=imread(rgb_path);% normal map loading
I=rgb2gray(I);
...
...
imwrite(I,"mask.png");%输出结果,保存为tif图片
end
Convert Matlab function into dynamic link library
First check whether your own mcc compiler is available
Enter the following command
!mcc
If normal, the following results will appear:
mcc Compile MATLAB functions for deployment outside MATLAB.
mcc [-options] fun [fun2...]
Options applicable across all deployment targets:
-? Display help for the mcc command
-a Add additional files or directories to be included in the build
-d Build output directory
-g Include debugging symbol information
-I Add a directory to be searched for MATLAB files
-v Verbose display of build
MATLAB Compiler
Standalone Application (MATLAB|Hadoop|Spark)
mcc -m <matlabFile.m>
Excel Add-In
mcc -W 'excel:<addinName>,<className>' -b <matlabFile.m>
Hadoop Deployable Archive
mcc -H -W 'hadoop:<archiveName>,CONFIG:<configFile.txt>' <mapperFile.m> <reducerFile.m> <datastoreInfo.mat>
Spark Application
mcc -C -W 'spark:<appName>,<sparkMajorVersion>' <matlabFile.m>
MATLAB Compiler SDK
C Shared Library
mcc -W lib:<libraryName> <matlabFile.m>
C++ Shared Library
mcc -W cpplib:<libraryName> <matlabFile.m>
.NET Assembly
mcc -W 'dotnet:<assemblyName>,<className>' <matlabFile.m>
Java Package
mcc -W 'java:<packageName>,<className>' <matlabFile.m>
Python Package
mcc -W python:<pythonPackageName> <matlabFile.m>
COM Component
mcc -W com:<componentName> <matlabFile.m>
MATLAB Production Server
Deployable Archive
mcc -W CTF:<archiveName> -U <matlabFile.m>
Deployable Archive for Excel Add-In
mcc -W mpsxl:<addinName> <matlabFile.m>
Replace single quotes with double when executing the mcc command from a Windows Command Prompt.
For more details, execute "doc mcc" from MATLAB.
Then enter it on the command line mbuild -setup
, and the following results will appear. Since we are developing in a C++ environment, choose the option with C++
Then enter it on the command line mex -setup
, and also choose the option with C++
Then click APP, and click the drop-down option
to select Liberty Complier
In the "TYPE" part, select C++ shared Library, "EXPORTED FUNCTIONS" is the m-file that needs to be exported, click the + sign to select the function to be written, select Runtime downloaded from web, and finally click Package
A subdirectory with the same name as the function will be generated under the project file
Enter the for_redistribution_files_only folder, put the generated dll/lib/h file into the code folder of the Qt project
Qt call
Reference
here and the previous step, you can refer to part3 and part4.1-part4.5 in this link
Operation and problem solving
After the above steps are executed in sequence, start to integrate the relevant functions into the Qt project
- First in mainwindow.h, add
#include "image_segment.h
the header file- Then perform
limage_segmentInitialize()
initialization, this step is necessary
Since my Matlab function needs to accept the address of the input image, then we write it as follows
QString str = "你的图像地址;
char * charStr = str.toLocal8Bit().data();
mwArray rgb_path(charStr);
image_segment(rgb_path);
It should be noted that when matlab receives parameter input, it must be in mwArray format. Here I am a string address, so it needs to be converted into a format that matlab can recognize. At the same time, you need to pay attention to the format of the image address when writing in Qt, otherwise there will be a reading error