在我們學習了膨脹腐蝕和基於膨脹腐蝕的變化之後,我比較喜歡的一個是擊中擊不中,因爲喜歡所以就要單獨列出來,心裏總是覺得他可以有很多的用處,以後模版匹配,特徵檢測都會用,更深入的是,他會加深對膨脹腐蝕的理解,是一個很好的例子。
下面先看一個算法步驟和原理:
Hit-miss算法步驟:
擊中擊不中變換是形態學中用來檢測特定形狀所處位置的一個基本工具。它的原理就是使用腐蝕;如果要在一幅圖像A上找到B形狀的目標,我們要做的是:
- 首先,建立一個比B大的模板W;使用此模板對圖像A進行腐蝕,得到圖像假設爲Process1;
- 其次,用B減去W,從而得到V模板(W-B);使用V模板對圖像A的補集進行腐蝕,得到圖像假設爲Process2;
- 然後,Process1與Process2取交集;得到的結果就是B的位置。這裏的位置可能不是B的中心位置,要視W-B時對齊的位置而異;
其實很簡單,兩次腐蝕,然後交集,結果就出來了。
Hit-miss原理:
基於腐蝕運算的一個特性:腐蝕的過程相當於對可以填入結構元素的位置作標記的過程。
腐蝕中,雖然標記點取決於原點在結構元素中的相對位置,但輸出圖像的形狀與此無關,改變原點的位置,只會導致輸出結果發生平移。
既然腐蝕的過程相當於對可以填入結構元素的位置作標記的過程,可以利用腐蝕來確定目標的位置。
進行目標檢測,既要檢測到目標的內部,也要檢測到外部,即在一次運算中可以同時捕獲內外標記。
由於以上兩點,採用兩個結構基元H、M,作爲一個結構元素對B=(H,M),一個探測目標內部,一個探測目標外部。當且僅當H平移到某一點可填入X的內部,M平移到該點可填入X的外部時,該點纔在擊中擊不中變換的輸出中。
opencv應用
<span style="font-size:18px;">Mat src;
src=imread("2312.png",0);
Mat input_image = src;
Mat Kernel_S1 = imread("2311.png");
cvtColor(Kernel_S1, Kernel_S1, CV_RGB2GRAY);
int threhold = 180;
threshold(input_image, input_image, threhold, 255, CV_THRESH_BINARY);
threshold(Kernel_S1, Kernel_S1, threhold, 255, CV_THRESH_BINARY);
imshow("二值化圖像", input_image);
Mat BigBlankimage = Mat::ones(input_image.size(), input_image.type());
input_image = BigBlankimage*255-input_image;
imshow("反置圖像", input_image);
Mat Blankimage = Mat::ones(Kernel_S1.rows, Kernel_S1.cols, CV_8UC1);
Mat Kernel_S2 = Blankimage * 255 - Kernel_S1;
imshow("核1", Kernel_S1);
imshow("核2", Kernel_S2);
Mat hit_result, hit_result1, hit_result2;
erode(input_image, hit_result1, Kernel_S1, Point(-1,-1), 1, BORDER_DEFAULT, 0);
imshow("hit_result1", hit_result1);
erode(input_image, hit_result2, Kernel_S2, Point(-1,-1), 1, BORDER_DEFAULT, 0);
imshow("hit_result2", hit_result2);
hit_result = hit_result1 & hit_result2;
imshow("擊中擊不中", hit_result); </span>
matlab應用之函數使用與自定義實現
只要定義好s1 s2 調用bwhitmiss
<span style="font-size:18px;">Ihm = bwhitmiss(I, S1, S2);
% I爲輸入圖像
% S1、S2爲結構元素 </span>
根據岡薩雷斯的書的說明,如下圖,然後用matlab編寫代碼,最後得到圖像
clear all;
I = zeros(120,180);
I(11:80,16:75) = 1;
I(56:105,86:135) = 1;
I(26:55,141:170) = 1;
figure,imshow(I);
se = zeros(58,58);
se(5:54,5:54) = 1;
figure,imshow(se);
%擊中擊不中變換
Ie1 = imerode(I,se);
figure,imshow(Ie1);
Ic = 1 - I;
figure,imshow(Ic);
S2 = 1 - se;
figure;imshow(S2);
Ie2 = imerode(Ic,S2);
figure,imshow(Ie2);
Ihm = Ie1 & Ie2;
figure,imshow(Ihm);
這裏我們看一下結果
圖像識別算法交流 QQ羣:145076161,歡迎圖像識別與圖像算法,共同學習與交流