利用openCV或其他工具編寫程序實現對多個產品圖片進行缺陷檢測並判斷產品是否合格。
實現過程
1、編寫程序
目標圖片如下
根據展示的程序功能編寫對應的程序:
第一步,讀取顯示圖像的功能openCV已經提供了函數imread()和imshow(),這一次實驗的讀取圖片與前幾次實驗有些許不同,首先我們需要先讀取一張合格產品圖片作為樣本,然后再讀取所有圖片並將其與樣本進行比較來完成檢測缺陷的功能,代碼如下
#-*- coding: utf-8 -*-
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image, ImageDraw, ImageFont
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"C:\Windows\Fonts\simhei.ttf", size=14)
font1 = ImageFont.truetype("C:\Windows\Fonts\simhei.ttf", 20, encoding="utf-8")
#樣本圖片
img_orgin=cv.imread('0.bmp')
#多張產品圖片的讀取
for i in range(6):
img=cv.imread('{}.bmp'.format(i))
第二步,為了對兩張圖進行比較與匹配,這里我們需要用到直方圖來完成這一功能,首先需要繪制每張圖的直方圖:
def create_rgb_hist(image):
h, w, c = image.shape
# 創建一個(16*16*16,1)的初始矩陣,作為直方圖矩陣
# 16*16*16的意思為三通道每通道有16個bins
rgbhist = np.zeros([16 * 16 * 16, 1], np.float32)
bsize = 256 / 16
for row in range(h):
for col in range(w):
b = image[row, col, 0]
g = image[row, col, 1]
r = image[row, col, 2]
# 人為構建直方圖矩陣的索引,該索引是通過每一個像素點的三通道值進行構建
index = int(b / bsize) * 16 * 16 + int(g / bsize) * 16 + int(r / bsize)
# 該處形成的矩陣即為直方圖矩陣
rgbhist[int(index), 0] += 1
return rgbhist
第三步,編寫比較兩張圖片的函數,這里就需要用到第二步所編寫的直方圖繪制函數:
def hist_compare(img1,img2):
hist1 = create_rgb_hist(img1)
# 創建第二幅圖的rgb三通道直方圖(直方圖矩陣)
hist2 = create_rgb_hist(img2)
match = cv.compareHist(hist1, hist2, cv.HISTCMP_CORREL)
#通過四舍五入拉開相關性值的差
result='{:.1f}'.format(match)
#檢查相關值與返回值
print(match,result)
return result
第四步,比較相關值來判斷產品是否合格,並在圖像上輸出合格、不合格的文本信息:
#str1='不合格' str2='合格'
img=cv.imread('{}.bmp'.format(i))
blur1=cv.cvtColor(img,cv.COLOR_BGR2RGB)
pilblur=Image.fromarray(blur1)
draw=ImageDraw.Draw(pilblur)
result=hist_compare(img_orgin,img)
if result!='1.0':
draw.text((5, 5), str1, (255, 0, 0), font=font1)
blurtext=cv.cvtColor(np.array(pilblur),cv.COLOR_RGB2BGR)
cv.imshow('buhege',blurtext)
cv.waitKey(0)
else:
draw.text((5, 5), str2, (255, 0, 0), font=font1)
blurtext=cv.cvtColor(np.array(pilblur),cv.COLOR_RGB2BGR)
cv.imshow('hege',blurtext)
cv.waitKey(0)
運行結果
問題及解決方法
1、圖片的匹配
存在的問題:在剛看到產品的缺陷檢測問題時,我首先想到的就是對圖像進行像素點比較而忽略了老師所講的直方圖,而在進行像素點比較時卻出現了問題,圖像0作為合格樣本與圖像1進行比較發現輸出的結果顯示圖像1為不合格產品,后來想到圖像中的產品旋轉的問題,又將圖片的每個像素點的值加起來求平均值並於樣本的平均值進行比較,這時的問題就是求出的值過大,對於產品的合格線不好界定。
解決方法:在我陷入如何縮小平均值的同時不影響結果的問題並上網搜索解決方案時,看到了直方圖的繪制,同時也找到了使用直方圖對圖像進行簡單匹配的方法。那就是使用直方圖比較函數cv2.compareHist(H1,H2,method),比較方式我選用的相關性比較,這個比較方式取值會更容易。使用相關性比較得到的值越大,相關性越高,最大值為1,最小值為0 。
實驗總結
這一次的實驗看代碼行數似乎很簡單,因為它只有短短十幾行,但這次實驗引入了一個新的概念,也就是圖像直方圖。圖像直方圖是反映一個圖像像素分布的統計表,其橫坐標代表了圖像像素的種類,縱坐標代表了每一種顏色值在圖像中的像素總數或者占所有像素個數的百分比。在實際應用中,圖像直方圖在特征提取、圖像匹配等方面都有很好的應用。
在我看來,直方圖的使用、如何運用直方圖來解決問題是這次實驗的重點。