opencv通过dll调用matlab函数,图片作为参数

[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
 
  片对代码进行编译。要注意这里是 -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;
}
生成结果





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值