【裂痕識別】基於matlab閾值裂痕+劃痕檢測【含Matlab原始碼 467期】
一、簡介
1 閾值
我們將影象分塊最簡單的方法就是設定一個閾值對影象進行二值化處理,那麼這個閾值我們應該如何選擇呢
對於影象的直方圖存在明顯邊界的影象,我們可以很容易找到這個閾值,但是如果影象直方圖分界不明顯,那麼這個閾值的尋找將變得十分困難。因此我們存在全域性閾值與區域性閾值兩種。
2 全域性閾值
全域性閾值就是在整幅影象中我們只有一個閾值來對影象進行二值化,但是其存在其侷限性,例如影象中存在高斯噪聲的情況下,我們無法找到一個很好的閾值將影象的邊界分開
另外如果影象的邊界是在區域性對比下出現的,即不同位置閾值不同,那麼全域性閾值的效果也非常不好。
我們先不管全域性閾值的缺點,我們來看看我們如何通過計算來獲得這個全域性閾值T呢?我們又OTSU'S演算法。
下面是一些數學概念在影象上的體現
OTSU演算法就是想把影象分為兩個塊,然後使得這兩個塊之間的方差最大,也就是最大化兩個塊的均值與全域性均值的差的平方
由於只存在這麼一個閾值,那麼我們在計算的時候可以簡單地讓這個值遍歷0-255,然後找到σB最大的值,這個值就是我們要的閾值。我們可以理解為這個值把影象分為了相距最遠的兩塊。我們在matlab中有graythresh這個函式來實現這個過程。
下圖就顯示了一個OTSU演算法不是很理想的例子。
為了克服以上缺點我們有兩點解決方法:1.先通過低通濾波器去噪再用OTSU 2.只在考慮邊緣部分的畫素來計算閾值,這樣可以大大減少其他不重要部分對閾值計算過程的影響
3 區域性閾值
下面讓我們來看看區域性閾值/自適應閾值。它的原理就是將影象分塊,對於不同的部分應用不同的閾值,在matlab中我們有blockproc這個函式來實現這個過程
我們看到相比於之前,效果確實有很大的提升,但是缺點也特別明顯,就是影象會出現分塊化
我們可以調小塊的大小,但是這樣的話會出現如果塊內畫素值變化不大的話,塊內畫素被全部分作黑或白而缺失了邊界(例如右上角窗戶的上方黑色的窗框內有白色的畫素塊)。因此塊的選擇是十分重要的。
更好的方式是我們在每個畫素周圍的一個區域內來計算閾值,根據這個塊內的均值方差來計算這個畫素的值是1還是0
4 RGB圖閾值
除了將閾值在灰度圖上應用,我們還可以將其應用在RGB圖中,我們可以設定一種顏色,來得到與這種顏色相近顏色的物體
例如我們取下圖絲帶的顏色可以得到如右圖的結果
二、原始碼
close all; clear; clc; warning off all; %% 第一類劃痕1-1.jpg 1-2.jpg I = imread('1-1.jpg'); IGrey = rgb2gray(I); %IGrey = adapthisteq(IGrey); % Contrast-limited adaptive histogram equalization (CLAHE) Ibw = im2bw(IGrey);% Ibw是二值影象,不需要求閾值 Ibw = ~Ibw; Ibw = bwareaopen(Ibw,20) ;%將小於XX畫素的單元去掉 figure, subplot(1,2,1) imshow(I); title('原圖'); subplot(1,2,2) imshow(Ibw); title('劃痕檢測圖'); I = imread('1-2.jpg'); IGrey = rgb2gray(I); level = graythresh(IGrey) Ibw = im2bw(IGrey,level);% Ibw是二值影象,不需要求閾值 Ibw = ~Ibw; figure, subplot(1,2,1) imshow(I); title('原圖'); subplot(1,2,2) imshow(Ibw); title('劃痕檢測圖'); %% 第二類劃痕2-1.jpg 2-2.jpg I = imread('2-1.jpg'); IGrey = rgb2gray(I); w2 = fspecial('average',[15 15]); %% 先定義一個濾波器 IMean = imfilter(IGrey,w2,'replicate'); %%讓影象通過濾波器 result = abs(imsubtract(im2double(IGrey),im2double(IMean))); maxValue = max(max(result)); threshod = maxValue * 0.3; result(result >= threshod) = 1; result(result < threshod) = 0; Ibw = bwareaopen(im2uint8(result),10);%將小於XX畫素的單元去掉 figure, subplot(1,2,1) imshow(I); title('原圖'); subplot(1,2,2) imshow(Ibw); title('劃痕檢測圖'); I = imread('2-2.jpg'); IGrey = rgb2gray(I); w2 = fspecial('average',[15 15]); %% 先定義一個濾波器 IMean = imfilter(IGrey,w2,'replicate'); %%讓影象通過濾波器 result = abs(imsubtract(im2double(IGrey),im2double(IMean))); maxValue = max(max(result));
三、執行結果
四、備註
版本:2014a
完整程式碼或代寫加1564658423