文章出處

這是matlab自帶的一個例程。

問題描述:光纖橫截面包括core和cladding兩部分,也就是“中心圓”和“漆包線”
希望兩者是同心圓,或者說,希望兩者圓心差的不要太離譜
原理:先將圖像轉換為二值圖像,得到只有漆包線(圓環)是黑色、其他都是白色的圖像
根據漆包線區域計算出圖像重心
根據重心得到cladding邊界上一個點,進而得到整個邊界上的點集
由邊界點擊得到圓心。使用了最小二乘法來擬合圓形(算法有點復雜。。沒看過)
計算圓心和重心之間的偏差,若小于閾值則認為光纖合格

%初始化
NumPts = 250; %邊界像素點的最大數目
tolerance = 1; %容忍距離
NumTimes = 8;

%創建一個視頻讀寫系統對象,讀取視頻文件
hmfr = vision.VideoFileReader('vipconcentricity.avi', 'PlayCount', NumTimes);
%轉換RGB到灰度空間。為什么要創建一個轉換對象?直接轉不好嗎?
hcsc = vision.ColorSpaceConverter('Conversion', 'RGB to intensity');

%創建一個光斑分析(BlobAnalysis)系統對象,用來尋找視頻中圓形光斑的重心
hblob = vision.BlobAnalysis('AreaOutputPort', false,...
    'BoundingBoxOutputPort', false,...
    'OutputDataType', 'single',...
    'MaximumCount', 1);

%創建一個邊界跟蹤系統對象,用來尋找包層的中心
%BoundaryTracer函數是在二值圖像上找到object的邊界,也就是非零的邊界點集合
%目測是用dfs來實現的
htracebound = vision.BoundaryTracer(...
    'MaximumPixelCount', NumPts,...
    'NoBoundaryAction', 'Fill with last point found');

%創建兩個視頻播放對象,用來顯示視頻的輸入和輸出
hVideo1 = vision.VideoPlayer('Name', 'Original');
hVideo_gray = vision.VideoPlayer('Name', 'Gray');
hVideo_binary = vision.VideoPlayer('Name', 'Binary');
hVideo2 = vision.VideoPlayer('Name', 'Results');
hVideo2.Position(1) = hVideo1.Position(1) + 450;

%處理視頻流
count = 1;
while(count<NumTimes)
    if isDone(hmfr)
        count = count + 1;
    end
    I = step(hmfr);
    image = step(hcsc, I); %轉化圖片為灰度圖
    step(hVideo_gray, image);
    
    BW = image < 0.5; %轉化圖片為二值圖
    step(hVideo_binary, BW);
    centroid = step(hblob, BW); %計算光斑重心
    
    Idx = floor(centroid(1)); %重心x坐標
    max_idx = find(BW(:,Idx), 1); %重心x坐標所在的列中,第一個非零元素的索引.
    %因為圖片已經是二值化的,(而且是理想圖片),所以第一個非零元素一定是cladding外圍圓周上、垂直過圓心的上側的點
    
    StartPts = [Idx, single(max_idx)]; %計算起始點,也就是cladding外圍圓周上垂直過圓心的上側的點
    
    %尋找外部包層的邊界像素
    Pts = step(htracebound, BW, StartPts);
    
    %以下是難點部分:根據邊界點,用最小二乘法擬合圓形,得到圓心和半徑
    %原理見Paper:http://www.emis.de/journals/BBMS/Bulletin/sup962/gander.pdf
    Row_bound = Pts(:, 1);
    Col_bound = Pts(:, 2);
    t = [Row_bound Col_bound ones(size(Pts, 1), 1)];
    
    X = pinv(t);
    X1 = Row_bound.^2 + Col_bound.^2;
    x2 = X*(-X1);
    
    radius = sqrt((-0.5*x2(1)).^2 + (-0.5*x2(2)).^2 - x2(3));
    center = [(-0.5*x2(1)), (-0.5*x2(2))];
    %擬合計算完畢,得到了圓心和半徑。下面,用圓心和重心比較
    %如果兩者之間誤差在允許范圍內,則光纖是可以接受的(合格)

    dist = sqrt(sum(centroid - center).^2);
    disp(dist)

    % 繪制圓形,并標注出圓心和重心
    y1 = insertMarker(I, centroid, '+', 'Color', 'red');
    y2 = insertShape(y1, 'Circle', [center, radius],'Color', 'cyan');
    y3 = insertMarker(y2, center, '*', 'Color', 'green');

    % 插入文本
    qualitySet =  {'Bad', 'Good'};
    textIdx = (dist <= tolerance) + 1;
    textQuality = ['Concentricity: ' qualitySet{textIdx}];
    textDist = sprintf('Distance in pixels: %d', uint8(dist));
    textAll = sprintf([textQuality '\n' textDist]);
    image_out = insertText(y3, [1 1], textAll, 'FontSize', 14);
    % 顯示結果
    step(hVideo2, image_out);
    step(hVideo1, I);
end

release(hmfr);

文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()