matlab coder:Generating C code for general functions is a big performance problem
古いコメントを表示
To my incomplete knowledge, for matlab built-in function imwarp generated C code/mex file performance is much inferior to the open source library OpenCV, I originally wanted to use matlab coder/embeded coder to deploy the algorithm to generate C code, but found that performance is a big problem. Below I have written a simple function to test this, "myEntry" is the function to generate the C code. Again I wrote the same function with very little C++ code. The performance was then compared as follows:
function outImg = myEntry(inImg)%#codegen
% or use "tform = rigidtform2d(30,[100,200]);" The following matrix is
% obtained directly from tform.A
% note: here should "single" type input,while very sensitive to "double"
% type and highly susceptible to invalid matrix inputs!
tform = rigidtform2d(single([0.8660 -0.5000 100.0000
0.5000 0.8660 200.0000
0 0 1.0000]));
% get output view full range
[h,w,~] =size(inImg);
xLimitsIn = [0.5,w+0.5];
yLimitsIn = [0.5,h+0.5];
[xLimitsOut,yLimitsOut] = outputLimits(tform,xLimitsIn,yLimitsIn);
% global full view range
xWorldLimits = [min(xLimitsIn(1),xLimitsOut(1)),max(xLimitsIn(2),xLimitsOut(2))];
yWorldLimits = [min(yLimitsIn(1),yLimitsOut(1)),max(yLimitsIn(2),yLimitsOut(2))];
W = round(xWorldLimits(2)-xWorldLimits(1));
H = round(yWorldLimits(2)-yWorldLimits(1));
outputView = imref2d([H,W],xWorldLimits,yWorldLimits);
% warp image
outImg = imwarp(inImg,tform,'OutputView',outputView);
end
The following script was then used to generate the mex/C code executable library file:
%% opencv VS matlab origin code VS generate mex/C performance
%% generate mex file
inImg = im2single(imread("peppers.png"));
codegen -config:mex myEntry -args {inImg}
%% test speed
num = 1000;
t1 = tic;
for i = 1:num
outImg1 = myEntry(inImg);
end
t = toc(t1);
t2 = tic;
for i = 1:num
outImg2 = myEntry_mex(inImg);
end
tt = toc(t2);
fprintf("origin matlab code take time:%.5f seconds,generate C/mex code take time:%.5f seconds\n",t,tt);
figure;imshowpair(outImg1,outImg2,'montage')
Code generation successful.
origin matlab code take time:5.53857 seconds,generate C/mex code take time:5.46453 seconds
These two take about the same amount of time and it looks like imwarp uses a pre-compiled library, even though it generates C code, there is no significant speed advantage!
For the same functionality, I implemented it again using OpenCV C++ as follows:
cv::Mat img = cv::imread("peppers.png");
cv::Mat dst;
size_t nums = 1000;
double t1 = cv::getTickCount();
for (size_t i = 0; i < nums; i++) {
cv::Mat transMat = (cv::Mat_<float>(2, 3) << 0.8660, -0.5000, 100.0000,
0.5000, 0.8660, 200.0000);
// 计算包含目标图像的最大范围
std::vector<cv::Point2f> srcCorners = {cv::Point2f(0, 0), cv::Point2f(img.cols, 0), cv::Point2f(img.cols, img.rows), cv::Point2f(0, img.rows)};
std::vector<cv::Point2f> dstCorners;
cv::transform(srcCorners, dstCorners, transMat); // 对应matlab的transpointsforward
dstCorners.insert(dstCorners.end(), srcCorners.begin(), srcCorners.end());
cv::Rect outputView = cv::boundingRect(dstCorners);
// 平移到可视化区域
transMat.colRange(2, 3) = transMat.colRange(2, 3) - (cv::Mat_<float>(2, 1) << outputView.x, outputView.y);
cv::warpAffine(img, dst, transMat, cv::Size(outputView.width, outputView.height));
}
double t2 = cv::getTickCount();
std::printf("it take time:%.5f seconds. dst image size:(%d*%d)\n", (t2 - t1) * 1.0 / cv::getTickFrequency(), dst.rows, dst.cols);
it take time:0.79880 seconds. dst image size:(789*636)
As you can see above, the performance difference between imwarp's built-in functions is about 6.89 times, so it seems that performance is indeed an issue.
RUN in R2022b, windows 10
採用された回答
その他の回答 (0 件)
カテゴリ
ヘルプ センター および File Exchange で Code Generation, GPU, and Third-Party Support についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!