基于OpenCV的焊件缺陷檢測
共 8105字,需瀏覽 17分鐘
·
2024-07-14 10:05
點擊上方“小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時間送達
圖像分割是指將圖像劃分為包含相似屬性的不同像素區(qū)域。為了對圖像分析和解釋,劃分的區(qū)域應(yīng)與對象特征密切相關(guān)。圖像分析的成功取決于分割的可靠性,但是圖像的正確分割通常是一個非常具有挑戰(zhàn)性的問題。
圖像中心距是圖像像素強度的某個特定加權(quán)平均值。圖像矩可用于描述分割后的對象。通過圖像瞬間發(fā)現(xiàn)的圖像簡單屬性包括:
面積(或總強度)
質(zhì)心
-
有關(guān)其方向的信息
該數(shù)據(jù)集包含兩個目錄。原始圖像存儲在“圖像”目錄中,分割后的圖像存儲在“標(biāo)簽”目錄中。讓我們來看看這些數(shù)據(jù):原始圖像是RGB圖像,用于訓(xùn)練模型和測試模型。這些圖片的尺寸各不相同。直觀地,較暗的部分是焊接缺陷。模型需要對這些圖像執(zhí)行圖像分割。
“標(biāo)簽”目錄的圖像是二進制圖像或地面真相標(biāo)簽。這是我們的模型必須針對給定的原始圖像進行預(yù)測。在二進制圖像中,像素具有“高”值或“低”值。白色區(qū)域或“高”值表示缺陷區(qū)域,而黑色區(qū)域或“低”值表示無缺陷。
我們將使用U-Net來解決這個問題,通過以下三個主要步驟來檢測缺陷及其嚴(yán)重性:
圖像分割
使用顏色顯示嚴(yán)重性
使用圖像矩測量嚴(yán)重性
訓(xùn)練模型
使用的U-Net架構(gòu)
注意事項:
每個藍色框?qū)?yīng)一個多通道特征圖
通道數(shù)顯示在框的頂部。
(x,y)尺寸位于框的左下邊緣。
箭頭表示不同的操作。
圖層名稱位于圖層下方。
C1,C2,...。C7是卷積運算后的輸出層
P1,P2,P3是最大池化操作的輸出層
U1,U2,U3是上采樣操作的輸出層
A1,A2,A3是跳過連接。
左側(cè)是收縮路徑,其中應(yīng)用了常規(guī)卷積和最大池化操作
圖像尺寸逐漸減小,而深度逐漸增大。
右側(cè)是擴展路徑,在其中應(yīng)用了(向上采樣)轉(zhuǎn)置卷積和常規(guī)卷積運算
在擴展路徑中,圖像尺寸逐漸增大,深度逐漸減小
為了獲得更好的精確位置,在擴展的每個步驟中,我們都使用跳過連接,方法是將轉(zhuǎn)置卷積層的輸出與來自編碼器的特征圖在同一級別上連接:
A1 = U1 + C3
A2 = U2 + C2
A3 = U3 + C1
每次串聯(lián)后,我們再次應(yīng)用規(guī)則卷積,以便模型可以學(xué)習(xí)組裝更精確的輸出。
import numpy as npimport cv2import osimport randomimport tensorflow as tf= 512,512def create_model():inputs = tf.keras.layers.Input(shape=(h,w,3))conv1 = tf.keras.layers.Conv2D(16,(3,3),activation='relu',padding='same')(inputs)pool1 = tf.keras.layers.MaxPool2D()(conv1)conv2 = tf.keras.layers.Conv2D(32,(3,3),activation='relu',padding='same')(pool1)pool2 = tf.keras.layers.MaxPool2D()(conv2)conv3 = tf.keras.layers.Conv2D(64,(3,3),activation='relu',padding='same')(pool2)pool3 = tf.keras.layers.MaxPool2D()(conv3)conv4 = tf.keras.layers.Conv2D(64,(3,3),activation='relu',padding='same')(pool3)upsm5 = tf.keras.layers.UpSampling2D()(conv4)upad5 = tf.keras.layers.Add()([conv3,upsm5])conv5 = tf.keras.layers.Conv2D(32,(3,3),activation='relu',padding='same')(upad5)upsm6 = tf.keras.layers.UpSampling2D()(conv5)upad6 = tf.keras.layers.Add()([conv2,upsm6])conv6 = tf.keras.layers.Conv2D(16,(3,3),activation='relu',padding='same')(upad6)upsm7 = tf.keras.layers.UpSampling2D()(conv6)upad7 = tf.keras.layers.Add()([conv1,upsm7])conv7 = tf.keras.layers.Conv2D(1,(3,3),activation='relu',padding='same')(upad7)model = tf.keras.models.Model(inputs=inputs, outputs=conv7)return modelimages = []labels = []files = os.listdir('./dataset/images/')random.shuffle(files)for f in files:img = cv2.imread('./dataset/images/' + f)parts = f.split('_')label_name = './dataset/labels/' + 'W0002_' + parts[1]label = cv2.imread(label_name,2)img = cv2.resize(img,(w,h))label = cv2.resize(label,(w,h))images.append(img)labels.append(label)images = np.array(images)labels = np.array(labels)labels = np.reshape(labels,(labels.shape[0],labels.shape[1],labels.shape[2],1))print(images.shape)print(labels.shape)images = images/255labels = labels/255model = tf.keras.models.load_model('my_model')#model = create_model() # uncomment this to create a new modelprint(model.summary())='adam', loss='binary_crossentropy',metrics=['accuracy'])=100,batch_size=10)model.evaluate(images,labels)model.save('my_model')
測試模型
import numpy as npimport cv2from google.colab.patches import cv2_imshowimport osimport randomimport tensorflow as tf= 512,512num_cases = 10images = []labels = []files = os.listdir('./dataset/images/')random.shuffle(files)model = tf.keras.models.load_model('my_model')lowSevere = 1midSevere = 2highSevere = 4for f in files[0:num_cases]:test_img = cv2.imread('./dataset/images/' + f)resized_img = cv2.resize(test_img,(w,h))resized_img = resized_img/255cropped_img = np.reshape(resized_img,(1,resized_img.shape[0],resized_img.shape[1],resized_img.shape[2]))test_out = model.predict(cropped_img)test_out = test_out[0,:,:,0]*1000test_out = np.clip(test_out,0,255)resized_test_out = cv2.resize(test_out,(test_img.shape[1],test_img.shape[0]))resized_test_out = resized_test_out.astype(np.uint16)test_img = test_img.astype(np.uint16)grey = cv2.cvtColor(test_img, cv2.COLOR_BGR2GRAY)for i in range(test_img.shape[0]):for j in range(test_img.shape[1]):& resized_test_out[i,j]>40):=test_img[i,j,1] + resized_test_out[i,j]= lowSevere& resized_test_out[i,j]>40):=test_img[i,j,2] + resized_test_out[i,j]= highSevere:=test_img[i,j,0] + resized_test_out[i,j]= midSevereelse:= 0M = cv2.moments(resized_test_out)maxMomentArea = resized_test_out.shape[1]*resized_test_out.shape[0]*highSevereMoment = " , (M["m00"]*100/maxMomentArea), "%")test_img = np.clip(test_img,0,255)test_img = test_img.astype(np.uint8)cv2_imshow(test_img)cv2.waitKey(0)
我們使用顏色來表示缺陷的嚴(yán)重程度:
綠色表示存在嚴(yán)重缺陷的區(qū)域。
藍色表示缺陷更嚴(yán)重的區(qū)域。
紅色區(qū)域顯示出最嚴(yán)重的缺陷。
以下是三個隨機樣本,它們顯示了原始輸入,地面真實情況以及由我們的模型生成的輸出。
范例1:
原始圖像
二進制圖像(地面真相)
范例2:
原始圖像
二進制圖像(地面真相)
范例3:
原始圖像
二進制圖像(地面真相)
具有嚴(yán)重性的預(yù)測輸出
參考文獻:
https://www.cs.auckland.ac.nz/courses/compsci773s1c/lectures/ImageProcessing-html/topic3.htm#adaptive
https://medium.com/r/?url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FImage_moment
https://medium.com/r/?url=https%3A%2F%2Ftowardsdatascience.com%2Funderstanding-semantic-segmentation-with-unet-6be4f42d4b47
https://www.sciencedirect.com/topics/materials-science/welding-defect
代碼鏈接:https://github.com/malakar-soham/cnn-in-welding
下載1:OpenCV-Contrib擴展模塊中文版教程
在「小白學(xué)視覺」公眾號后臺回復(fù):擴展模塊中文教程,即可下載全網(wǎng)第一份OpenCV擴展模塊教程中文版,涵蓋擴展模塊安裝、SFM算法、立體視覺、目標(biāo)跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。
下載2:Python視覺實戰(zhàn)項目52講 在「小白學(xué)視覺」公眾號后臺回復(fù):Python視覺實戰(zhàn)項目,即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計數(shù)、添加眼線、車牌識別、字符識別、情緒檢測、文本內(nèi)容提取、面部識別等31個視覺實戰(zhàn)項目,助力快速學(xué)校計算機視覺。
下載3:OpenCV實戰(zhàn)項目20講 在「小白學(xué)視覺」公眾號后臺回復(fù):OpenCV實戰(zhàn)項目20講,即可下載含有20個基于OpenCV實現(xiàn)20個實戰(zhàn)項目,實現(xiàn)OpenCV學(xué)習(xí)進階。
交流群
歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會逐漸細(xì)分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~
