特征提取+BP神经网络,实现对图像的分类

1.前言

这里是使用”特征提取+BP神经网络,实现对图像的分类”,需要知道的是: 1.对二维图像做完标签,制作数据集后,可以用CNN(一般输入是而惟独图片)来对图像做分类的。当前,在这之前要经过对模型的训练过程。 2.也可以通过特征提取先把二维图片变成一位特征,输入到BP神经网络中,进行模型训练,然后做分类。

今天,讲到的,就是第2种方式。

2.数据集制作

这里使用的是对工业金属件表面缺陷图像(有三类缺陷图像,分别是:裂纹crack,夹杂inclusion,麻点pitted )。

特征提取+BP神经网络,实现对图像的分类

使用Hu不变矩等方法手动提取特征(一维特征),然后输入BP神经网络中做分类。

首先,使用Hu不变矩对缺陷图像进行特征提取,每一副缺陷图像产生7个特征,再加上这副图像的类别标签,就形成了数据集中的一个样本。

我们选取了夹杂、裂纹和麻点三类缺陷各100副图像,制作数据集。使用Hu不变矩进行特征提取后,就有了300个样本的特征。

特征提取+BP神经网络,实现对图像的分类

Hu矩特征提取的代码(opencv+python)

def sys_moments(img):
    '''
    opencv_python自带求矩以及不变矩的函数
    :param img: 灰度图像,对于二值图像来说就只有两个灰度0和255
    :return: 返回以10为底对数化后的hu不变矩
    '''
    moments = cv2.moments(img)
    humoments = cv2.HuMoments(moments)

    humoment = (np.log(np.abs(humoments))) / np.log(10)
    return humoment

def def_moments(img_gray):
    '''
    自定义求矩函数,主要是根据公式将一个个参数求出
    :param img_gray:  灰度图像,对于二值图像来说就只有两个灰度0和255
    :return: 返回以10为底对数化后的hu不变矩
    '''
    '''
        由于7个不变矩的变化范围很大,为了便于比较,可利用取对数的方法进行数据压缩;
        同时考虑到不变矩有可能出现负值的情况,因此,在取对数之前先取绝对值
        经修正后的不变矩特征具有平移 、旋转和比例不变性
    '''

    row, col = img_gray.shape

    m00 = img_gray.sum()

    m10 = m01 = 0

    m11 = m20 = m02 = m12 = m21 = m30 = m03 = 0
    for i in range(row):
        m10 += (i * img_gray[i]).sum()
        m20 += (i ** 2 * img_gray[i]).sum()
        m30 += (i ** 3 * img_gray[i]).sum()
        for j in range(col):
            m11 += i * j * img_gray[i][j]
            m12 += i * j ** 2 * img_gray[i][j]
            m21 += i ** 2 * j * img_gray[i][j]
    for j in range(col):
        m01 += (j * img_gray[:, j]).sum()
        m02 += (j ** 2 * img_gray[:, j]).sum()
        m30 += (j ** 3 * img_gray[:, j]).sum()

    u10 = m10 / m00
    u01 = m01 / m00

    y00 = m00
    y10 = y01 = 0
    y11 = m11 - u01 * m10
    y20 = m20 - u10 * m10
    y02 = m02 - u01 * m01
    y30 = m30 - 3 * u10 * m20 + 2 * u10 ** 2 * m10
    y12 = m12 - 2 * u01 * m11 - u10 * m02 + 2 * u01 ** 2 * m10
    y21 = m21 - 2 * u10 * m11 - u01 * m20 + 2 * u10 ** 2 * m01
    y03 = m03 - 3 * u01 * m02 + 2 * u01 ** 2 * m01

    n20 = y20 / m00 ** 2
    n02 = y02 / m00 ** 2
    n11 = y11 / m00 ** 2
    n30 = y30 / m00 ** 2.5
    n03 = y03 / m00 ** 2.5
    n12 = y12 / m00 ** 2.5
    n21 = y21 / m00 ** 2.5

    h1 = n20 + n02
    h2 = (n20 - n02) ** 2 + 4 * n11 ** 2
    h3 = (n30 - 3 * n12) ** 2 + (3 * n21 - n03) ** 2
    h4 = (n30 + n12) ** 2 + (n21 + n03) ** 2
    h5 = (n30 - 3 * n12) * (n30 + n12) * ((n30 + n12) ** 2 - 3 * (n21 + n03) ** 2) + (3 * n21 - n03) * (n21 + n03) \
         * (3 * (n30 + n12) ** 2 - (
            n21 + n03) ** 2)
    h6 = (n20 - n02) * ((n30 + n12) ** 2 - (n21 + n03) ** 2) + 4 * n11 * (n30 + n12) * (n21 + n03)
    h7 = (3 * n21 - n03) * (n30 + n12) * ((n30 + n12) ** 2 - 3 * (n21 + n03) ** 2) + (3 * n12 - n30) * (n21 + n03) \
         * (3 * (n30 + n12) ** 2 - (
            n21 + n03) ** 2)
    inv_m7 = [h1, h2, h3, h4, h5, h6, h7]
    humoments = np.log(np.abs(inv_m7))
    return humoments
def main():
    img = cv2.imread('3.png', 0)
    sys_humoments = sys_moments(img)

    print('Hu不变矩为:\n', sys_humoments)

if __name__ == '__main__':
    main()

这里提供了两个Hu的实现,一个opencv中封装的,一个手动实现的。建议读者使用opencv中封装的。

为何Hu矩可以作为特征提取的一个方法,因为Hu矩具有不变性的特点( Hu不变矩,Hu.M.K在1962年证明了它们具有平移,尺度(缩放)和旋转不变性,参考论文:Visual pattern recognition by moment invariants)。既然具有不变性,就可以作为图像分类的依据。

特征提取+BP神经网络,实现对图像的分类

从实验中,可以看出对一副图像做平移,尺度,旋转变换后,这7个值很接近。表明Hu矩的不变性。

3.使用tensortflow搭建BP网络

这里只附上代码,不做具体讲解,读者有疑问可评论区留言。

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import random
from sklearn.preprocessing import MinMaxScaler

from tensorflow.python.client import device_lib
import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
os.environ["CUDA_VISIBLE_DEVICES"] = "0"

Lables = {0: 'crack',
          1: 'inclusion',
          2: 'pitted'}

def print_history(history):

    plt.plot(history.history['accuracy'])
    plt.plot(history.history['val_accuracy'])
    plt.plot(history.history['loss'])
    plt.plot(history.history['val_loss'])
    plt.title('Model accuracy&loss')

    plt.xlabel('Epoch')
    plt.legend(['Train_acc', 'Val_acc', 'Train_loss', 'Val_loss'])

    plt.show()

def BP1(lr):
    model = tf.keras.models.Sequential([
        tf.keras.layers.Dense(5, activation='sigmoid', input_shape=(7,)),
        tf.keras.layers.Dense(3, activation='softmax')
    ])
    model.build(input_shape=(None, 7))

    model.compile(loss='categorical_crossentropy',
                  optimizer=tf.keras.optimizers.Adam(lr),
                  metrics=['accuracy'])

    return model

if __name__ == '__main__':

    data = []

    raw = pd.read_csv('Hu.csv')
    raw_data = raw.values
    raw_feature = raw_data[:, 0:7]

    scaler = MinMaxScaler()
    scaler.fit(raw_feature)
    scaler.data_max_
    raw_feature = scaler.transform(raw_feature)

    x = []
    y = []
    for i in range(len(raw_feature)):
        x.append(list(raw_feature[i]))
        if raw_data[i][9] == 'crack':
            y.append([1, 0, 0])
        elif raw_data[i][9] == 'inclusion':
            y.append([0, 1, 0])
        else:
            y.append([0, 0, 1])

    x = np.array(x)
    y = np.array(y)
    permutation = np.random.permutation(len(x))
    x = x[permutation]
    y = y[permutation]

    train_data = x[0:240]
    train_label = y[0:240]

    test_data = x[240:]
    test_label = y[240:]

    lr = 0.001
    bp_model = BP1(lr=lr)

    bp_model.summary()

    lr_reducer = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss',
                                                      factor=0.8, patience=5,
                                                      min_lr=0.5e-6)

    es = tf.keras.callbacks.EarlyStopping(monitor='val_loss', mode='min',
                                          verbose=0, patience=100, min_delta=0.0001,
                                          restore_best_weights='True')

    history = bp_model.fit(train_data, train_label, batch_size=10, epochs=10000, verbose=1,
                           callbacks=[lr_reducer, es], validation_split=0.25, shuffle=False)

    print_history(history)

    print('loss, acc:', bp_model.evaluate(test_data, test_label, batch_size=10, verbose=0))

这里数据集、验证集和测试集采用6:2:2的比例划分,总共300个样本

实现结果:

特征提取+BP神经网络,实现对图像的分类
特征提取+BP神经网络,实现对图像的分类

使用Early Stopping在训练集和验证集上accuracy和loss曲线

数据和代码:百度网盘
提取码:tian
–来自百度网盘超级会员V7的分享

如果这篇文章帮助到你了,那就点个赞,给个关注吧!

Original: https://blog.csdn.net/t18438605018/article/details/121664082
Author: 做个好男人!
Title: 特征提取+BP神经网络,实现对图像的分类

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/661896/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球