崔 宣,丁 楊,高 文,金世林
(西華大學機械工程與自動化學院, 四川 成都 610039)
在一些機械零部件的生產(chǎn)過程中,焊接起到了十分關鍵的作用,其焊接質(zhì)量對工件的質(zhì)量有非常大的影響[1]。焊縫中出現(xiàn)的夾渣、虛焊、沙孔、疏松甚至偏焊漏焊等缺陷很難完全避免,所以在焊接之后焊縫的探傷工作是不可避免的。探傷需要首先找到準確的焊接部分。在歐美等發(fā)達國家,探傷的研究進行較早,且投入了大量的人力物力[2];而我國基本上采用人工抽樣探傷或者半自動設備探傷,識別錯誤率高、速度慢,探傷的有效性低。為此,本文提出一種基于圖像快速并行細化的焊縫識別方法,以代替人工對焊縫的位置識別,該方法主要是通過圖像快速并行細化算法找到焊接部分的準確位置,并指導檢查設備對其進行檢測,實現(xiàn)自動化。大部分的圖像主要集中在PC環(huán)境中使用matlab實現(xiàn)識別,不利于嵌入式的移植。本文利用C#語言和FreeMat開發(fā),以增強算法的可移植性,使其能夠應用于一些嵌入式平臺,降低自動焊接質(zhì)量檢測設備的價格。
焊縫的圖像識別主要經(jīng)過圖像的獲取、圖像的灰度變換、圖像二值化、圖像的縮放、圖像的細化、圖像的去除噪點、輸出焊縫路徑等處理步驟[3],如圖1所示。
圖1 圖像處理流程圖
圖像轉換主要是將真彩色圖像轉變?yōu)榛叶葓D像。其著名心理學公式[4]為
Gray=R×0.299+G×0.587+B×0.114。
(1)
對于程序的算法來說,式(1)涉及浮點運算,所以編程的效率會非常低。在實際運用中,應盡量避免低速的浮點運算而使用整數(shù)算法。
由于該算法需要32位運算,所以式(1)可變?yōu)榱硪环N形式
Gray=(R×30+G×59+B×11+50)/100。
(2)
對于實際操作來說,式(2)會制約運算速度,所以可以將系數(shù)縮放成 2的整數(shù)冪。習慣上使用16位精度,2的16次冪是65 536,所以系數(shù)的計算為:
0.299×65536=19595.264≈19595;
(3)
0.587×65536+(0.264)=38469.632+0.264=38469.896 38469;
(4)
0.114×65536-(0.896)=7471。
(5)
由于四舍五入會有較大的誤差,所以將以前計算結果的誤差一起計算進去進行舍入,其表達式為
Gray(R×19595+G×38469+B×7472)?16。
(6)
其中
Gray=(R×38+G×75+B×15)?7。
(7)
式(7)使用了16位的位運算,其效率高,并且運算精度高,超過了前面放大100倍的運算精度。
同時式(8)也可以達到相似的效果,且運算量大大減小,所以本文采用之。
Gray=(R×1+G×2+B×1)?2。
(8)
式(8)可以通過位運算優(yōu)化為
Gray=(R+G?1+B)?2。
(9)
式(9)實現(xiàn)了無乘除法的完全移位運算優(yōu)化。
在FreeMat中,由于不支持位運算,所以計算方法依然和普通乘除法相同,在此省略FreeMat的代碼。C#支持位運算,并且位運算相對于乘除法運算有很大的速度優(yōu)勢,其代碼如下。
private static uint RGBtoGray(uint r,uint g,uint b)
{uint res=g<<1;
res+=r+b;
return res>>2;}
在數(shù)字圖像處理中,圖像二值化占有非常重要的地位。該方法是將圖像上的像素點的灰度值設置為0或255,使整個圖像呈現(xiàn)明顯的黑白效果[3,5]。
要進行二值圖像的處理與分析,必須把灰度圖像二值化。圖像的二值化使圖像變得簡單,數(shù)據(jù)量減小,能凸顯出感興趣的目標輪廓。
閾值分割不僅可以大量壓縮數(shù)據(jù),減少儲存容量,而且能夠大大簡化其后的分析和處理步驟。
設原始圖像為f(x,y),在一定的準則下找出一個合適的灰度值作為閾值,按照閾值進行分割后的圖像是g(x,y),可表示為:
(10)
要實現(xiàn)圖像的二值化首先要選擇分割的閾值。常見的方法有雙峰法、迭代法、大津法(即OTSU法)、直接法、固定閾值法,本文使用的是固定閾值法[3]。
經(jīng)過圖像灰度轉換、二值化、圖像分割和膨脹腐蝕等預處理過程后,接下來將對圖像進行快速并行細化處理。
圖2為二值紋理圖像中某一像素點P1的3×3鄰域。設P1為紋理上的一點,其值為1,所有非紋理點取值0。細化過程為逐步迭代過程。在第n次迭代中P1的取值不但取決于P1本身的值,還取決于P1的鄰域點在第(n-1)次迭代后的值。在整個紋理圖像域內(nèi),所有滿足條件的像素點可以同時去掉,并行算法便由此得名[4-7]。
P9P2P3P8P1P4P7P6P5
圖2P1的3×3鄰域
為保證原紋理的連續(xù)性,每次迭代分成2個子迭代。第1次子迭代消去紋理的所有東、南邊界點和西北角的點;第2次子迭代消去西、北邊界點和東南角的點。
在標準的計算過程中每次迭代會標記相應的點,然后在迭代結束后刪除對應的點。迭代條件如表1所示。
表1 細化算法迭代條件
其中A(P1)是按P2,P3,P4,…,P9的排列順序出現(xiàn)0 1(或 1 0)模式的個數(shù),即從P2到P9幾次出現(xiàn)0到1(或1到0)的變化。B(P1)是P1的8鄰接點中非零值的個數(shù)。
B(P1)=P2+P3+P4+…+P9。
(11)
對于條件1,B(P1)=1時,只能出現(xiàn)8種情況之一[4]。顯然,P1是紋線的端點。為保證細化后線條不縮短,甚至被全部吞食,P1必須被保留。當B(P1)=7或B(P1)=8時,為保證消蝕是從外緣逐層向中心骨架進行,并保證細化紋線的定中性和拓撲不變性,P1必須被保留。
條件2保證了細化紋線的連續(xù)性。原始紋線只要有1個像素相連,細化后就不會出現(xiàn)墳線斷裂。假設A(P1)=2,P1顯然是紋線上不能去掉的點,否則將破壞紋線的連續(xù)性。類似的,當A(P1)=3,A(P1)=4時,情況與A(P1)=2的相似,如果去掉P1點就會破壞紋線的連續(xù)性。
對于條件3和4,只有當P4=0或P6=0或P2,P8同時等于0才能同時滿足條件。當P4=0時,則表示P1為紋線的東邊界點,如果去掉P1點,則可去掉整個圖像所有紋線的東邊界點。同理,當P6=0時,表示要去掉所有紋線的南邊界點。當P2,P8同時等于0時,表示要去掉所有紋線的西北角點。
以下為FreeMat實現(xiàn)并行圖像細化算法的過程.
首先需要判斷當前點是否為前景點,若為背景點則不需要處理,細化時只是細化前景點。
if( false == tempin.getxy( tx, ty ) )
continue.
接著將當前點和8鄰域的各個點按照順序排列到數(shù)組中,用于存儲數(shù)據(jù)。通過對數(shù)據(jù)儲存,可以方便調(diào)試時觀察數(shù)據(jù)的正誤,以及后續(xù)的運算過程的處理。
//初始化8個鄰域數(shù)據(jù)點
bool pt[9];
pt[0] = tempin.getxy( tx, ty );
pt[1] = tempin.getxy( tx, ty - 1 );
pt[2] = tempin.getxy( tx + 1, ty - 1 );
pt[3] = tempin.getxy( tx + 1, ty );
pt[4] = tempin.getxy( tx + 1, ty + 1 );
pt[5] = tempin.getxy( tx, ty + 1 );
pt[6] = tempin.getxy( tx - 1, ty + 1 );
pt[7] = tempin.getxy( tx - 1, ty );
pt[8] = tempin.getxy( tx - 1, ty - 1 ).
根據(jù)前文中對細化算法的說明可知,對于這9個點的順序并不是任意分布,所以要按照順序排布這9個點。排布好以后,通過數(shù)組索引來代替直接使用坐標讀取數(shù)據(jù)。
判斷這幾個領域點的狀況,如果8鄰域中的8個點有6個及以上的點為前景時,視此點為內(nèi)部點;如果僅有1個點是前景點時,則此點為孤立點。通過計算鄰域點的數(shù)目,從而判斷原坐標點為內(nèi)部點或孤立點的情況。
int tcount = 0;
for( int tt = 1; tt < 9; tt++ )
{if( true == pt[tt] )
tcount++;}
if( tcount < 2 || tcount > 6 )
continue.
經(jīng)過對內(nèi)部點和孤立點的判斷以后,如果不是內(nèi)部點和孤立點的話,程序會繼續(xù)執(zhí)行,然后需要判斷8鄰域的分支數(shù)量,如果分支數(shù)量為1,則視此點在圖像內(nèi)容的邊界上,可以對此點進行消除。
int tcount2 = 0;
for( int tt = 1; tt < 8; tt++ )
{if( true == pt[tt] && false == pt[tt+1] )
tcount2++;}
if( true == pt[8] && false == pt[1] )
tcount2++;
if( tcount2 != 1 )
continue.
接下來對右方和下方的像素點進行判斷。如果滿足條件,則刪除此點;否則跳過這個循環(huán)。
bool tempb1 = false; bool tempb2 = false;
tempb1 = pt[5] && pt [7] && pt[1];
tempb2 = pt[5] && pt [3] && pt[7];
if( true == tempb1 || true == tempb2 )
{continue;}
如果以上條件均滿足,則沒有跳出這循環(huán),直接進行刪除點操作,并記錄標記。
temp.setxy( tx, ty, true );
modified = true;
counter++.
以上過程完成了一個方向上的操作,在另外一個方向上,基本流程都一樣,大部分語句都是相似的,主要的區(qū)別在于對點的條件判斷進行了修改,對圖2中P1點左方的像素點和上方像素點進行判斷。
bool tempb1 = false; bool tempb2 = false;
tempb1 = pt[5] && pt [7] && pt[1];
tempb2 = pt[5] && pt [3] && pt[7];
if( true == tempb1 || true == tempb2 )
{continue;}
本文對焊縫圖像的2種情況進行實驗:一種是直接采用焊縫圖像進行處理如圖3所示;另一種是對圖像加上椒鹽噪點后再進行處理,以檢查圖像的抗噪能力如圖4所示。首先讀取原始圖像,對圖像進行灰度變換,通過位運算優(yōu)化后,在C#中的執(zhí)行效率有一定的提升;然后對灰度圖像進行縮小變化,其目的是固定處理圖像的大小,確定處理的時間。其算法過程為:讀入原圖,計算出該圖的尺寸大小,通過縮放比例得到目標圖像尺寸大小;掃描X軸和Y軸方向像素點,對每個目標圖像坐標(u,v),利用近鄰取樣法在原圖中找到模塊中心位置(i,j);進行雙線性插值,并對X方向和Y方向遞推實現(xiàn)圖像縮小;利用公式temp=temp+grayimg(u,v)進行遞推,得到最終縮小的圖像scaleimg(i,j)。
(a)原始圖像
(b)灰度圖像
(c)縮小圖像
(d)二值化圖像
(e)細化后圖像
此方法相對于臨近取樣法有更好的圖像效果,但是運算速度相對較低,適合一些小規(guī)模的數(shù)據(jù)。由于處理的是固定大小的圖像,這種縮放方法的運算量是一常量,所以這種方法是合理的。
在圖像二值化后,圖4(d)中的焊縫占有幾個像素寬度,但通過細化處理以后都變成了一個像素寬度的點,這說明圖像細化方法有一定的缺點,在有些特殊情況的地方會出現(xiàn)一個像素的斷點。解決這個問題的方法是通過其他細化算法得到更加精確的沒有斷點的圖像;但是對于焊縫的軌跡來說,由于焊縫都是比較長的直線,若是出現(xiàn)了一個像素的斷點,可以通過后期的軟件插補出對應的直線軌跡,所以這種斷點對于實際應用來說幾乎是沒有影響的。在圖4焊縫加噪點處理過程中,原始圖像被人為添加了椒鹽噪點,圖像本身受到很大影響,通過縮小方法后依然有許多噪點,通過圖像二值化以后,噪點依然存在。
(a)加噪點圖像
(b)灰度圖像
(c)縮小圖像
(d)二值化圖像
(e)細化后圖像
圖4 情況2加噪點的處理過程
當圖像細化和去噪點完成后,圖像的焊縫骨架非常完好地保存了下來,噪點基本上被完全去除;但是在焊縫骨架線條上方依然有一個短線條沒有被去除,這是因為圖像本身在骨架上方存在由于采集圖像時留下的一片黑色區(qū)域。這同樣可以通過后期路徑插補的運算消除。
實驗結果表明:本文的處理方法對圖像的焊縫骨架提取較為精確,并且能夠保持很好的拓撲結構,執(zhí)行周期少,灰度變換的效率較高,程序執(zhí)行時間短;對加了椒鹽噪點圖像也能夠很好的處理,達到了較好的去除噪點的效果。由于程序代碼在C#語言和FreeMat語言環(huán)境中都測試通過,所以該算法具有一定的可移植性。
[1]續(xù)晉華.用于石油鋼管螺旋焊機外焊縫自動跟蹤的視覺系統(tǒng)[D].西安:西安交通大學,1991.
[2]Rafael C Gonzalez,Richard E Woods.數(shù)字圖像處理[M].2版. 阮秋琦,譯.北京:電子工業(yè)出版社,2007:192-209.
[3]劉海波,沈晶,郭聳,等.Visual C++數(shù)字圖像處理技術詳解[M].北京:機械工業(yè)出版社,2010:158-172.
[4]嚴玉龍,王厚樞. 快速并行細化算法[J]. 南京航空學院學報,1991(1):136-140.
[5]王云. 焊縫圖像處理的匹配算法研究[D]. 杭州:浙江工業(yè)大學, 2012.
[6]曲興田,王濱,張雷,等. 焊縫磨拋圖像預處理技術[J]. Issue,2012 (6): 1421-1425 .
[7]俞博,陳守強,王雙一,等.基于手指角度特征的靜態(tài)手勢識別算法[J].西華大學學報:自然科學版,2014,33(1):69-71.