亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Matlab處理圖像后實現(xiàn)簡單的人臉檢測

 更新時間:2021年11月17日 16:17:18   作者:Kakaluotuo  
本文主要介紹一下如何使用matlab進行圖像處理后實現(xiàn)人臉檢測,感興趣的可以了解一下

1.人臉檢測原理框圖

整體思路是尋找圖片中最大的連通域,將其認定為人臉。

第一個環(huán)節(jié)均值濾波,是為了減弱圖像的相關細節(jié)部分,以免毛刺影響后期連通域的形成,二值化方便形態(tài)學處理,減少運算量??紤]到人臉有黑人和白人黃種人,黑人膚色較深,在二值化之后面部區(qū)域不容易形成較大的連通域,如果采取形態(tài)學邊界提取的辦法,就可以避免這個問題,形態(tài)學邊界提取,只要結(jié)構元素夠大,也可以形成較大的封閉連通域。

然后就是縱向閉合操作,這一步我選擇采用豎向長條狀的結(jié)構元素進行閉合運算,因為人的臉部和頸部以及頭發(fā)和衣物等等都是縱向分布的,在進行形態(tài)學邊界提取的時候,容易將這些靠近的成分割裂開來,這對連通域的判斷極為不利,所以用豎向長條狀的結(jié)構元素在在縱向進行閉合運算,將臉部上下部的區(qū)域重新連接起來。

緊接著我又用橫向長條狀結(jié)構元素進行橫向腐蝕運算,這是因為,人的頭部以下的身體部分存在有大量連通域的時候,容易對最大連通域的判決產(chǎn)生干擾,又因為下半部分,多半呈縱向分布,通過橫向腐蝕可以將這些大塊的連通域割裂開來,但是要注意的是,割裂程度不應太大,否則會使得上一步閉合操作喪失意義。

接著,由于背景雜物等因素,同樣也會產(chǎn)生大量連通域,這會對最后結(jié)果的判決產(chǎn)生干擾,因此要予以剔除。

進行了層層篩選之后,在剩下的連通域里面挑一個最大的連通域,并且尺寸形狀滿足要求的用矩形框框起來作為人臉檢測結(jié)果。

2 步驟

2.1 均值濾波

h = ones(9)/81;
I = uint8(conv2(I,h));
figure,imshow(I),title('線性均值濾波')

采用9x9模板進行線性均值濾波,因為后面調(diào)用gpuArray()函數(shù)轉(zhuǎn)換對輸入數(shù)據(jù)有要求,所以在進行了二維卷積之后重新將數(shù)據(jù)格式轉(zhuǎn)換成8位無符號整形數(shù)據(jù)。

2.2 二值化

BW = imbinarize(I);
figure,imshow(BW),title('二值化')

直接調(diào)用imbinarize對圖像進行二值化

2.3.形態(tài)學邊界提取

B = ones(21);%結(jié)構元素
BW = -imerode(BW,B) + BW;
figure,imshow(BW),title('形態(tài)學邊界提取')
BW = bwmorph(BW,'thicken');
figure,imshow(BW),title('加粗邊界')
BW = not(bwareaopen(not(BW), 300));
figure,imshow(BW),title('把空洞填了')

結(jié)構元素采用21x21大小的全1矩陣,先調(diào)用imrode()進行腐蝕,再用原圖減去腐蝕結(jié)果,得到邊界。為了讓邊界更加明顯,調(diào)用bmworph函數(shù),傳入'thicken'參數(shù),意在將邊界加粗加厚。最后為了把空洞就是連續(xù)的小黑色塊填滿,調(diào)用bwareaopen()函數(shù),該函數(shù)是去除面積小于300的白塊,為了去除黑塊,先調(diào)用not(BW)給原來的二值圖像取反,去掉取反后面積小于300的白塊,再次取反,達到去掉面積小于300的黑塊的目的。

 2.4 縱向閉合與橫向腐蝕

%進行形態(tài)學運算
B = strel('line',50,90);
BW = imdilate(BW,B);
BW = imerode(BW,B);
figure,imshow(BW),title('再閉操作之后')
B = strel('line',10,0);
BW = imerode(BW,B);
figure,imshow(BW),title('閉操作之后再腐蝕')
BW = gpuArray(BW);

