Julia 中的 vcat StackOverflowError [英] vcat StackOverflowError in julia
问题描述
我编写了一个函数来检测数组中的对象.在这种情况下,我用它来清除接触图像边界的白色物体.但问题是,vcat 中总是存在 StackOverFlowError 并且它发生在不同的行(取决于图像).这是一个最小的工作示例.它适用于第二张图像,但不适用于第一张:
I have written a function to detect objects in arrays. In this case I use it to clear white objects, which touch the border of an image. But the problem is, that there is always a StackOverFlowError in vcat and it occurs at different lines (depends on image). Here is a minimum working example. It works fine with the second image, but not with the first:
using Images
function getImChars(I::Array)
charAr=copy(I);
indexMax=find(x->(x==1),charAr);
(h,w)=size(charAr);
# check border values
(r,c)=ind2sub(size(charAr),indexMax);
indexBorderR1=find(x->(x==1),r);
indexBorderR2=find(x->(x==h),r);
indexBorderR=[indexBorderR1;indexBorderR2];
indexBorderC1=find(x->(x==1),c);
indexBorderC2=find(x->(x==w),c);
indexBorderC=[indexBorderC1;indexBorderC2];
borderPixels=[999;999]; # initialize def value FIX
for bRc=1:length(indexBorderR)
borderPixels=[borderPixels [r[indexBorderR[bRc]];c[indexBorderR[bRc]]]];
end
for bCc=1:length(indexBorderC)
borderPixels=[borderPixels [r[indexBorderC[bCc]];c[indexBorderC[bCc]]]];
end
borderPixels=borderPixels[:,2:end];
(rbP,cbP)=size(borderPixels);
fcharAr=[];
for k=1:cbP
bP=[borderPixels[:,k];false;false;false;false];
locObj1=[];
locObj2=[];
locObj3=[];
locObj4=[];
locObj5=[];
locObj6=[];
if(charAr[bP[1],bP[2]]==0)
continue;
else
charAr[bP[1],bP[2]]=0;
end
recGetCharClearBorders(true,false,h,w,bP,locObj1,locObj2,locObj3,locObj4,locObj5,locObj6,charAr);
end
return charAr;
end
function recGetCharClearBorders(firstFlag::Bool,doNotAdd::Bool,h::Int,w::Int,hP::Array,locObj1::Array,locObj2::Array,locObj3::Array,locObj4::Array,locObj5::Array,locObj6::Array,imAr::Array)
leftPoint=[hP[1];hP[2]-1;0;0;0;0];
rightPoint=[hP[1];hP[2]+1;0;0;0;0];
topPoint=[hP[1]-1;hP[2];0;0;0;0];
bottomPoint=[hP[1]+1;hP[2];0;0;0;0];
# check if it is not out of bounds and relative directions
if(topPoint[1]!=0)
if(imAr[topPoint[1],topPoint[2]]==1)
hP[4]=1;
end
end
if(bottomPoint[1]!=(h+1))
if(imAr[bottomPoint[1],bottomPoint[2]]==1)
hP[6]=1;
end
end
if(leftPoint[2]!=0)
if(imAr[leftPoint[1],leftPoint[2]]==1)
hP[3]=1;
end
end
if(rightPoint[2]!=(w+1))
if(imAr[rightPoint[1],rightPoint[2]]==1)
hP[5]=1;
end
end
# add first elements
if(firstFlag)
locObj1=collect(hP[1]);
locObj2=collect(hP[2]);
locObj3=collect(hP[3]);
locObj4=collect(hP[4]);
locObj5=collect(hP[5]);
locObj6=collect(hP[6]);
firstFlag=false;
else
# if first element of locObj was deleted actual point should not get pushed to array
if(!doNotAdd)
push!(locObj1,hP[1]);
push!(locObj2,hP[2]);
push!(locObj3,hP[3]);
push!(locObj4,hP[4]);
push!(locObj5,hP[5]);
push!(locObj6,hP[6]);
imAr[hP[1],hP[2]]=0;
end
end
goL=false;
goT=false;
goR=false;
goB=false;
doNotAdd=false;
if(length(locObj1)!=0)
# always take and check first elements of locObj
hPfInLoc=[locObj1[1],locObj2[1],locObj3[1],locObj4[1],locObj5[1],locObj6[1]];
hPl=[hPfInLoc[1];hPfInLoc[2]-1;0;0;0;0];
hPt=[hPfInLoc[1]-1;hPfInLoc[2];0;0;0;0];
hPr=[hPfInLoc[1];hPfInLoc[2]+1;0;0;0;0];
hPb=[hPfInLoc[1]+1;hPfInLoc[2];0;0;0;0];
compL=false;
compT=false;
compR=false;
compB=false;
# check bounds and if array values have changed
if(hPt[1]!=0)
if(imAr[hPt[1],hPt[2]]!=0)
compT=true;
end
end
if(hPb[1]!=(h+1))
if(imAr[hPb[1],hPb[2]]!=0)
compB=true;
end
end
if(hPl[2]!=0)
if(imAr[hPl[1],hPl[2]]!=0)
compL=true;
end
end
if(hPr[2]!=(w+1))
if(imAr[hPr[1],hPr[2]]!=0)
compR=true;
end
end
# define directions and set defined direction false in locObj
if((locObj3[1]==1)& compL)
locObj3[1]=0;
goL=true;
elseif((locObj4[1]==1)& compT)
locObj4[1]=0;
goT=true;
elseif((locObj5[1]==1)& compR)
locObj5[1]=0;
goR=true;
elseif((locObj6[1]==1)& compB)
locObj6[1]=0;
goB=true;
else
if (length(locObj1)==1)
locObj=[];
else # if everything is zero delete first rows of arrays
deleteat!(locObj1,1);
deleteat!(locObj2,1);
deleteat!(locObj3,1);
deleteat!(locObj4,1);
deleteat!(locObj5,1);
deleteat!(locObj6,1);
doNotAdd=true;
return recGetCharClearBorders(firstFlag,doNotAdd,h,w,hP,locObj1,locObj2,locObj3,locObj4,locObj5,locObj6,imAr);
end
end
end
#execute choosen direction
if(goL)
return recGetCharClearBorders(firstFlag,doNotAdd,h,w,hPl,locObj1,locObj2,locObj3,locObj4,locObj5,locObj6,imAr);
end
if(goT)
return recGetCharClearBorders(firstFlag,doNotAdd,h,w,hPt,locObj1,locObj2,locObj3,locObj4,locObj5,locObj6,imAr);
end
if(goR)
return recGetCharClearBorders(firstFlag,doNotAdd,h,w,hPr,locObj1,locObj2,locObj3,locObj4,locObj5,locObj6,imAr);
end
if(goB)
return recGetCharClearBorders(firstFlag,doNotAdd,h,w,hPb,locObj1,locObj2,locObj3,locObj4,locObj5,locObj6,imAr);
end
end
# execute test procedure
Im=Images.load("Test.png");
Im=data(Im);
imAr=map(Float64,Im);
resIm=getImChars(imAr);
save("Imout.png",resIm);
您只需在我的代码中更改图像的名称.告诉我,如果您需要更多信息.非常感谢.
You only have to change the name of the image in my code. Just tell me, if you need some more information. Thanks a lot.
干杯,克拉克斯
推荐答案
运行和修复尾递归需要几分钟.recGetCharClearBorders
的以下替换是否正确执行:
Took a few minutes needed to run and fixup the tail recursion. Is the following replacement for recGetCharClearBorders
performing correctly:
function recGetCharClearBorders(firstFlag::Bool,doNotAdd::Bool,h::Int,w::Int,hP::Array,locObj1::Array,locObj2::Array,locObj3::Array,locObj4::Array,locObj5::Array,locObj6::Array,imAr::Array,recdepth,recloc)
while true
leftPoint=[hP[1];hP[2]-1;0;0;0;0];
rightPoint=[hP[1];hP[2]+1;0;0;0;0];
topPoint=[hP[1]-1;hP[2];0;0;0;0];
bottomPoint=[hP[1]+1;hP[2];0;0;0;0];
# check if it is not out of bounds and relative directions
if(topPoint[1]!=0)
if(imAr[topPoint[1],topPoint[2]]==1)
hP[4]=1;
end
end
if(bottomPoint[1]!=(h+1))
if(imAr[bottomPoint[1],bottomPoint[2]]==1)
hP[6]=1;
end
end
if(leftPoint[2]!=0)
if(imAr[leftPoint[1],leftPoint[2]]==1)
hP[3]=1;
end
end
if(rightPoint[2]!=(w+1))
if(imAr[rightPoint[1],rightPoint[2]]==1)
hP[5]=1;
end
end
# add first elements
if(firstFlag)
locObj1=collect(hP[1]);
locObj2=collect(hP[2]);
locObj3=collect(hP[3]);
locObj4=collect(hP[4]);
locObj5=collect(hP[5]);
locObj6=collect(hP[6]);
firstFlag=false;
else
# if first element of locObj was deleted actual point should not get pushed to array
if(!doNotAdd)
push!(locObj1,hP[1]);
push!(locObj2,hP[2]);
push!(locObj3,hP[3]);
push!(locObj4,hP[4]);
push!(locObj5,hP[5]);
push!(locObj6,hP[6]);
imAr[hP[1],hP[2]]=0;
end
end
goL=false;
goT=false;
goR=false;
goB=false;
doNotAdd=false;
if(length(locObj1)!=0)
# always take and check first elements of locObj
hPfInLoc=[locObj1[1],locObj2[1],locObj3[1],locObj4[1],locObj5[1],locObj6[1]];
hPl=[hPfInLoc[1];hPfInLoc[2]-1;0;0;0;0];
hPt=[hPfInLoc[1]-1;hPfInLoc[2];0;0;0;0];
hPr=[hPfInLoc[1];hPfInLoc[2]+1;0;0;0;0];
hPb=[hPfInLoc[1]+1;hPfInLoc[2];0;0;0;0];
compL=false;
compT=false;
compR=false;
compB=false;
# check bounds and if array values have changed
if(hPt[1]!=0)
if(imAr[hPt[1],hPt[2]]!=0)
compT=true;
end
end
if(hPb[1]!=(h+1))
if(imAr[hPb[1],hPb[2]]!=0)
compB=true;
end
end
if(hPl[2]!=0)
if(imAr[hPl[1],hPl[2]]!=0)
compL=true;
end
end
if(hPr[2]!=(w+1))
if(imAr[hPr[1],hPr[2]]!=0)
compR=true;
end
end
# define directions and set defined direction false in locObj
if((locObj3[1]==1)& compL)
locObj3[1]=0;
goL=true;
elseif((locObj4[1]==1)& compT)
locObj4[1]=0;
goT=true;
elseif((locObj5[1]==1)& compR)
locObj5[1]=0;
goR=true;
elseif((locObj6[1]==1)& compB)
locObj6[1]=0;
goB=true;
else
if (length(locObj1)==1)
locObj=[];
else # if everything is zero delete first rows of arrays
deleteat!(locObj1,1);
deleteat!(locObj2,1);
deleteat!(locObj3,1);
deleteat!(locObj4,1);
deleteat!(locObj5,1);
deleteat!(locObj6,1);
doNotAdd=true;
continue
end
end
end
#execute choosen direction
if(goL)
hP = hPl
continue
end
if(goT)
hP = hPt
continue
end
if(goR)
hP = hPr
continue
end
if(goB)
hP = hPb
continue
end
break
end
end
不知何故,输出图像在我的运行中转向了它.
Somehow the output image turned on its side in my run.
这篇关于Julia 中的 vcat StackOverflowError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!