opencv机器学习之KNN

1.KNN原理

2.opencv中的KNN

代码速记:

  • cv2.ml.KNearest_create()
  • knn.train()
  • knn.findNearest()

实战:

def opencv_knn(self):
    # 包含(x,y)值的25个点作为训练数据
    trainData = np.random.randint(0, 100, (25, 2)).astype(np.float32)#low,hign,size,dtype
    # 把25个点用数字0和1分别标记红色或蓝色
    responses = np.random.randint(0, 2, (25, 1)).astype(np.float32)#low,hign,size,dtype
    # 找出红色点并画出
    red = trainData[responses.ravel() == 0]#中括号里的表达式返回indexes
    plt.scatter(red[:, 0], red[:, 1], 80, 'r', '^')#x,y,s,c,marker
    # 找出蓝色点并画出
    blue = trainData[responses.ravel() == 1]
    plt.scatter(blue[:, 0], blue[:, 1], 80, 'b', 's')
    newcomer = np.random.randint(0, 100, (1, 2)).astype(np.float32)#一个新的点
    plt.scatter(newcomer[:, 0], newcomer[:, 1], 80, 'g', 'o')#画出这个点
    #【1】创建knn对象
    knn = cv2.ml.KNearest_create()
    #【2】训练数据
    knn.train(trainData, cv2.ml.ROW_SAMPLE,responses)
    #【3】用新的点进行测试
    ret, results, neighbours, dist = knn.findNearest(newcomer, 3)
  
    print("result: ", results, "\n")#预测的标签
    print("neighbours: ", neighbours, "\n")#找到的邻居
    print("distance: ", dist)#和最近的邻居的距离
    plt.show()

result: [[1.]]
neighbours: [[1. 1. 0.]]
distance: [[ 557. 1105. 1160.]]

在这里插入图片描述

3.使用kNN 对手写数字OCR

  • Optical Character Recognition:光学字符识别。
  • 数据集是一张大图,其中有5000 个手写数字(每个数字重复500遍)。每个数字是一个20x20 的小图。
  • 我们使用每个数字的前250 个样本做训练数据,剩余的250 个做测试数据。在这里插入图片描述
def ocr(self):
    #【1】读图,并转为灰度图
    img =self.img
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    #【2】切割大图为小图:把图像分成20x20的5000个小块(row:1000、col:2000
    cells = [np.hsplit(row, 100) for row in np.vsplit(gray, 50)]
    #【3】转为numpy数组,它的size为(50,100,20,20)
    x = np.array(cells)
    #【4】准备train_data 和 test_data.
    train = x[:, :50].reshape(-1, 400).astype(np.float32)  # Size = (2500,400)
    test = x[:, 50:100].reshape(-1, 400).astype(np.float32)  # Size = (2500,400)
    #【5】为train 和 test data准备标签
    k = np.arange(10)#0-9
    train_labels = np.repeat(k, 250)[:, np.newaxis]
    test_labels = train_labels.copy()
    #【6】初始化kNN, 训练数据, 测试数据for k=1,得到预测结果
    knn = cv2.ml.KNearest_create()
    knn.train(train, cv2.ml.ROW_SAMPLE, train_labels)
    ret, result, neighbours, dist = knn.findNearest(test, k=5)
    #【7】计算分类器的准确率
    # 比较预测标签和test_data的实际标签
    matches = (result == test_labels)
    correct = np.count_nonzero(matches)
    accuracy = correct * 100.0 / result.size
    print('准确率', accuracy)  # 准确率91.76%
    # 保存数据
    np.savez('knn_data.npz', train=train, train_labels=train_labels, test=test, test_labels=test_labels)
    # 加载数据
    with np.load('knn_data.npz') as data:
        print(data.files)#['train', 'train_labels', 'test', 'test_labels']
        train = data['train']
        train_labels = data['train_labels']
        test = data['test']
        test_labels = data['test_labels']

准确率 91.76
[‘train’, ‘train_labels’, ‘test’, ‘test_labels’]

4.英文字母的OCR

在这里插入图片描述

  • 每一行的第一列是我们的一个字母标记。接下来的16 个数字是它的不同特征。这些特征来源于UCI Machine Learning Repository.
  • 有20000 个样本可以使用,我们取前10000 个作为训练样本,剩下的10000 个作为测试样本。
def en_ocr(self):
    #【1】加载数据,converters把字母转换为数字
    data = np.loadtxt('../images/letter-recognition.data', dtype='float32', delimiter=',',
                      converters={0: lambda ch: ord(ch) - ord('A')})  # 20000个
    #【2】把数据分成2部分,train和test各10000
    train, test = np.vsplit(data, 2)
    #【3】把数据集分成特征值和标签
    responses, trainData = np.hsplit(train, [1])
    labels, testData = np.hsplit(test, [1])
    #【4】初始化KNN,分类,计算准确率
    knn = cv2.ml.KNearest_create()
    knn.train(trainData, cv2.ml.ROW_SAMPLE, responses)
    ret, result, neighbours, dist = knn.findNearest(testData, k=5)
    correct = np.count_nonzero(result == labels)
    accuracy = correct * 100.0 / 10000
    print('准确率', accuracy)  # 93.06
    #存储数据
    np.savez('knn_data_alphabet.npz', train_alphabet=train, train_labels_alphabet=responses, test_alphabet=testData,
             test_labels_alphabet=labels)

准确率 93.06

发布了154 篇原创文章 · 获赞 45 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_36622009/article/details/104828425
今日推荐