歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

在OpenCV中圖像邊界擴展 copyMakeBorder 的實現

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;
}

Copyright © Linux教程網 All Rights Reserved