加入收藏 | 设为首页 | 会员中心 | 我要投稿 开发网_开封站长网 (http://www.0378zz.com/)- 科技、AI行业应用、媒体智能、低代码、办公协同!
当前位置: 首页 > 教程 > 正文

在OpenCV中图像边界扩展 copyMakeBorder 的达成

发布时间:2021-11-22 10:00:51 所属栏目:教程 来源:互联网
导读:1. 边界处理的类型 2. opencv的实现 在图像处理中,经常需要空域或频域的滤波处理,在进入真正的处理程序中,需要考虑图像边界情况。 通常的处理方法是为图像增加一定的边缘,以适应 卷积核 在原图像边界的操作。 1. 增加边界的类型有以下4个类型: 以一行图
1. 边界处理的类型
 
2. opencv的实现
 
在图像处理中,经常需要空域或频域的滤波处理,在进入真正的处理程序中,需要考虑图像边界情况。
 
通常的处理方法是为图像增加一定的边缘,以适应 卷积核 在原图像边界的操作。
 
1. 增加边界的类型有以下4个类型:
 
以一行图像数据为例,abcdefgh是原图数据,|是图像边界,为原图加边
 
aaaaaa|abcdefgh|hhhhhhh    重复
 
fedcba|abcdefgh|hgfedcb    反射
 
gfedcb|abcdefgh|gfedcba  反射101,相当于上一行的左右互换
 
cdefgh|abcdefgh|abcdefg  外包装
 
iiiiii|abcdefgh|iiiiiii  with some specified 'i'  常量
 
2. opencv的实现
 
opencv中有几处增加边界的实现,其源码分别散布在Utils.cpp,Filter.cpp,Ts_func.cpp中,功能和实现都基本相同。
 
以Utils的copyMakeBorder,及Filter中的borderInterpolate为例,这两种的代码风格比较通俗易懂。
 
边界处理的步骤:
 
首先,为目的图像(结果图像)分配内存,图像大小为size(src.rows + top + bottom, src.cols + left + right)
 
然后,以原图为基准,逐行处理,先扩展左边界,复制原图数据到目的图像,再扩展右边界。
 
最后,扩展上边界,以及下边界。
 
 
 
其中,每扩展一个边界像素,都需要计算出对应的原图中的位置,这个功能被提炼出来,就是borderInterpolate
 
/*
 Various border types, image boundaries are denoted with '|'
 
 * BORDER_REPLICATE:    aaaaaa|abcdefgh|hhhhhhh
 * BORDER_REFLECT:      fedcba|abcdefgh|hgfedcb
 * BORDER_REFLECT_101:  gfedcb|abcdefgh|gfedcba
 * BORDER_WRAP:          cdefgh|abcdefgh|abcdefg       
 * BORDER_CONSTANT:      iiiiii|abcdefgh|iiiiiii  with some specified 'i'
 */
int cv::borderInterpolate( int p, int len, int borderType ) // p是扩展边界的位置,len是原图宽度
{
    if( (unsigned)p < (unsigned)len )    // 转换为无符号类型,左边界和上边界:p一般是负数,右边界和下边界,p一般是大于len的。
        ;
    else if( borderType == BORDER_REPLICATE ) // 重复类型,每次对应原图的位置是0或len-1
        p = p < 0 ? 0 : len - 1;
    else if( borderType == BORDER_REFLECT || borderType == BORDER_REFLECT_101 ) // 反射/映射
    {
        int delta = borderType == BORDER_REFLECT_101;
        if( len == 1 )
            return 0;
        do
        {
            if( p < 0 )    // 反射:左边界或101:右边界
                p = -p - 1 + delta;
            else
                p = len - 1 - (p - len) - delta;
        }
        while( (unsigned)p >= (unsigned)len );
    }
    else if( borderType == BORDER_WRAP )  // 包装
    {
        if( p < 0 )  // 左边界
            p -= ((p-len+1)/len)*len;
        if( p >= len )  // 右边界
            p %= len;
    }
    else if( borderType == BORDER_CONSTANT )  // 常量,另外处理
        p = -1;
    else
        CV_Error( CV_StsBadArg, "Unknown/unsupported border type" );
    return p;
}

(编辑:开发网_开封站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读