[blog 项目实战派]opencv通过dll调用matlab函数,图片作为参数
前文介绍了如何“
csharp通过dll调用opencv函数,图片作为参数
”。而在实际的代码编写过程中,很多时候想把已经写好的matlab函数融合进去,但是依然是将图片作为参数传递比较成为问题。这里我经过一段时间的研究解决了这个问题(目前只解决了灰度图片下的图片传递问题)。这个问题包含几个难点,一个是mxmatrix的使用,一个是matlab和opencv对于图片的格式处理是不一样的。
本次这个项目,是opencv通过调用matlab里面实现的Frangi函数,对图像进行Frangi滤波处理,并且最后在opencv中显示出来。
首先是修改Frangi函数,也就是调整参数,用图片作为输入和输出,一定要保证修改后的程序是正确的
function [outIm]
= GOFrangi(I)
%读入图片
defaultoptions = struct( 'FrangiScaleRange', [ 1 15], 'FrangiScaleRatio', 2, 'FrangiBetaOne', 0. 5, 'FrangiBetaTwo', 15, 'verbose', true, 'BlackWhite', true);
options =defaultoptions;
% Process inputs
if( ~exist( 'options', 'var')),
options =defaultoptions;
else
tags = fieldnames(defaultoptions);
for i = 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', 'unknown options found');
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;
% Make matrices to store all filterd images
ALLfiltered =zeros([size(I) length(sigmas)]);
ALLangles =zeros([size(I) length(sigmas)]);
% Frangi filter for all sigmas
for i = 1 :length(sigmas),
% Show progress
% if(options.verbose)
% disp([ 'Current Frangi Filter Sigma: ' num2str(sigmas(i)) ]);
%end
% Make 2D hessian
[Dxx,Dxy,Dyy] = Hessian2D(I,sigmas(i));
% Correct for scale
Dxx = (sigmas(i) ^ 2) *Dxx;
Dxy = (sigmas(i) ^ 2) *Dxy;
Dyy = (sigmas(i) ^ 2) *Dyy;
% Calculate (abs sorted) eigenvalues and vectors
[Lambda2,Lambda1,Ix,Iy] =eig2image(Dxx,Dxy,Dyy);
% Compute the direction of the minor eigenvector
angles = atan2(Ix,Iy);
% Compute some similarity measures
Lambda1(Lambda1 == 0) = eps;
Rb = (Lambda2. /Lambda1). ^ 2;
S2 = Lambda1. ^ 2 + Lambda2. ^ 2;
% Compute the output image
Ifiltered = exp( -Rb /beta) . *(ones(size(I)) -exp( -S2 /c));
% see pp. 45
if(options.BlackWhite)
Ifiltered(Lambda1 < 0) = 0;
else
Ifiltered(Lambda1 > 0) = 0;
end
% store the results in 3D matrices
ALLfiltered( :, :,i) = Ifiltered;
ALLangles( :, :,i) = angles;
end
% Return for every pixel the value of the scale(sigma) with the maximum
% output pixel value
if length(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
%读入图片
defaultoptions = struct( 'FrangiScaleRange', [ 1 15], 'FrangiScaleRatio', 2, 'FrangiBetaOne', 0. 5, 'FrangiBetaTwo', 15, 'verbose', true, 'BlackWhite', true);
options =defaultoptions;
% Process inputs
if( ~exist( 'options', 'var')),
options =defaultoptions;
else
tags = fieldnames(defaultoptions);
for i = 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', 'unknown options found');
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;
% Make matrices to store all filterd images
ALLfiltered =zeros([size(I) length(sigmas)]);
ALLangles =zeros([size(I) length(sigmas)]);
% Frangi filter for all sigmas
for i = 1 :length(sigmas),
% Show progress
% if(options.verbose)
% disp([ 'Current Frangi Filter Sigma: ' num2str(sigmas(i)) ]);
%end
% Make 2D hessian
[Dxx,Dxy,Dyy] = Hessian2D(I,sigmas(i));
% Correct for scale
Dxx = (sigmas(i) ^ 2) *Dxx;
Dxy = (sigmas(i) ^ 2) *Dxy;
Dyy = (sigmas(i) ^ 2) *Dyy;
% Calculate (abs sorted) eigenvalues and vectors
[Lambda2,Lambda1,Ix,Iy] =eig2image(Dxx,Dxy,Dyy);
% Compute the direction of the minor eigenvector
angles = atan2(Ix,Iy);
% Compute some similarity measures
Lambda1(Lambda1 == 0) = eps;
Rb = (Lambda2. /Lambda1). ^ 2;
S2 = Lambda1. ^ 2 + Lambda2. ^ 2;
% Compute the output image
Ifiltered = exp( -Rb /beta) . *(ones(size(I)) -exp( -S2 /c));
% see pp. 45
if(options.BlackWhite)
Ifiltered(Lambda1 < 0) = 0;
else
Ifiltered(Lambda1 > 0) = 0;
end
% store the results in 3D matrices
ALLfiltered( :, :,i) = Ifiltered;
ALLangles( :, :,i) = angles;
end
% Return for every pixel the value of the scale(sigma) with the maximum
% output pixel value
if length(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(
int argc, _TCHAR
* argv[])
{
Mat src = imread( "vessel.jpg", 0);
imshow( "src",src);
src.convertTo(src,CV_32F); //32f非常常见
//初始化函数,如果初始失败,刚提示并返回
if( !GOFrangiInitialize()) {
printf( "调用matlab失败!");
return 0;
}
else {
printf( "调用matlab成功!");
mxArray * pv;
mxArray * pout;
if ( !src.empty()) {
Mat dst(src.rows,src.cols,CV_32F);
Mat dst2(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);
//数据对齐,直接换算
int icols = dst.cols;
int irows = dst.rows;
for( int i = 0;i <dst.rows;i ++){
for( int j = 0;j <dst.cols;j ++){
int isum = icols *i +j;
int i2 = isum % irows;
int j2 = isum / irows;
dst2.at <uchar >(i2,j2) = dst.at <uchar >(i,j);
}
}
imwrite( "结果图片.jpg",dst2);
} else {
printf( "src 为空! \n");
return 0;
}
}
waitKey();
return 0;
}
{
Mat src = imread( "vessel.jpg", 0);
imshow( "src",src);
src.convertTo(src,CV_32F); //32f非常常见
//初始化函数,如果初始失败,刚提示并返回
if( !GOFrangiInitialize()) {
printf( "调用matlab失败!");
return 0;
}
else {
printf( "调用matlab成功!");
mxArray * pv;
mxArray * pout;
if ( !src.empty()) {
Mat dst(src.rows,src.cols,CV_32F);
Mat dst2(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);
//数据对齐,直接换算
int icols = dst.cols;
int irows = dst.rows;
for( int i = 0;i <dst.rows;i ++){
for( int j = 0;j <dst.cols;j ++){
int isum = icols *i +j;
int i2 = isum % irows;
int j2 = isum / irows;
dst2.at <uchar >(i2,j2) = dst.at <uchar >(i,j);
}
}
imwrite( "结果图片.jpg",dst2);
} else {
printf( "src 为空! \n");
return 0;
}
}
waitKey();
return 0;
}
生成结果
来自为知笔记(Wiz)