本文用matlab實現了基本多邊形的檢測、提取。算法
本文涉及到的知識點以下:google
一、Canny邊緣檢測。 bw = edge(gray,'canny',[0 , 50/256]);spa
二、細化操做。 im=bwmorph(image,'thin',Inf);.net
三、邊界追蹤。 edgelist=bwboundaries(im);code
四、邊界的多邊形近似。 linefit_Prasad_RDP_opt(edgelist);blog
本文算法思路借鑑了Nash的博客,地址:http://opencv-code.com/tutorials/detecting-simple-shapes-in-an-image/點擊打開連接圖片
邊界的多邊形近似算法爲:Douglas-Peucker algorithm,算法的matlab實現我引用了Dilip K. Prasad分享的文件。本文全部操做的理論基礎都可在岡薩雷斯的《數字圖像處理》中找到答案。ip
Douglas-Peucker algorithm地址:https://docs.google.com/file/d/0B10RxHxW3I92dG9SU0pNMV84alk/edit?pli=1點擊打開連接ci
算法實現過程可分爲如下幾步。get
一、提取邊緣。
二、進行形態學處理,分割圖像。
三、進行細化操做,減少計算量。
四、用多邊形近似邊界。
五、判斷該頂點是否有效。(根據相鄰頂點之間的距離)
轉載請註明出處:http://blog.csdn.net/u010278305
下面給出源代碼:
%function: % 基於最小距離分類器的模板匹配 % 尋找圖片中與已知模板的匹配區域 % 程序中調用了Dilip K. Prasad對Ramer–Douglas–Peucker algorithm的matlab實現 %referrence: % 思路借鑑:http://opencv-code.com/tutorials/detecting-simple-shapes-in-an-image/ % Ramer–Douglas–Peucker algorithm:http://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm %date:2015-1-10 %author:chenyanan %轉載請註明出處:http://blog.csdn.net/u010278305 %清空變量,讀取圖像 clear;close all src = imread('basic_shapes.png'); figure('name','原始圖像'), imshow(src),title('src'), %Convert to grayscale gray=rgb2gray(src); gray = im2double(gray); %Convert to binary image using Canny bw = edge(gray,'canny',[0 , 50/256]); %dilate dilateElement=strel('square', 5); bw=imdilate(bw, dilateElement); %提取每一個連通區域 stats = regionprops(bw, 'Image'); statssize= numel(stats); plotsize=ceil(sqrt(statssize)); figure('name','分離結果'), num=zeros(statssize,1); %算法核心 for i=1:statssize image=stats(i).Image; %進行細化操做 im=bwmorph(image,'thin',Inf); % getting the edge data. edgelist=bwboundaries(im);edgelist=edgelist.'; % calling linefit_Prasad_RDP_opt [edgelist,seglist,precision_list,reliability_list,precision_edge,reliability_edge, time_edge] = linefit_Prasad_RDP_opt(edgelist); boundnum=length(seglist{1}(:,:)); bound=0; sizepic=sum(size(im)); %判斷每一個頂點之間的間距是否符合要求 for j=1:boundnum-1 cornerdiff=seglist{1}(j,:)-seglist{1}(j+1,:); cornerdiff=sqrt(sum(cornerdiff.^2)); if(cornerdiff>0.09*sizepic) bound=bound+1; end end num(i)=bound; %進行繪圖並標識 subplot(plotsize,plotsize,i);imshow(image), if bound<7 title(bound); else title('圓'); end end
源圖像已上傳: