本实验基于OpenCV进行机器视觉入门的学习,并利用OpenCV进行零件瑕疵检测。

实验步骤:

  1. 安装OpenCV

首先需要安装OpenCV,可以通过以下命令在Linux系统中安装:

sudo apt-get install libopencv-dev python-opencv
  1. 准备数据集

本实验使用的是一个零件瑕疵数据集,包含正常零件和瑕疵零件各100张。可以从以下链接下载数据集:

https://pan.baidu.com/s/1BfBjMgY1UcIHUvqfuYbQVw

  1. 数据预处理

将数据集分为训练集和测试集,并将图片转换成灰度图。代码如下:

import cv2
import os

# 数据集路径
dataset_path = './dataset'

# 保存训练集和测试集的路径
train_path = './train'
test_path = './test'

# 如果文件夹不存在,则创建
if not os.path.exists(train_path):
    os.makedirs(train_path)
if not os.path.exists(test_path):
    os.makedirs(test_path)

# 将数据集分为训练集和测试集
for label in os.listdir(dataset_path):
    label_path = os.path.join(dataset_path, label)
    train_label_path = os.path.join(train_path, label)
    test_label_path = os.path.join(test_path, label)
    if not os.path.exists(train_label_path):
        os.makedirs(train_label_path)
    if not os.path.exists(test_label_path):
        os.makedirs(test_label_path)
    count = 0
    for img_name in os.listdir(label_path):
        img_path = os.path.join(label_path, img_name)
        img = cv2.imread(img_path)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转换为灰度图
        if count < 80:
            save_path = os.path.join(train_label_path, img_name)
        else:
            save_path = os.path.join(test_label_path, img_name)
        cv2.imwrite(save_path, img)
        count += 1
  1. 特征提取

使用SIFT算法进行特征提取,并保存到文件中。代码如下:

import cv2
import os

# 训练集和测试集路径
train_path = './train'
test_path = './test'

# SIFT特征提取器
sift = cv2.xfeatures2d.SIFT_create()

# 保存特征的文件
train_feature_file = 'train_features.txt'
test_feature_file = 'test_features.txt'

# 提取训练集特征
f_train = open(train_feature_file, 'w')
for label in os.listdir(train_path):
    label_path = os.path.join(train_path, label)
    for img_name in os.listdir(label_path):
        img_path = os.path.join(label_path, img_name)
        img = cv2.imread(img_path)
        kp, des = sift.detectAndCompute(img, None)
        des_str = ' '.join([str(d) for d in des.flatten()])
        line = '{} {}\n'.format(label, des_str)
        f_train.write(line)
f_train.close()

# 提取测试集特征
f_test = open(test_feature_file, 'w')
for label in os.listdir(test_path):
    label_path = os.path.join(test_path, label)
    for img_name in os.listdir(label_path):
        img_path = os.path.join(label_path, img_name)
        img = cv2.imread(img_path)
        kp, des = sift.detectAndCompute(img, None)
        des_str = ' '.join([str(d) for d in des.flatten()])
        line = '{} {}\n'.format(label, des_str)
        f_test.write(line)
f_test.close()
  1. 训练模型

使用SVM模型进行训练,并保存模型到文件中。代码如下:

import cv2
import os
import numpy as np
from sklearn.svm import SVC

# 特征文件
train_feature_file = 'train_features.txt'
test_feature_file = 'test_features.txt'

# 读取训练集和测试集特征
train_features = []
train_labels = []
f_train = open(train_feature_file, 'r')
for line in f_train.readlines():
    parts = line.strip().split()
    label = parts[0]
    des = np.array(list(map(float, parts[1:])))
    train_features.append(des)
    train_labels.append(int(label))
f_train.close()

test_features = []
test_labels = []
f_test = open(test_feature_file, 'r')
for line in f_test.readlines():
    parts = line.strip().split()
    label = parts[0]
    des = np.array(list(map(float, parts[1:])))
    test_features.append(des)
    test_labels.append(int(label))
f_test.close()

# 训练SVM模型
svm = SVC(kernel='linear', C=1.0, probability=True)
svm.fit(train_features, train_labels)

# 预测测试集
test_pred = svm.predict(test_features)
test_prob = svm.predict_proba(test_features)

# 输出准确率
accuracy = np.mean(test_pred == test_labels)
print('Accuracy: {:.2f}%'.format(accuracy * 100))

# 保存模型
model_file = 'svm.model'
cv2.ml.SVM_create().save(model_file)
  1. 检测瑕疵

使用训练好的模型对新的零件图像进行瑕疵检测。代码如下:

import cv2
import numpy as np

# 模型文件
model_file = 'svm.model'

# SIFT特征提取器
sift = cv2.xfeatures2d.SIFT_create()

# 加载SVM模型
svm = cv2.ml.SVM_load(model_file)

# 待检测图像路径
img_path = './test/0/01.jpg'

# 加载待检测图像
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 提取特征
kp, des = sift.detectAndCompute(gray, None)

# 预测
prob = svm.predict(des)[1]
prob = prob.ravel()

# 统计瑕疵数目
n_defects = np.sum(prob > 0.5)

# 绘制检测结果
font = cv2.FONT_HERSHEY_SIMPLEX
if n_defects == 0:
    cv2.putText(img, 'Normal', (10, 50), font, 1, (0, 255, 0), 2, cv2.LINE_AA)