調(diào)用strel()函數(shù)生成特定的結(jié)構元素,第一步調(diào)用strel(‘line',50,90),意思是調(diào)用直線型結(jié)構元素,長度為50,角度90度,也就是豎直的長條形結(jié)構元素。接著利用B調(diào)用imdilate和imerode,先進行膨脹再進行腐蝕完成閉操作運算。下一步,繼續(xù)生成橫向長條形結(jié)構元素,進行腐蝕操作,注意這里的結(jié)構元素不宜面積太大,長度太長,否則會過度影響上一步的結(jié)果

最后為了循環(huán)過程中提升運算速度,將數(shù)據(jù)類型更改為gpuArray(),可以在GPU上進行計算,節(jié)省時間。

2.5 消除邊界多余連通域

%最小化背景
%細分
div = 10;
r = floor(n1/div);%分成10塊 行
c = floor(n2/div);%分成10塊 列
x1 = 1;x2 = r;%對應行初始化
s = r*c;%塊面積
%判斷人臉是否處于圖片四周,如果不是就全部弄黑
%figure
for i=1:div
    y1 = 1;y2 = c;%對應列初始化
    for j=1:div
        loc = find(BW(x1:x2,y1:y2)==0);%統(tǒng)計這一塊黑色像素的位置
        num = length(loc);
        rate = num*100/s;%統(tǒng)計黑色像素占比
        if (y2<=0.2*div*c||y2>=0.8*div*c)||(x1<=r||x2>=r*div)
            if rate <=100
                BW(x1:x2,y1:y2) = 0;
            end
            %imshow(BW)
        else
            if rate <=25
                BW(x1:x2,y1:y2) = 1;
            end
            %imshow(BW)
        end%下一列
        y1 = y1 + c;
        y2 = y2 + c;
    end%下一行
    x1 = x1 + r;
    x2 = x2 + r;
end

對于周圍多余的雜物產(chǎn)生的連通域,我選擇先將整幅圖像劃分為很多小塊,對一部分在圖像邊緣的小塊全部置成黑色,對不在邊緣的通過計算其中黑色像素比例來判定是否應該全部給成白色。因為圖片中央可能還會存在一些細小空洞,這些空洞在每一小塊占比不是很大但有可能影響連通性,如果一個小塊里面大部分是白色就全部給成白色,方便后期判定最大連通域。

Div是均分比例,我這里設置成10,也就是將整個圖像劃分成100個小塊。r就是在行方向上一個小塊占多少像素,c就是在列方向上一個小塊有多少像素。用兩層循環(huán)來遍歷每個小塊,通過find(x1:x2,y1:y2)==0返回所有滿足要求的像素的索引,索引長度就是黑色像素的個數(shù)。

通過條件判斷是否在邊界。

2.6 尋找最大連通域并畫框

figure
subplot(1,2,1)
imshow(BW)
title('最終處理')
L = bwlabel(BW,8);%利用belabel函數(shù)對8連通域區(qū)間進行標號
BB = regionprops(L,'BoundingBox');%得到矩形框,框柱每一個連通域
BB = cell2mat(struct2cell(BB));
[s1,s2] = size(BB);
BB = reshape(BB,4,s1*s2/4)';
pickshape = BB(:,3)./BB(:,4);%
shapeind = BB(0.3<pickshape&pickshape<3,:);%篩選掉尺寸比例不合格
[~,arealind] = max(shapeind(:,3).*shapeind(:,4));
subplot(1,2,2)
imshow(rgb)
hold on
rectangle('Position',[shapeind(arealind,1),shapeind(arealind,2),shapeind(arealind,3),shapeind(arealind,3)],...
    'EdgeColor','g','Linewidth',2)
title('人臉檢測')

經(jīng)過消除邊界多余連通域后得到的BW中剩下的連通域內(nèi)存在著我們需要的那個對應人臉的連通域。一般情況下,對應人臉的那個連通域會是最大的連通域。

調(diào)用bwlabel(BW,8)函數(shù)給所有連通域標記,其中鄰域規(guī)則采用8鄰域,返回一個被標記過連通域的圖像,第k個被標記的連通域所有像素值為k。

調(diào)用regionprops(L,'BoundingBox')函數(shù),傳入?yún)?shù)L和'BoundingBox',該函數(shù)用于獲取圖像的各種屬性,傳入'BoundingBox'返回的是一個結(jié)構體,每一個結(jié)構體內(nèi)都包含了一個能框柱其對應連通域的最小方框。一個方框,用一個序列來描述[x,y,width,height],這個序列包含了方框左上角像素的坐標以及長和寬。

