cv::pyrMeanShiftFiltering 和 cuda::meanShiftSegmentation源码阅读笔记

最近学了cuda,准备找个项目来练练手。先分析了一把代码,发现主要性能瓶颈在cv::pyrMeanShiftFiltering,原本打算自己撸一个gpu版的,没想到一搜发现已经有人写好了cuda::meanShiftSegmentation。那就改变计划,读读源码吧。

mean shift

mean shift简单理解就是划一个圈圈,算出mean,然后往这个方向shift过去。

图片来自opencv官方文档
思路还是挺简单、直观。但是具体到应用的时候,就可以发挥各种脑洞去改造了。

meanshift
我之前用meanshift是用来聚类后自动划档,比如统计购买同一个商品的用户的注册时间,可以按新老用户划分出几个人群。因为每一个商品的用户分布都不一致,不能直接拍脑袋定一个固定值,聚成多少个簇也是不固定的。而meanshift就可以很方便解决划分多少个档位,怎么划分的问题。

那回到图像的问题,图片是rows*cols个像素,跟opencv举例子的那个图的情况好像不一样,图片怎么meanshift呢?图像有颜色空间(R,G,B)和位置空间(x,y)5维,我之前还以为是直接对颜色空间进行meanshift,其实不是的。
那先来看看cv::pyrMeanShiftFiltering是怎么处理的吧。

cv::pyrMeanShiftFiltering源码

pyr是指金字塔pyramids,那金字塔的meanshift又是怎么实现呢?

/****************************************************************************************\
*                                         Meanshift                                      *
\****************************************************************************************/

void cv::pyrMeanShiftFiltering( InputArray _src, OutputArray _dst,
                                double sp0, double sr, int max_level,
                                TermCriteria termcrit )
{
    CV_INSTRUMENT_REGION()

    Mat src0 = _src.getMat();

    if( src0.empty() )
        return;

    _dst.create( src0.size(), src0.type() );
    Mat dst0 = _dst.getMat();

    // cn=channel num?
    const int cn = 3;
    const int MAX_LEVELS = 8;

    if( (unsigned)max_level > (unsigned)MAX_LEVELS )
        CV_Error( CV_StsOutOfRange, "The number of pyramid levels is too large or negative" );

    std::vector<cv::Mat> src_pyramid(max_level+1);
    std::vector<cv::Mat> dst_pyramid(max_level+1);
    cv::Mat mask0;
    int i, j, level;
    //uchar* submask = 0;


    //(c0,c1,c2) 跟 (ofs0,ofs1,ofs2)的颜色欧式距离的平方。用平方就不用开根号了
    #define cdiff(ofs0) (tab[c0-dptr[ofs0]+255] + \
        tab[c1-dptr[(ofs0)+1]+255] + tab[c2-dptr[(ofs0)+2]+255] >= isr22)

    double sr2 = sr * sr;
    // i是指integer, isr2^2为啥最小要16?因为sr至少要2
    int isr2 = cvRound(sr2), isr22 = MAX(isr2,16);
    int tab[768];


    if( src0.type() != CV_8UC3 )
        CV_Error( CV_StsUnsupportedFormat, "Only 8-bit, 3-channel images are supported" );

    if( src0.type() != dst0.type() )
        CV_Error( CV_StsUnmatchedFormats, "The input and output images must have the same type" );

    if( src0.size() != dst0.size() )
        CV_Error( CV_StsUnmatchedSizes, "The input 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值