此示例說明如何自動(dòng)檢測(cè)圖像中的圓形目標(biāo)并可視化檢測(cè)到的圓。
步驟 1:加載圖像
讀取并顯示包含各種顏色的圓形塑料片的圖像。除了有大量要檢測(cè)的圓之外,從圓檢測(cè)的角度來(lái)看,此圖像還有一些有趣的特點(diǎn):
有不同顏色的塑料片,它們相對(duì)于背景有不同對(duì)比度。一方面,藍(lán)色和紅色塑料片在此背景上形成強(qiáng)烈的對(duì)比。另一方面,一些黃色塑料片與背景的對(duì)比不明顯。
請(qǐng)注意一些塑料片重疊在一起,而另一些塑料片則靠得很近,幾乎互相接觸。對(duì)于目標(biāo)檢測(cè)來(lái)說,場(chǎng)景中存在重疊的對(duì)象邊緣和對(duì)象遮擋通常具有挑戰(zhàn)性。
rgb
= imread
('coloredChips.png'); %加載圖像
imshow
(rgb
);
title
('coloredChips');
步驟 2:確定搜索圓的半徑范圍
使用 drawline 函數(shù)找到合適的圓半徑范圍。在塑料片的近似直徑上繪制一條線。
rgb
= imread
('coloredChips.png'); %加載圖像
imshow
(rgb
);
title
('coloredChips');
d
= drawline
; %使用 drawline 函數(shù)找到合適的圓半徑范圍
pos
= d.Position
;
diffPos
= diff
(pos
);
diameter
= hypot
(diffPos
(1),diffPos
(2));
步驟 3:尋找圓的初步嘗試
imfindcircles 函數(shù)搜索符合半徑范圍的圓。搜索半徑在 20 到 25 個(gè)像素范圍內(nèi)的圓。在此之前,最好要清楚對(duì)象是比背景亮還是比背景暗。要回答該問題,請(qǐng)看此圖像的灰度版本。
rgb
= imread
('coloredChips.png'); %加載圖像
subplot
(1,2,1
);
imshow
(rgb
);
title
('coloredChips');
%d
= drawline
; %使用 drawline 函數(shù)找到合適的圓半徑范圍
% pos
= d.Position
;
% diffPos
= diff
(pos
);
% diameter
= hypot
(diffPos
(1),diffPos
(2));
gray_image
= rgb2gray
(rgb
); %轉(zhuǎn)為灰度圖像
subplot
(1,2,2
);
imshow
(gray_image
); %顯示灰度圖像
title
('coloredChips灰度圖');
背景相當(dāng)亮,大多數(shù)塑料片比背景暗。但是,默認(rèn)情況下,imfindcircles 會(huì)找到比背景亮的圓形目標(biāo)。因此,在 imfindcircles 中將參數(shù) ‘ObjectPolarity’ 設(shè)置為 ‘dark’ 以搜索較暗的圓。
>> [centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'dark') %在 imfindcircles 中將參數(shù)
'ObjectPolarity' 設(shè)置為
'dark' 以搜索較暗的圓centers
=[]radii
=[]
請(qǐng)注意,輸出 centers 和 radii 為空,這意味著未找到圓。這種情況經(jīng)常發(fā)生,因?yàn)?imfindcircles 是圓形檢測(cè)器,與大多數(shù)檢測(cè)器類似,imfindcircles 有內(nèi)部檢測(cè)閾值決定其敏感度。簡(jiǎn)而言之,這意味著檢測(cè)器對(duì)某個(gè)(圓形)檢測(cè)的信心必須大于某個(gè)水平,才將其視為有效檢測(cè)。imfindcircles 有參數(shù) ‘Sensitivity’,可用于控制此內(nèi)部閾值,從而控制算法的敏感度。較高的 ‘Sensitivity’ 值會(huì)將檢測(cè)閾值設(shè)置得較低,并導(dǎo)致檢測(cè)到更多圓。這類似于家庭安全系統(tǒng)中使用的運(yùn)動(dòng)檢測(cè)器的敏感度控制。
步驟 4:提高檢測(cè)敏感度
回到塑料片圖像,在默認(rèn)敏感度水平下,可能所有圓都低于內(nèi)部閾值,因此未檢測(cè)到圓。‘Sensitivity’ 是介于 0 和 1 之間的數(shù)字,默認(rèn)設(shè)置為 0.85。將 ‘Sensitivity’ 提高到 0.9。
>> [centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'dark',
'Sensitivity',0.9
) %將
'Sensitivity' 設(shè)置為
0.9centers
=146.1895 198.5824328.8132 135.5883130.3134 43.8039175.2698 297.0583312.2831 192.3709327.1316 297.0077243.9893 166.4538271.5873 280.8920radii
=23.160422.571022.957623.735622.955122.999522.905523.0298
這次,imfindcircles 發(fā)現(xiàn)了一些圓 - 準(zhǔn)確地說是八個(gè)。centers 包含圓心的位置,radii 包含這些圓的估計(jì)半徑。
步驟 5:在圖像上繪制圓
函數(shù) viscircles 可用于在圖像上繪制圓。來(lái)自 imfindcircles 的輸出變量 centers 和 radii 可以直接傳遞給 viscircles。
rgb
= imread
('coloredChips.png'); %加載圖像
subplot
(2,2,1
);
imshow
(rgb
);
title
('coloredChips');[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'dark',
'Sensitivity',0.9
);
subplot
(2,2,2
);
imshow
(rgb
);
h
= viscircles
(centers,radii
); %在圖像上繪制靈敏度為0.9時(shí)找到的圓
title
('靈敏度為0.9時(shí)找到的圓');
a1
= length
(centers
) %計(jì)算找到繪制靈敏度為0.9時(shí)的圓的個(gè)數(shù)
[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'dark',
'Sensitivity',0.92
);
subplot
(2,2,3
);
imshow
(rgb
);
h
= viscircles
(centers,radii
); %在圖像上繪制靈敏度為0.92時(shí)找到的圓
title
('靈敏度為0.92時(shí)找到的圓');
a2
= length
(centers
) %計(jì)算找到繪制靈敏度為0.92時(shí)的圓的個(gè)數(shù)
[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'dark',
'Sensitivity',0.95
);
subplot
(2,2,4
);
imshow
(rgb
);
h
= viscircles
(centers,radii
); %在圖像上繪制靈敏度為0.95時(shí)找到的圓
title
('靈敏度為0.95時(shí)找到的圓');
a3
= length
(centers
) %計(jì)算找到繪制靈敏度為0.95時(shí)的圓的個(gè)數(shù)%計(jì)算結(jié)果
a1
=8a2
=16a3
=22
步驟 6:使用第二種方法(兩階段)尋找圓
此方法的結(jié)果看起來(lái)更好。imfindcircles 有兩種不同尋找圓的方法。到當(dāng)前為止,默認(rèn)方法(稱為相位編碼方法)用于檢測(cè)圓。在 imfindcircles 中還可以使用另一種方法,通常稱為兩階段方法。使用兩階段方法并顯示結(jié)果。
rgb
= imread
('coloredChips.png'); %加載圖像
subplot
(2,2,1
);
[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'dark',
'Sensitivity',0.9
);
imshow
(rgb
);
h
= viscircles
(centers,radii
); %用相位編碼方法在圖像上繪制靈敏度為0.9時(shí)找到的圓
title
('相位編碼方法:靈敏度為0.9時(shí)找到的圓');
a1
= length
(centers
) %計(jì)算相位編碼方法找到繪制靈敏度為0.9時(shí)的圓的個(gè)數(shù)subplot
(2,2,2
);
[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'dark',
'Sensitivity',0.9,
'Method',
'twostage');
imshow
(rgb
);
h
= viscircles
(centers,radii
); %用兩階段方法在圖像上繪制靈敏度為0.9時(shí)找到的圓
title
('兩階段方法:靈敏度為0.9時(shí)找到的圓');
a2
= length
(centers
) %計(jì)算兩階段方法找到繪制靈敏度為0.9時(shí)的圓的個(gè)數(shù)subplot
(2,2,3
);
[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'dark',
'Sensitivity',0.92
);
imshow
(rgb
);
h
= viscircles
(centers,radii
); %用相位編碼方法在圖像上繪制靈敏度為0.92時(shí)找到的圓
title
('相位編碼方法:靈敏度為0.92時(shí)找到的圓');
a3
= length
(centers
) %計(jì)算相位編碼方法找到繪制靈敏度為0.92時(shí)的圓的個(gè)數(shù)subplot
(2,2,4
);
[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'dark',
'Sensitivity',0.92,
'Method',
'twostage');
imshow
(rgb
);
h
= viscircles
(centers,radii
); %用兩階段方法在圖像上繪制靈敏度為0.92時(shí)找到的圓
title
('兩階段方法:靈敏度為0.92時(shí)找到的圓');
a4
= length
(centers
) %計(jì)算兩階段方法找到繪制靈敏度為0.92時(shí)的圓的個(gè)數(shù)
!%統(tǒng)計(jì)結(jié)果
a1
=8 %相位編碼方法找到繪制靈敏度為0.9時(shí)的圓的個(gè)數(shù)為8個(gè)a2
=22 %兩階段方法找到繪制靈敏度為0.9時(shí)的圓的個(gè)數(shù)為22個(gè)a3
=16 %相位編碼方法找到繪制靈敏度為0.92時(shí)的圓的個(gè)數(shù)為16個(gè)a4
=22 %兩階段方法找到繪制靈敏度為0.92時(shí)的圓的個(gè)數(shù)為22個(gè)
兩階段方法使用敏感度0.9和 0.92 檢測(cè)更多圓。一般來(lái)說,這兩種方法是互補(bǔ)的,因?yàn)樗鼈冇胁煌瑑?yōu)點(diǎn)。相位編碼方法通常比兩階段方法更快,抗噪聲的穩(wěn)定性稍強(qiáng)。但是,它也可能需要更高的 ‘Sensitivity’ 水平才能實(shí)現(xiàn)與兩階段方法相同數(shù)量的檢測(cè)。例如,如果 ‘Sensitivity’ 水平提高到 0.95,相位編碼方法也會(huì)找到相同的塑料片。
rgb
= imread
('coloredChips.png'); %加載圖像
subplot
(1,2,1
);
[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'dark',
'Sensitivity',0.95
);
imshow
(rgb
);
h
= viscircles
(centers,radii
); %用相位編碼方法在圖像上繪制靈敏度為0.95時(shí)找到的圓
title
('相位編碼方法:靈敏度為0.95時(shí)找到的圓');
a1
= length
(centers
) %計(jì)算相位編碼方法找到繪制靈敏度為0.95時(shí)的圓的個(gè)數(shù)subplot
(1,2,2
);
[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'dark',
'Sensitivity',0.95,
'Method',
'twostage');
imshow
(rgb
);
h
= viscircles
(centers,radii
); %用兩階段方法在圖像上繪制靈敏度為0.95時(shí)找到的圓
title
('兩階段方法:靈敏度為0.95時(shí)找到的圓');
a2
= length
(centers
) %計(jì)算兩階段方法找到繪制靈敏度為0.95時(shí)的圓的個(gè)數(shù)%統(tǒng)計(jì)結(jié)果
a1
=22 %相位編碼方法找到繪制靈敏度為0.95時(shí)的圓的個(gè)數(shù)為22個(gè)a2
=22 %兩階段方法找到繪制靈敏度為0.95時(shí)的圓的個(gè)數(shù)為22個(gè)
請(qǐng)注意,imfindcircles 中的兩種方法都能準(zhǔn)確找到部分可見(遮擋)塑料片的中心和半徑。
步驟 7:為什么有些圓仍檢測(cè)不到?
查看最后一個(gè)結(jié)果,很奇怪 imfindcircles 沒有在圖像中找到黃色塑料片。黃色塑料片與背景的對(duì)比不夠強(qiáng)烈。事實(shí)上,它們看起來(lái)和背景的強(qiáng)度非常相似。是不是黃色塑料片并沒有想象中的那樣比背景“更暗”?要確認(rèn)這一點(diǎn),請(qǐng)?jiān)俅物@示該圖像的灰度版本。
步驟 8:在圖像中找到“明亮”的圓
查看圖像的灰度圖,可發(fā)現(xiàn)與背景相比,黃色塑料片的強(qiáng)度幾乎相同,甚至更亮。因此,要檢測(cè)黃色塑料片,請(qǐng)將 ‘ObjectPolarity’ 更改為 ‘bright’。
rgb
= imread
('coloredChips.png'); %加載圖像
subplot
(1,2,1
);
[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'bright',
'Sensitivity',0.92
);
imshow
(rgb
);
h
= viscircles
(centers,radii
); %用相位編碼方法在圖像上繪制靈敏度為0.92時(shí)找到的圓
title
('相位編碼方法:靈敏度為0.92時(shí)找到的圓');
a1
= length
(centers
) %計(jì)算相位編碼方法找到繪制靈敏度為0.92時(shí)的圓的個(gè)數(shù)subplot
(1,2,2
);
[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'bright',
'Sensitivity',0.92,
'Method',
'twostage');
imshow
(rgb
);
h
= viscircles
(centers,radii
); %用兩階段方法在圖像上繪制靈敏度為0.92時(shí)找到的圓
title
('兩階段方法:靈敏度為0.92時(shí)找到的圓');
a2
= length
(centers
) %計(jì)算兩階段方法找到繪制靈敏度為0.92時(shí)的圓的個(gè)數(shù)%統(tǒng)計(jì)結(jié)果
a1
=3a2
=5
步驟 9:用不同顏色繪制 ‘Bright’ 圓
通過更改 viscircles 中的 ‘Color’ 參數(shù),以不同顏色繪制明亮的圓。
h
= viscircles
(centers,radii,
'Color',
'b'); %將上面程序中的代碼改為此代碼即可
請(qǐng)注意,找到了三個(gè)原先未檢測(cè)到的黃色塑料片,但仍有黃色塑料片未檢測(cè)到。這些黃色塑料片很難檢測(cè)到,因?yàn)樵谶@種背景下,它們沒有呈現(xiàn)出與眾不同。
步驟 10:降低 ‘EdgeThreshold’ 的值
在這里還可以使用 imfindcircles 中的另一個(gè)參數(shù),即 ‘EdgeThreshold’。要查找圓,imfindcircles 僅使用圖像中的邊緣像素。這些邊緣像素基本上是具有高梯度值的像素。‘EdgeThreshold’ 參數(shù)控制像素的梯度值必須有多高,才能將其視為邊緣像素并包含在計(jì)算中。該參數(shù)的高值(更接近 1)只允許包含強(qiáng)邊緣(較高梯度值),而低值(更接近 0)的寬容度更高,可在計(jì)算中包含較弱的邊緣(較低梯度值)。對(duì)于檢測(cè)不到黃色塑料片的情況,是因?yàn)閷?duì)比度低,一些邊界像素(在塑料片的圓周上)預(yù)期具有低梯度值。因此,請(qǐng)降低 ‘EdgeThreshold’ 參數(shù),以確保黃色塑料片的大多數(shù)邊緣像素都包含在計(jì)算中。
rgb
= imread
('coloredChips.png'); %加載圖像
subplot
(1,2,1
);
[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'bright',
'Sensitivity',0.92,
'EdgeThreshold',0.1
);
imshow
(rgb
);
h
= viscircles
(centers,radii,
'Color',
'b'); %用相位編碼方法在圖像上繪制靈敏度為0.92時(shí)找到的圓
title
('相位編碼方法:靈敏度為0.92時(shí)找到的圓');
a1
= length
(centers
) %計(jì)算相位編碼方法找到繪制靈敏度為0.92時(shí)的圓的個(gè)數(shù)subplot
(1,2,2
);
[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'bright',
'Sensitivity',0.92,
'Method',
'twostage',
'EdgeThreshold',0.1
);
imshow
(rgb
);
h
= viscircles
(centers,radii,
'Color',
'b'); %用兩階段方法在圖像上繪制靈敏度為0.92時(shí)找到的圓
title
('兩階段方法:靈敏度為0.92時(shí)找到的圓');
a2
= length
(centers
) %計(jì)算兩階段方法找到繪制靈敏度為0.92時(shí)的圓的個(gè)數(shù)%統(tǒng)計(jì)結(jié)果
a1
=5a2
=6
步驟 11:同時(shí)繪制“暗”和“亮”圓
現(xiàn)在 imfindcircles 找到了所有黃色圓,還找到了一個(gè)綠色圓。用藍(lán)色繪制這些塑料片,用紅色繪制之前發(fā)現(xiàn)的其他塑料片(‘ObjectPolarity’ 設(shè)置為 ‘dark’)。
用相位編碼法找到的所有圓
**
rgb
= imread
('coloredChips.png'); %加載圖像
%subplot
(2,2,1
);
[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'bright',
'Sensitivity',0.92
);
imshow
(rgb
);
h
= viscircles
(centers,radii,
'color',
'b'); %用相位編碼方法在圖像上繪制靈敏度為0.92時(shí)找到
"亮"圓
title
('相位編碼方法:靈敏度為0.92時(shí)找到的圓');
[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'dark',
'Sensitivity',0.92
);
h
= viscircles
(centers,radii
); %找到
"暗"圓
a1
= length
(centers
) %計(jì)算相位編碼方法找到繪制靈敏度為0.92時(shí)的圓的個(gè)數(shù)%統(tǒng)計(jì)個(gè)數(shù)
a1
=16
用兩階段法找到的圓
rgb
= imread
('coloredChips.png'); %加載圖像
%subplot
(2,2,1
);
[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'bright',
'Sensitivity',0.92,
'Method',
'twostage');
imshow
(rgb
);
h
= viscircles
(centers,radii,
'color',
'b'); %用兩階段方法在圖像上繪制靈敏度為0.92時(shí)找到
"明"圓
title
('兩階段方法:靈敏度為0.92時(shí)找到的圓');
[centers,radii
] = imfindcircles
(rgb,
[20 25],
'ObjectPolarity',
'dark',
'Sensitivity',0.92,
'Method',
'twostage');
h
= viscircles
(centers,radii
); %找到
"暗"圓
a2
= length
(centers
) %計(jì)算兩階段方法找到繪制靈敏度為0.92時(shí)的圓的個(gè)數(shù)%統(tǒng)計(jì)結(jié)果
a2
= 22
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀
總結(jié)
以上是生活随笔為你收集整理的1.2 检测和测量图像中的圆形目标的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。