[blog 项目实战派]opencv通过dll调用matlab函数,图片作为参数 前文介绍了如何“csharp通过dll调用opencv函数,图片作为参数”。而在实际的代码编写过程中,很多时候想把已经写好的matlab函数融合进去,但是依然是将图片作为参数传递比较成为问题。这里我经过一段时间的研究解决了这个问题(目前只解决了灰度图片下的图片传递问题)。这个问题包含几个难点,一个是mxmatrix的使用,一个是matlab和opencv对于图片的格式处理是不一样的。本次这个项目,是opencv通过调用matlab里面实现的Frangi函数,对图像进行Frangi滤波处理,并且最后在opencv中显示出来。首先是修改Frangi函数,也就是调整参数,用图片作为输入和输出,一定要保证修改后的程序是正确的 function[outIm]=GOFrangi(I)
%读入图片
defaultoptions=struct('FrangiScaleRange',[115],'FrangiScaleRatio',2,'FrangiBetaOne',0.5,'FrangiBetaTwo',15,'verbose',true,'BlackWhite',true);
options=defaultoptions;
%Processinputs
if(~exist('options','var')),
options=defaultoptions;
else
tags=fieldnames(defaultoptions);
fori=1:length(tags)
if(~isfield(options,tags{i})),options.(tags{i})=defaultoptions.(tags{i});end
end
if(length(tags)~=length(fieldnames(options))),
warning('FrangiFilter2D:unknownoption','unknownoptionsfound');
end
end
sigmas=options.FrangiScaleRange(1):options.FrangiScaleRatio:options.FrangiScaleRange(2);
sigmas=sort(sigmas,'ascend');
beta=2*options.FrangiBetaOne^2;
c=2*options.FrangiBetaTwo^2;
%Makematricestostoreallfilterdimages
ALLfiltered=zeros([size(I)length(sigmas)]);
ALLangles=zeros([size(I)length(sigmas)]);
%Frangifilterforallsigmas
fori=1:length(sigmas),
%Showprogress
%if(options.verbose)
%disp(['CurrentFrangiFilterSigma:'num2str(sigmas(i))]);
%end
%Make2Dhessian
[Dxx,Dxy,Dyy]=Hessian2D(I,sigmas(i));
%Correctforscale
Dxx=(sigmas(i)^2)*Dxx;
Dxy=(sigmas(i)^2)*Dxy;
Dyy=(sigmas(i)^2)*Dyy;
%Calculate(abssorted)eigenvaluesandvectors
[Lambda2,Lambda1,Ix,Iy]=eig2image(Dxx,Dxy,Dyy);
%Computethedirectionoftheminoreigenvector
angles=atan2(Ix,Iy);
%Computesomesimilaritymeasures
Lambda1(Lambda1==0)=eps;
Rb=(Lambda2./Lambda1).^2;
S2=Lambda1.^2+Lambda2.^2;
%Computetheoutputimage
Ifiltered=exp(-Rb/beta).*(ones(size(I))-exp(-S2/c));
%seepp.45
if(options.BlackWhite)
Ifiltered(Lambda1<0)=0;
else
Ifiltered(Lambda1>0)=0;
end
%storetheresultsin3Dmatrices
ALLfiltered(:,:,i)=Ifiltered;
ALLangles(:,:,i)=angles;
end
%Returnforeverypixelthevalueofthescale(sigma)withthemaximum
%outputpixelvalue
iflength(sigmas)>1,
[outIm,whatScale]=max(ALLfiltered,[],3);
outIm=reshape(outIm,size(I));
if(nargout>1)
whatScale=reshape(whatScale,size(I));
end
if(nargout>2)
Direction=reshape(ALLangles((1:numel(I))'+(whatScale(:)-1)*numel(I)),size(I));
end
else
outIm=reshape(ALLfiltered,size(I));
if(nargout>1)
whatScale=ones(size(I));
end
if(nargout>2)
Direction=reshape(ALLangles,size(I));
end
end
片对代码进行编译。要注意这里是 -W lib:GOFrangi 而不是 -W cpplib:GOFrange mcc -W lib:GOFrangi -T link:lib GOFrangi.m -C 拷贝这四个文件放到opencv目录下 系统相关设置 还有 还有int_tmain(intargc,_TCHAR*argv[])
{
Matsrc=imread("vessel.jpg",0);
imshow("src",src);
src.convertTo(src,CV_32F);//32f非常常见
//初始化函数,如果初始失败,刚提示并返回
if(!GOFrangiInitialize()){
printf("调用matlab失败!");
return0;
}
else{
printf("调用matlab成功!");
mxArray*pv;
mxArray*pout;
if(!src.empty()){
Matdst(src.rows,src.cols,CV_32F);
Matdst2(src.rows,src.cols,CV_32FC1);
src=src.t();
pv=mxCreateNumericMatrix(src.cols,src.rows,mxSINGLE_CLASS,mxREAL);
memcpy(mxGetPr(pv),src.data,mxGetNumberOfElements(pv)*sizeof(float));
pout=mxCreateNumericMatrix(dst.cols,dst.rows,mxSINGLE_CLASS,mxREAL);
mlfGOFrangi(1,&pout,pv);
memcpy(dst.data,mxGetPr(pout),mxGetNumberOfElements(pout)*sizeof(float));
dst.convertTo(dst,CV_8UC1);
//数据对齐,直接换算
inticols=dst.cols;
intirows=dst.rows;
for(inti=0;i<dst.rows;i++){
for(intj=0;j<dst.cols;j++){
intisum=icols*i+j;
inti2=isum%irows;
intj2=isum/irows;
dst2.at<uchar>(i2,j2)=dst.at<uchar>(i,j);
}
}
imwrite("结果图片.jpg",dst2);
}else{
printf("src为空!\n");
return0;
}
}
waitKey();
return0;
} 生成结果
来自为知笔记(Wiz)