DIA實驗——條碼缺陷檢測

實驗名稱:條碼缺陷檢測

  1. 實驗內容
    條碼中可能存在的斷碼、白點、黑點等影響條碼外觀的瑕疵,檢測這些瑕疵,並用紅色矩形框將其標出。

  2. 分析過程
    需要用到圖像形態學知識,先確定條碼目標,再對ROI區域內進行缺陷檢測。步驟如下:
    ① 預處理:對圖形進行二值化;
    ② 確定ROI:圖形取反,膨脹,得到最大的兩個連通域目標,即爲兩個條碼區域ROI;
    ③ 取條碼圖形:將ROI區域與原圖形做邏輯與操作,得到只有原條碼的圖片;
    ④ 去噪:中值濾波,去除過小的噪聲,並讓過小的缺陷橫向特徵更明顯;
    ⑤ 去條碼:再次取反,進行開運算,先通過腐蝕操作使用長橫條形狀內核去除豎碼條,再通過膨脹操作讓缺陷部分更突出;
    ⑥ 確定缺陷塊:將去除了豎條碼區域的圖像和ROI區域做與運算,得到缺陷小塊集合;
    ⑦ 優化:不同內核的多次中值濾波,進一步濾去未消除乾淨的豎條碼,再次膨脹突出缺陷;
    ⑧ 標記:使用紅色矩形框對各連通域進行標記。

  3. 實驗效果圖
    1
    3
    4
    6
    7
    可以看到,大多數缺陷都已經可以檢測出,但依舊有些地方檢測不到,有待改進。

  4. 實驗代碼(Matlab)
    Main.m

clear;
close all;
clc;
 
%% Binarize the input image
im = imread('images/barcode_7.png');
 
im_gray = rgb2gray(im); 
level = graythresh(im_gray)
bw = im2bw(im_gray, level);
 
figure; 
subplot(3, 2, 1); imshow(im_gray); title('original image');
subplot(3, 2, 2); imshow(bw); title('binary result');
 
%% 請基於二值圖像bw,將二維碼瑕疵區域檢測出來 
detect = ~bw;
% subplot(3, 2, 3);imshow(detect); title('detect');
hold on
SE=strel('rectangle',[1 30]);
detect = imdilate(~bw, SE);
f = maxLianTongYu(detect);          %分離第一個二維碼
s = maxLianTongYu(detect-f);        %分離第二個二維碼
f = f + s;
ROI = imdilate(f, strel('rectangle',[30 30]));
ROI = imerode(ROI, strel('rectangle',[40 40]));  %白色二維碼區域
first = f&~bw;                
first = medfilt2(first,[1,5]);         %中值濾波,讓過小的缺陷橫向特徵更明顯
% subplot(3, 2, 4);imshow(~first); title('first');
first = imerode(~first, strel('rectangle',[1 35])); %去除豎碼條
first = imdilate(first, strel('rectangle',[10 10]));    %讓缺陷部分更突出
first = first & ROI;
first = medfilt2(first,[15,2]);         %中值濾波[15,14]
first = medfilt2(first,[18,12]); 
first = imdilate(first, strel('rectangle',[10 10]));
% subplot(3, 2, 5); imshow(first); title('second');
 
imLabel = bwlabel(first);                %對各連通域進行標記
stats = regionprops(imLabel,'Area', 'boundingbox');    %求各連通域的大小
area = cat(1,stats.Area);
rects = cat(1,stats.BoundingBox);
subplot(3, 2, [3 6]); imshow(im); title('final');
for i = 1:size(rects, 1)
    rectangle('position', rects(i, :), 'EdgeColor', 'r');
end

maxLianTongYu.m

%function [img]=maxLianTongYu(I):求圖像中最大的連通域
%輸入:I    輸入圖像
%輸出:img  僅包含最大連通域的圖像 
function [img]=maxLianTongYu(I)
if length(size(I))>2
    I = rgb2gray(I);
end
if ~islogical(I)
    imBw = im2bw(I);                        %轉換爲二值化圖像
else
    imBw = I;
end
imLabel = bwlabel(imBw);                %對各連通域進行標記
stats = regionprops(imLabel,'Area');    %求各連通域的大小
area = cat(1,stats.Area);
index = find(area == max(area));        %求最大連通域的索引
img = ismember(imLabel,index);          %獲取最大連通域圖像

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章