這三條語句,第一條用來將結(jié)構體轉(zhuǎn)換成矩陣向量,方便計算。第二行獲取這個矩陣的維度。由于BB剛轉(zhuǎn)換成向量的時候,是一個行向量,每4個元素1組對應一個方框。為了后續(xù)計算方便,使用reshape()函數(shù),將BB重構成一個矩陣,這個矩陣有4列,每一列對應方框的一個參數(shù),比如坐標,長寬等等。每一行對應一個方框。

第一行計算長寬比,得到的pickshape向量的每一行對應每個方框的長寬比。由于有的方框明顯過于扁平或者過于狹長,這種方框應該是要扔掉的。

所以第二行,通過邏輯表達式從BB內(nèi)篩選出尺寸比例合格的方框,存在shapeind里面。
剩下的尺寸符合要求的方框里面要選出面積最大的那個,最后一行,得到面積最大的方框?qū)乃饕?/p>

把方框畫出來。

3 檢測結(jié)果

                       圖 15rgb圖像轉(zhuǎn)換成灰度圖像                                                         圖 16線性均值濾波結(jié)果

可以看到,均值濾波使得圖像變模糊了細節(jié)減少

                                  圖 17二值化結(jié)果                                                                                圖 18形態(tài)學邊界提取結(jié)果

以看到邊界被成功提取了出來,在人臉部形成了一個比較大的連通域

可以看到,進行邊界加粗和空洞添補之后,眼睛部分的黑塊被消除了,這使得臉部連通域更大了

注意觀察圖片左邊的相分離的白塊,在縱向閉操作之后連在了一起,同時臉部連通域進一步擴大,然后橫向腐蝕在盡量維持臉部連通域大小的情況下減小了圖片下方連通域。

 可以看到效果還可以。還有其他的測試結(jié)果

 圖 24測試樣例

 圖 25測試樣例

 圖 26測試樣例

 圖 27測試樣例

 圖 28測試樣例

 圖 29測試樣例

圖 30測試樣例

這里注意到,黑人同樣也被檢測到了

---%%%完整代碼
rgb = imread('f.jpg');
I = rgb2gray(rgb);
[n1,n2] = size(I);
%灰度圖
figure,imshow(I),title('灰度圖')
tic
h = ones(9)/81;
I = uint8(conv2(I,h));
figure,imshow(I),title('線性均值濾波')
BW = imbinarize(I);
figure,imshow(BW),title('二值化')
B = ones(21);%結(jié)構元素
BW = -imerode(BW,B) + BW;
figure,imshow(BW),title('形態(tài)學邊界提取')
BW = bwmorph(BW,'thicken');
figure,imshow(BW),title('加粗邊界')
BW = not(bwareaopen(not(BW), 300));
figure,imshow(BW),title('把空洞填了')
%進行形態(tài)學運算
B = strel('line',50,90);
BW = imdilate(BW,B);
BW = imerode(BW,B);
figure,imshow(BW),title('再閉操作之后')
B = strel('line',10,0);
BW = imerode(BW,B);
figure,imshow(BW),title('閉操作之后再腐蝕')
BW = gpuArray(BW);
 
%最小化背景
%細分
div = 10;
r = floor(n1/div);%分成10塊 行
c = floor(n2/div);%分成10塊 列
x1 = 1;x2 = r;%對應行初始化
s = r*c;%塊面積
%判斷人臉是否處于圖片四周,如果不是就全部弄黑
%figure
for i=1:div
    y1 = 1;y2 = c;%對應列初始化
    for j=1:div
        loc = find(BW(x1:x2,y1:y2)==0);%統(tǒng)計這一塊黑色像素的位置
        num = length(loc);
        rate = num*100/s;%統(tǒng)計黑色像素占比
        if (y2<=0.2*div*c||y2>=0.8*div*c)||(x1<=r||x2>=r*div)
            if rate <=100
                BW(x1:x2,y1:y2) = 0;
            end
            %imshow(BW)
        else
            if rate <=25
                BW(x1:x2,y1:y2) = 1;
            end
            %imshow(BW)
        end%下一列
        y1 = y1 + c;
        y2 = y2 + c;
    end%下一行
    x1 = x1 + r;
    x2 = x2 + r;
end
 
figure
subplot(1,2,1)
imshow(BW)
title('最終處理')
L = bwlabel(BW,8);%利用belabel函數(shù)對8連通域區(qū)間進行標號
BB = regionprops(L,'BoundingBox');%得到矩形框,框柱每一個連通域
BB = cell2mat(struct2cell(BB));
[s1,s2] = size(BB);
BB = reshape(BB,4,s1*s2/4)';
pickshape = BB(:,3)./BB(:,4);%
shapeind = BB(0.3<pickshape&pickshape<3,:);%篩選掉尺寸比例不合格
[~,arealind] = max(shapeind(:,3).*shapeind(:,4));
subplot(1,2,2)
imshow(rgb)
hold on
rectangle('Position',[shapeind(arealind,1),shapeind(arealind,2),shapeind(arealind,3),shapeind(arealind,3)],...
    'EdgeColor','g','Linewidth',2)
title('人臉檢測')
toc

到此這篇關于MATLAB處理圖像后實現(xiàn)簡單的人臉檢測的文章就介紹到這了,更多相關MATLAB實現(xiàn)人臉檢測內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C語言內(nèi)存函數(shù)的使用及其模擬實現(xiàn)

    C語言內(nèi)存函數(shù)的使用及其模擬實現(xiàn)

    這篇文章主要介紹了C語言內(nèi)存函數(shù)的使用及其模擬實現(xiàn),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-10-10
  • C語言連續(xù)子向量的最大和及時間度量實例

    C語言連續(xù)子向量的最大和及時間度量實例

    這篇文章主要介紹了C語言連續(xù)子向量的最大和及時間度量,需要的朋友可以參考下
    2014-09-09
  • C++控制臺實現(xiàn)俄羅斯方塊游戲

    C++控制臺實現(xiàn)俄羅斯方塊游戲

    這篇文章主要為大家詳細介紹了C++控制臺實現(xiàn)俄羅斯方塊游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • Unity編輯器下重啟的方法

    Unity編輯器下重啟的方法

    這篇文章主要介紹了Unity編輯器下重啟的方法的相關資料,希望通過本文能幫助到大家,讓大家學習理解這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • 關于C++友元類的實現(xiàn)講解

    關于C++友元類的實現(xiàn)講解

    今天小編就為大家分享一篇關于關于C++友元類的實現(xiàn)講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • C++中結(jié)構體和Json字符串互轉(zhuǎn)的問題詳解

    C++中結(jié)構體和Json字符串互轉(zhuǎn)的問題詳解

    這篇文章主要給大家介紹了關于C++中結(jié)構體和Json字符串互轉(zhuǎn)問題的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • C++中typeid實現(xiàn)原理詳解

    C++中typeid實現(xiàn)原理詳解

    這篇文章主要給大家介紹了關于C++中typeid實現(xiàn)原理的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • 探討:用兩個棧實現(xiàn)一個隊列(我作為面試官的小結(jié))

    探討:用兩個棧實現(xiàn)一個隊列(我作為面試官的小結(jié))

    作為面試官的我,經(jīng)常拿這道用兩個棧實現(xiàn)一個隊列的面試題來考面試者,通過對面試者的表現(xiàn)和反應,有一些統(tǒng)計和感受,在此做個小結(jié)
    2013-05-05
  • 使用c++實現(xiàn)OpenCV繪制旋轉(zhuǎn)矩形圖形

    使用c++實現(xiàn)OpenCV繪制旋轉(zhuǎn)矩形圖形

    這篇文章主要給大家介紹了使用c++實現(xiàn)OpenCV繪制圖形旋轉(zhuǎn)矩形的方法案例,通過圖文及代碼形式進行了詳細的描述,有需要的朋友可以參考下,希望可以有所幫助
    2021-08-08
  • c語言?數(shù)據(jù)存儲與原碼?反碼?補碼詳細解析

    c語言?數(shù)據(jù)存儲與原碼?反碼?補碼詳細解析

    不知道你是否和我一樣好奇,學習編程語言的同時想,各個數(shù)據(jù)類型是怎樣在我們的內(nèi)存中儲存的呢,如果你仔細深入了解的話,你會了解其中的樂趣,了解科學家們的偉大,了解c語言
    2022-02-02

最新評論