1 圖像的二值化的基本原理
圖像的二值化處理就是講圖像上的點的灰度置爲0或255,也就是講整個圖像呈現出明顯的黑白效果。即將256個亮度等級的灰度圖像經過適當的閥值選取而得到仍然能夠反映圖像總體和局部特徵的二值化圖像。在數字圖像處理中,二值圖像佔有很是重要的地位,特別是在實用的圖像處理中,以二值圖像處理實現而構成的系統是不少的,要進行二值圖像的處理與分析,首先要把灰度圖像二值化,獲得二值化圖像,這樣子有利於再對圖像作進一步處理時,圖像的集合性質只與像素值爲0或255的點的位置有關,再也不涉及像素的多級值,使處理變得簡單,並且數據的處理和壓縮量小。爲了獲得理想的二值圖像,通常採用封閉、連通的邊界定義不交疊的區域。全部灰度大於或等於閥值的像素被斷定爲屬於特定物體,其灰度值爲255表示,不然這些像素點被排除在物體區域之外,灰度值爲0,表示背景或者例外的物體區域。若是某特定物體在內部有均勻一致的灰度值,而且其處在一個具備其餘等級灰度值的均勻背景下,使用閥值法就能夠獲得比較的分割效果。若是物體同背景的差異表現不在灰度值上(好比紋理不一樣),能夠將這個差異特徵轉換爲灰度的差異,而後利用閥值選取技術來分割該圖像。動態調節閥值實現圖像的二值化可動態觀察其分割圖像的具體結果。算法
二值化是圖像分割的一種方法。在二值化圖象的時候把大於某個臨界灰度值的像素灰度設爲灰度極大值,把小於這個值的像素灰度設爲灰度極小值,從而實現二值化。
根據閾值選取的不一樣,二值化的算法分爲固定閾值和自適應閾值。 比較經常使用的二值化方法則有:雙峯法、P參數法、迭代法和OTSU法等。數組
clc; close all; %啓動定時器,測試軟件性能 [filename,filepath]=uigetfile('*.jpg','打開文件');%gui中打開文件 filep=strcat(filepath,filename); %filep Image=imread(filep); tic; %讀取圖像並二值化 % Image = imread('0081.jpg'); level = graythresh(Image); %獲取圖像二值化的閾值 bw = im2bw(Image,level); %二值化處理 imshow(bw); t = 1; p = 1; [m n] = size(bw); %初步計數黑白條的書目 q = round(m/2); for i=q for j=1:n-1 if bw(i,j)==0&&bw(i,j+1)==1%顏色變化由黑色變成白色,黑條 x(t) = j; t = t+1; end end end for i=q for j=1:n-1 if bw(i,j)==1&&bw(i,j+1)==0 %顏色變化由白色變成黑色,白條 y(p) = j; p = p+1; end end end pin = 0; while length(x)~=30||length(y)~=30 %%等待提示信息 if pin ==0 display('正在掃碼,請對準而條形碼............'); end pin = pin+1; %條形碼有損壞是逐行掃描 for pp=q:round(5*m/6) t=1; p=1; if length(x)==30&&length(y)==30 %經過判斷黑白條數測試當前行有無算壞 break; end for i=pp for j=1:n-1 if bw(i,j)==0&&bw(i,j+1)==1 x(t) = j; t = t+1; end end end for i=pp for j=1:n-1 if bw(i,j)==1&&bw(i,j+1)==0 y(p) = j; p = p+1; end end end end end if length(x)~=30||length(y)~=30 display('掃碼錯誤!'); return; end if i~=round(m/2) display('該條形碼已受損,但仍然能夠正常掃描'); end %計算每一個條—空的寬度,利用所記錄在xy數組中的座標值,對應相減 for ii=1:30 if ii==1 d(ii)=x(ii)-y(ii); %計算第一個條的寬度 d(ii+1)=y(ii+1)-x(ii); %計算第一個空的寬度 end if ii>1 if ii>1&&ii<30 d(2*ii) = y(ii+1)-x(ii); %分別計算第2~29個空的寬度 d(2*ii-1)=x(ii)-y(ii); %分別計算第2~29個條的寬度 elseif ii==30 d(ii*2-1)=x(ii)-y(ii); %總共有59個條-空,單獨計算第三十個條的寬度 end end end j = 3; for i=1:6 r(i)=(d(j+1)+d(j+2)+d(j+3)+d(j+4))/7; %計算左邊六個字的基準碼的寬度 end j=32; for i=7:12 r(i)=(d(j+1)+d(j+2)+d(j+3)+d(j+4))/7; %計算右邊五個字的基準碼的寬度 end n=0;%四字計數 i=1; j1=1; j=4;%跳過起始符,從左邊第一個開始讀碼 flag0=0;%做爲標識符,將樣條交替翻譯成1或者0 while j<=56 if n==4 n=0; i=i+1; end if d(j)<0.5*r(i)%小於0.5捨去 return; elseif d(j)<1.5*r(i)&&d(j)>0.5*r(i)%0.5~1.5記爲1個值 if flag0==0 bs(j1)={'0'};%對於的被譯碼 else bs(j1)={'1'}; end j1=j1+1; elseif (d(j)>=1.5*r(i))&&(d(j)<2.5*r(i))%1.5~2.5記爲2個值 if flag0==0 bs(j1)={'00'}; else bs(j1)={'11'}; end j1=j1+1; elseif (d(j)>=2.5*r(i))&&(d(j)<3.5*r(i))%2.5~3.5記爲3個值 if flag0==0 bs(j1)={'000'}; else bs(j1)={'111'}; end j1=j1+1; elseif (d(j)>=3.5*r(i))&&(d(j)<4.5*r(i))%3.5~4.5記爲4個值 if flag0==0 bs(j1)={'0000'}; else bs(j1)={'1111'}; end j1=j1+1; else return; end n=n+1; if flag0==0 flag0=1; else flag0=0; end
版本:2014amarkdown