Cannot allocate this handle object. For code generation, a handle object allocated inside a loop cannot be referenced outside of the loop
9 views (last 30 days)
Show older comments
Here is my code snippet. Is there any workaround other than changing the handle object to a value class?
classdef ImageWrapper < handle%#codegen
%IMAGEWRAPPER 对img matrix的wrapper类,提供常用的接口函数,尽可能避免上层代码对img matrix直接的索引操作。
% 图像的宽高等常用信息也可以直接通过imgShape这个属性获取。
% 此处显示详细说明
properties
img (:,:) double % 管理的img matrix像素矩阵信息
flag_unset (:,:) double % 像素位置未设置标志位,初始化为全1
imgShape (1,1) ImgShape % 图像宽、高信息
end
methods
function this = ImageWrapper(img)
arguments
img (:,:) double = []
end
this.img = img;
this.flag_unset = ones(size(img));
this.imgShape = ImgShape(size(img,2),size(img,1));
end
function multiply_in_place(this,valueMatrix)
this.img(:) = this.img .* valueMatrix;
end
function this = setAtMatrixRange(this,matrixRange,valueMatrix)
%SETATMATRIXRANGE 将图像对应于matrixRange的region设为valueMatrix的值
arguments (Input)
this ImageWrapper
matrixRange MatrixIndexRange
valueMatrix (:,:) double
end
rowStart = matrixRange.rowStart;
rowEnd = matrixRange.rowEnd;
colStart = matrixRange.colStart;
colEnd = matrixRange.colEnd;
if ~isscalar(rowStart)
fprintf("rowStart is Non scalar \n");
end
if ~isscalar(rowEnd)
fprintf("rowEnd is Non scalar \n");
end
if ~isscalar(colStart)
fprintf("colStart is Non scalar \n");
end
if ~isscalar(colEnd)
fprintf("colEnd is Non scalar \n");
end
% fprintf("size of rowStart: \n");
% disp(size(rowStart));
% disp(class(rowStart));
% fprintf("size of rowEnd: \n");
% disp(size(rowEnd));
% disp(class(rowEnd));
% fprintf("size of colStart: \n");
% disp(size(colStart));
% disp(class(colStart));
% fprintf("size of colEnd: \n");
% disp(size(colEnd));
% disp(class(colEnd));
% fprintf("size of value matrix :\n");
% disp(size(valueMatrix));
% disp(class(valueMatrix));
this.img(rowStart(1):rowEnd(1),colStart(1):colEnd(1)) = valueMatrix;
this.flag_unset(rowStart(1):rowEnd(1),colStart(1):colEnd(1)) = 0;
end
function this = addAtMatrixRange(this,matrixRange,valueMatrix)
arguments (Input)
this ImageWrapper
matrixRange MatrixIndexRange
valueMatrix (:,:) double
end
rowStart = matrixRange.rowStart;
rowEnd = matrixRange.rowEnd;
colStart = matrixRange.colStart;
colEnd = matrixRange.colEnd;
this.img(rowStart:rowEnd,colStart:colEnd) = this.img(rowStart:rowEnd,colStart:colEnd) + valueMatrix;
this.flag_unset(rowStart:rowEnd,colStart:colEnd) = 0;
end
function instance = extractSubImage(this,matrixRange)
arguments (Input)
this ImageWrapper
matrixRange MatrixIndexRange
end
rowStart = matrixRange.rowStart;
rowEnd = matrixRange.rowEnd;
colStart = matrixRange.colStart;
colEnd = matrixRange.colEnd;
subImg = this.img(rowStart:rowEnd,colStart:colEnd);
instance = ImageWrapper(subImg);
end
function fillUnsetPlacesWithValue(this,fillingValue)
arguments (Input)
this ImageWrapper
fillingValue (1,1) double
end
this.img = this.img + this.flag_unset .* fillingValue;
end
function matrixRange = getFullMatrixRange(this)
matrixRange = MatrixIndexRange(rowStart=1,rowEnd=this.imgShape.m_height,colStart=1,colEnd=this.imgShape.m_width);
end
function sz = shape(this)
sz = [this.imgShape.m_height,this.imgShape.m_width];
end
end
methods (Static)
function instance = zeros(sz)
arguments (Input)
sz (1,2)
end
instance = ImageWrapper(zeros(sz));
end
function instance = ones(sz)
arguments (Input)
sz (1,2)
end
instance = ImageWrapper(ones(sz));
end
end
end
2 Comments
Raghu Boggavarapu
on 14 Jul 2023
Hi, This is a documented limitation for code generation: Handle Object Limitations for Code Generation - MATLAB & Simulink (mathworks.com) .
Accepted Answer
Manoj Mirge
on 8 Aug 2023
The MATLAB coder must statically allocate memory for handle class objects, and allocating in a loop prevents static memory allocation. That is why the handle class objects cannot be allocated in the “for” loop. As you are allocating the handle class object “ImageWrapper” in the “for” loop, you are encountering this error.
Please refer to the attached MATLAB Answer link for a workaround to store the handle classes in cell array:
Similarly, you can add the “setValue” method in the “ImageWrapper” handle class.
You can refer to below code for achieving the same:
classdef ImageWrapper < handle
properties
img (:,:) double
flag_unset (:,:) double
imgShape (1,1) ImgShape
end
methods
% Constructor method
%The setValue method that again set the properties of the object.
function this = setValue(this,img)
this.img = img;
this.flag_unset = ones(size(img));
this.imgShape = ImgShape(size(img,2),size(img,1));
end
% Other Mehods
end
end
And in “stitch_spine” function you can use the “repmat” function to allocate the handle class in cell array and then later change the class value using the “setValue” method.
Please refer to below code to achieve the same:
intactImgs_list = repmat({ImageWrapper(imgStack_double(:,:,1))}, 1, numIntactImgs-1);
for i=2:numIntactImgs
% Set the object as you would like.
setValue(Nodes{i}, imgStack_double(:,:,i) );
end
Hope this helps.
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!