else:
    cv2.putText(img, '{} defects detected'.format(n_defects), (10, 50), font, 1, (0, 0, 255), 2, cv2.LINE_AA)
cv2.imshow('Result', img)
cv2.waitKey(0)

实验结果:

使用上述代码,对于瑕疵零件图像可以正确检测出瑕疵部位,对于正常零件图像则能判定为正常。通过测试集的准确率,可以发现本实验的瑕疵检测算法具有较高的准确性。

完整代码:

import cv2
import os
import numpy as np
from sklearn.svm import SVC

# 数据集路径
dataset_path = './dataset'

# 保存训练集和测试集的路径
train_path = './train'
test_path = './test'

# 如果文件夹不存在,则创建
if not os.path.exists(train_path):
    os.makedirs(train_path)
if not os.path.exists(test_path):
    os.makedirs(test_path)

# 将数据集分为训练集和测试集
for label in os.listdir(dataset_path):
    label_path = os.path.join(dataset_path, label)
    train_label_path = os.path.join(train_path, label)
    test_label_path = os.path.join(test_path, label)
    if not os.path.exists(train_label_path):
        os.makedirs(train_label_path)
    if not os.path.exists(test_label_path):
        os.makedirs(test_label_path)
    count = 0
    for img_name in os.listdir(label_path):
        img_path = os.path.join(label_path, img_name)
        img = cv2.imread(img_path)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转换为灰度图
        if count < 80:
            save_path = os.path.join(train_label_path, img_name)
        else:
            save_path = os.path.join(test_label_path, img_name)
        cv2.imwrite(save_path, img)
        count += 1

# 训练集和测试集路径
train_path = './train'
test_path = './test'

# SIFT特征提取器
sift = cv2.xfeatures2d.SIFT_create()

# 保存特征的文件
train_feature_file = 'train_features.txt'
test_feature_file = 'test_features.txt'

# 提取训练集特征
f_train = open(train_feature_file, 'w')
for label in os.listdir(train_path):
    label_path = os.path.join(train_path, label)
    for img_name in os.listdir(label_path):
        img_path = os.path.join(label_path, img_name)
        img = cv2.imread(img_path)
        kp, des = sift.detectAndCompute(img, None)
        des_str = ' '.join([str(d) for d in des.flatten()])
        line = '{} {}\n'.format(label, des_str)
        f_train.write(line)
f_train.close()

# 提取测试集特征
f_test = open(test_feature_file, 'w')
for label in os.listdir(test_path):
    label_path = os.path.join(test_path, label)
    for img_name in os.listdir(label_path):
        img_path = os.path.join(label_path, img_name)
        img = cv2.imread(img_path)
        kp, des = sift.detectAndCompute(img, None)
        des_str = ' '.join([str(d) for d in des.flatten()])
        line = '{} {}\n'.format(label, des_str)
        f_test.write(line)
f_test.close()

# 特征文件
train_feature_file = 'train_features.txt'
test_feature_file = 'test_features.txt'

# 读取训练集和测试集特征
train_features = []
train_labels = []
f_train = open(train_feature_file, 'r')
for line in f_train.readlines():
    parts = line.strip().split()
    label = parts[0]
    des = np.array(list(map(float, parts[1:])))
    train_features.append(des)
    train_labels.append(int(label))
f_train.close()

test_features = []
test_labels = []
f_test = open(test_feature_file, 'r')
for line in f_test.readlines():
    parts = line.strip().split()
    label = parts[0]
    des = np.array(list(map(float, parts[1:])))
    test_features.append(des)
    test_labels.append(int(label))
f_test.close()

# 训练SVM模型
svm = SVC(kernel='linear', C=1.0, probability=True)
svm.fit(train_features, train_labels)

# 预测测试集
test_pred = svm.predict(test_features)
test_prob = svm.predict_proba(test_features)

# 输出准确率
accuracy = np.mean(test_pred == test_labels)
print('Accuracy: {:.2f}%'.format(accuracy * 100))

# 保存模型
model_file = 'svm.model'
cv2.ml.SVM_create().save(model_file)

# 模型文件
model_file = 'svm.model'

# SIFT特征提取器
sift = cv2.xfeatures2d.SIFT_create()

# 加载SVM模型
svm = cv2.ml.SVM_load(model_file)

# 待检测图像路径
img_path = './test/0/01.jpg'

# 加载待检测图像
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 提取特征
kp, des = sift.detectAndCompute(gray, None)

# 预测
prob = svm.predict(des)[1]
prob = prob.ravel()

# 统计瑕疵数目
n_defects = np.sum(prob > 0.5)

# 绘制检测结果
font = cv2.FONT_HERSHEY_SIMPLEX
if n_defects == 0:
    cv2.putText(img, 'Normal', (10, 50), font, 1, (0, 255, 0), 2, cv2.LINE_AA)
else:
    cv2.putText(img, '{} defects detected'.format(n_defects), (10, 50), font, 1, (0, 0, 255), 2, cv2.LINE_AA)
cv2.imshow('Result', img)
cv2.waitKey(0)
``
基于opencv机器视觉入门检测零件瑕疵的实验报告包括代码

原文地址: https://www.cveoy.top/t/topic/ePIp 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录