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
[cpp]view plain
copy
/*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(
intp,
intlen,
intbordertype )
// p是擴充套件邊界的位置,len是原圖寬度
while
( (unsigned)p >= (unsigned)len );
} else
if( bordertype == border_wrap )
// 包裝
else
if( bordertype == border_constant )
// 常量,另外處理
p = -1;
else
cv_error( cv_stsbadarg, "unknown/unsupported border type"
);
return
p;
}
非常量型別邊界擴充套件:
[cpp]view plain
copy
static
void
copymakeborder_8u(
const
uchar* src,
size_t
srcstep, size srcroi,
// 原圖 引數:資料,step,大小
uchar* dst, size_t
dststep, size dstroi,
// 目的影象引數
inttop,
intleft,
intcn,
intbordertype )
autobuffer
> _tab((dstroi.width - srcroi.width)*cn);
// 大小是 擴充套件的左右邊界之和,僅用於存放 擴充套件的邊界 在原圖中的位置
int* tab = _tab;
intright = dstroi.width - srcroi.width - left;
intbottom = dstroi.height - srcroi.height - top;
for( i = 0; i
// 左邊界
for( i = 0; i
// 右邊界
srcroi.width *= cn;
dstroi.width *= cn;
left *= cn;
right *= cn;
uchar* dstinner = dst + dststep*top + left*elemsize;
for( i = 0; i
// 從原圖中複製資料到擴充套件的邊界中
else
} dstroi.width *= elemsize;
dst += dststep*top;
for( i = 0; i
// 上邊界
for( i = 0; i
// 先邊界
} 常量型別的擴充套件就更簡單了:
[cpp]view plain
copy
static
void
copymakeconstborder_8u(
const
uchar* src,
size_t
srcstep, size srcroi,
uchar* dst, size_t
dststep, size dstroi,
inttop,
intleft,
intcn,
const
uchar* value )
srcroi.width *= cn;
dstroi.width *= cn;
left *= cn;
right *= cn;
uchar* dstinner = dst + dststep*top + left;
for( i = 0; i
// 複製原圖資料和擴充套件左右邊界
dst += dststep*top;
for( i = 0; i
memcpy(dst + (i - top)*dststep, constbuf, dstroi.width); // 擴充套件上邊界
for( i = 0; i
// 擴充套件下邊界
memcpy(dst + (i + srcroi.height)*dststep, constbuf, dstroi.width);
}
對於medianblur( inputarray _src0, outputarray _dst, int ksize )的邊界擴充套件方式是 重複複製最邊緣畫素 border_replicate。
Opencv之邊界跟蹤
問題描述 一般是將二值化後的影象進行邊界的提取。需要說明的是這個提取不是簡單的找到邊界,而是按照順序的找出來。即邊界上的點是按照鄰接關係依次給出。相關演算法 1 這裡解釋 程式實現 還有canny演算法之類的一推 opencv的現有演算法 有兩個函式 findcontours和cvfindconto...
mediawiki邊界處理
在使用wiki中發現,內容頁面始終佔據瀏覽器100 寬度,乙個不好的表現就是 當需要編輯特殊欄位時,編輯 始終在瀏覽器最右方,不方便操作,而且,文章內容佔據寬度過長,不易於瀏覽。因此,改動方法有二。其一,在編輯新頁面時,人為的寫入 內容 之後在 內容 替換為自己想要輸入的內容即可,n 替換為需要的百...
卷積邊界處理 copyMakeBorder
進行卷積處理影像時,在影像的邊界,核心沒有足夠元素納入計算,opencv裡用copymakeborder 函式將原圖稍微放大,再開始進行卷積,opencv在空間濾波的相關函式內部已包含copymakeborder 了,所以實際上使用空間濾波時,不需要呼叫copymakeborder 在opencv裡...