矩陣的掩碼操作

2021-10-02 03:58:33 字數 2627 閱讀 2820

矩陣的掩碼操作很簡單。其思想是:根據掩碼矩陣(也稱作核)重新計算影象中每個畫素的值。掩碼矩陣中的值表示近鄰畫素值(包括該畫素自身的值)對新畫素值有多大影響。從數學觀點看,我們用自己設定的權值,對畫素鄰域內的值做了個加權平均。

思考一下影象對比度增強的問題。我們可以對影象的每個畫素應用下面的公式:

上面那種表達法是公式的形式,而下面那種是以掩碼矩陣表示的緊湊形式。使用掩碼矩陣的時候,我們先把矩陣中心的元素(上面的例子中是(0,0)位置的元素,也就是5)對齊到要計算的目標畫素上,再把鄰域畫素值和相應的矩陣元素值的乘積加起來。雖然這兩種形式是完全等價的,但在大矩陣情況下,下面的形式看起來會清楚得多。

現在,我們來看看實現掩碼操作的兩種方法。一種方法是用基本的畫素訪問方法,另一種方法是用 filter2d 函式。

下面是實現了上述功能的函式:

void

sharpen

(const mat& myimage,mat& result)

} result.

row(0)

.setto

(scalar(0

)); result.

row(result.rows-1)

.setto

(scalar(0

)); result.

col(0)

.setto

(scalar(0

)); result.

col(result.cols-1)

.setto

(scalar(0

));}

剛進入函式的時候,我們要確保輸入影象是無符號字元型別的。為了做到這點,我們使用了 cv_assert 函式。若該函式括號內的表示式為false,則會丟擲乙個錯誤。

cv_assert

(myimage.

depth()

== cv_8u)

;// 僅接受uchar影象

然後,我們建立了乙個與輸入有著相同大小和型別的輸出影象。在 影象矩陣是如何儲存在記憶體之中的? 一節可以看到,根據影象的通道數,我們有乙個或多個子列。我們用指標在每乙個通道上迭代,因此通道數就決定了需計算的元素總數。

result.

create

(myimage.

size()

,myimage.

type()

);const

int nchannels = myimage.

channels()

;

利用c語言的操作符,我們能簡單明瞭地訪問畫素。因為要同時訪問多行畫素,所以我們獲取了其中每一行畫素的指標(分別是前一行、當前行和下一行)。此外,我們還需要乙個指向計算結果儲存位置的指標。有了這些指標後,我們使用操作符,就能輕鬆訪問到目標元素。為了讓輸出指標向前移動,我們在每一次操作之後對輸出指標進行了遞增(移動乙個位元組):

for

(int j =

1; j < myimage.rows-1;

++j)

}

在影象的邊界上,上面給出的公式會訪問不存在的畫素位置(比如(0,-1))。因此我們的公式對邊界點來說是未定義的。一種簡單的解決方法,是不對這些邊界點使用掩碼,而直接把它們設為0:

result.

row(0)

.setto

(scalar(0

));// 上邊界

result.

row(result.rows-1)

.setto

(scalar(0

));// 下邊界

result.

col(0)

.setto

(scalar(0

));// 左邊界

result.

col(result.cols-1)

.setto

(scalar(0

));// 右邊界

濾波器在影象處理中的應用太廣泛了,因此opencv也有個用到了濾波器掩碼(某些場合也稱作核)的函式。不過想使用這個函式,你必須先定義乙個表示掩碼的 mat 物件:

mat kern =

(mat_<

char

>(3

,3)<<0,

-1,0

,-1,

5,-1

,0,-

1,0)

;

然後呼叫 filter2d 函式,引數包括輸入、輸出影象以及用到的核:

filter2d

(i, k, i.

depth()

, kern )

;

它還帶有第五個可選引數——指定核的中心,和第六個可選引數——指定函式在未定義區域(邊界)的行為。使用該函式有一些優點,如**更加清晰簡潔、通常比 自己實現的方法 速度更快(因為有一些專門針對它實現的優化技術)等等。例如,我測試的濾波器方法僅花了13毫秒,而前面那樣自己實現迭代方法花了約31毫秒,二者有著不小差距。

OpenCv矩陣掩碼操作

定義 矩陣的掩碼操作就是重新計算影象中的每個畫素值。應用 常用於影象平滑,邊緣檢測,特徵分析等區域。方法 第一種使用公式,第二種使用filter2d 函式 include include includeusing namespace cv using namespace std int main n...

OpenCV學習筆記 矩陣的掩碼操作

矩陣的掩碼操作很簡單。其思想是 根據掩碼矩陣 也稱作核 重新計算影象中每個畫素的值。掩碼矩陣中的值表示近鄰畫素值 包括該畫素自身的值 對新畫素值有多大影響。從數學觀點看,我們用自己設定的權值,對畫素鄰域內的值做了個加權平均。思考一下影象對比度增強的問題。我們可以對影象的每個畫素應用下面的公式 上面那...

opencv學習(二) 矩陣的掩碼操作

矩陣的掩碼操作 根據掩碼矩陣 也稱作核 重新計算影象中每個畫素的值。掩碼矩陣中的值表示近鄰畫素值 包括該畫素自身的值 對新畫素值有多大影響。從數學觀點看,我們用自己設定的權值,對畫素鄰域內的值做了個加權平均。對影象的每個畫素應用下面的公式 即 每個畫素 該畫素 5 相鄰上下左右的畫素的和 原始演算法...