1. 前言
Python是目前最火热的编程语言之一,而OpenCV是最常见的计算机视觉库。在这篇文章中,我们将使用Python中的OpenCV库来实现图片缺陷检测。对于工业生产线上的生产质量控制、车辆出厂检测、电子元器件生产检测等应用场景,都需要进行缺陷检测,因此这是一个非常有价值的方向。在介绍具体实现方法之前,我们需要先了解一些相关的基础知识。
2. 直方图
2.1 什么是直方图
直方图是用于表示(分布)性质的一种统计图表,是由一系列高度不等的纵向条纹表示数据分布情况的图表。在图像处理中,直方图是一种可以用来显示图像灰度级分布情况的工具。
2.2 直方图的用途
直方图在图像处理中有许多用途,主要包括以下三种:
了解图像的灰度分布
图像增强
图像分割
2.3 如何计算直方图
在OpenCV库中,可以通过cv2.calcHist()函数来计算直方图。这个函数的参数很多,主要包括图像、通道、掩膜、直方图大小、直方图范围等。我们可以通过下面的代码来计算一张图像的直方图:
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image.jpg', 0)
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
plt.plot(hist)
plt.show()
上面的代码中,首先我们使用cv2.imread()函数来读取一张图片,然后使用cv2.calcHist()函数计算图像的直方图,最后使用matplotlib库来画出直方图。运行代码可以得到如下的图像:
从以上的图像可以看出,我们的算法并没有很好地展现出直方图,我们需要通过对直方图的进一步处理,来让图像更好地呈现。
3. 相似度
3.1 什么是相似度
相似度是用来衡量两个东西在多大程度上相似的一个指标。在计算机视觉中,相似度被广泛用于图像、视频、音频等多媒体信息的查找和识别。
3.2 相似度的计算方法
对于两个物体的相似度,我们通常会使用特征向量来表示。特征向量可以使用多种多样的特征来构造,例如颜色、形状、纹理、亮度等。在这里,我们使用图像的直方图来构造特征向量,进而计算图片之间的相似度。
对于两张图片A和B,我们可以先计算它们的直方图,然后计算它们直方图之间的距离。距离越小,说明两张图片相似度越高。在实际应用中,我们通常使用欧几里得距离(Euclidean distance)或余弦相似度(Cosine similarity)来计算图片之间的相似度。
欧几里得距离表示两点之间的直线距离。在图像处理中,我们通常会对两张图片的直方图进行归一化处理,然后对它们的直方图进行L2距离计算。公式如下:
其中,histA和histB分别表示图片A和B的直方图向量,L2表示欧几里得距离。
余弦相似度可以衡量两个向量的相似度,公式如下:
其中,histA和histB分别表示图片A和B的直方图向量。
4. 图像缺陷检测
4.1 缺陷检测的流程
在我们了解了直方图和相似度的基础知识之后,现在让我们来看看如何使用它们来实现图片缺陷检测。
我们可以分为以下几个步骤来完成图片缺陷检测的任务:
读取原始图片
设置模板窗口大小
计算原始图片和模板的直方图
滑动窗口,计算不同位置的相似度
输出缺陷检测结果
4.2 代码实现
接下来,让我们看看如何使用Python的OpenCV库实现图片缺陷检测。这里我们将会使用CV2库实现图片缺陷检测。
我们首先需要导入CV2库和NumPy库:
import cv2
import numpy as np
然后我们需要定义一个函数,用来计算两张图片的相似度。我们这里使用cosine similarity来计算相似度:
def cos_criterion(hist1, hist2):
# 计算两张图片的余弦相似度
simi = np.dot(hist1, hist2) / (np.linalg.norm(hist1) * np.linalg.norm(hist2))
return simi
接下来我们来定义缺陷检测函数:
def defect_detect(img_path, template_path, window_size, threshold):
# 读取原始图片
img = cv2.imread(img_path)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 读取模板
template = cv2.imread(template_path)
template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
# 调整模板大小
template_resize = cv2.resize(template_gray, (window_size, window_size))
# 计算直方图
hist_temp = cv2.calcHist([template_resize], [0], None, [256], [0, 256])
hist_temp = cv2.normalize(hist_temp, hist_temp)
# 滑动窗口计算相似度
height, width = img_gray.shape[:2]
step = 10 # 步长
max_similarity = 0 # 最大相似度
pos = (0, 0) # 缺陷位置
for y in range(0, height - window_size + 1, step):
for x in range(0, width - window_size + 1, step):
# 计算直方图
hist_img = cv2.calcHist([img_gray[y:y + window_size, x:x + window_size]], [0], None, [256], [0, 256])
hist_img = cv2.normalize(hist_img, hist_img)
# 计算相似度
similarity = cos_criterion(hist_temp, hist_img)
# 更新最大相似度和缺陷位置
if similarity > max_similarity:
max_similarity = similarity
pos = (x, y)
# 输出结果
if max_similarity > threshold:
print('存在缺陷,缺陷位置为:', pos)
else:
print('不存在缺陷')
代码说明:
第2行:定义计算相似度的函数。
第4行:定义缺陷检测函数。
第6行:读取原始图片。
第7行:将原始图片转换成灰度图像。
第9行:读取模板。
第10行:将模板转换成灰度图像。
第13行:调整模板大小。
第16~18行:计算模板的直方图并进行归一化处理。
第21~32行:遍历原始图片,计算不同位置的相似度。在计算相似度之前,我们需要先计算当前区域的直方图。然后我们计算当前区域的相似度,并更新最大相似度以及对应的缺陷位置。
第35~38行:输出缺陷检测结果。
现在,我们可以使用上面的函数来对图片进行缺陷检测。下面是一段简单的测试代码:
img_path = 'test_image.jpg'
template_path = 'template.jpg'
window_size = 50
threshold = 0.7 # 相似度阈值
defect_detect(img_path, template_path, window_size, threshold)
代码说明:
第1~2行:定义测试用的图片和模板路径。
第3行:设置滑动窗口的大小。
第4行:设置相似度的阈值。若相似度超过该阈值,则认为存在缺陷。
第6行:调用缺陷检测函数,并传入参数。运行程序可以得到缺陷检测结果。
5. 总结
本篇文章介绍了如何使用Python的OpenCV库来实现图片缺陷检测。我们了解了直方图和相似度的基础知识,并使用它们来构建缺陷检测算法。在实际应用中,我们可以将缺陷检测算法与生产线、车辆出厂检测、电子元器件生产检测等结合使用,实现智能化的生产质量控制,提高生产效率。