• (3) OpenCV图像处理kNN近邻算法-识别摄像头数字


    目录

    一、代码简介

    二、程序代码

    三、使用的图片资源

    1、图片digits.png

    2、图片6.png 


    一、代码简介

            使用Python的OpenCV库进行图像处理和数字识别的例子。通过下面的步骤对摄像头的黑色数字进行识别(由于我电脑没有摄像头,实际使用需要替换获取图像部分的代码)。这里的代码只能用于识别照片里面最大的单个数字的简单识别算法,需要更多样化的识别就需要自己在这基础上扩展咯!!!(注意:识别的是黑色数字)

    具体步骤如下:

            首先,它读取一个名为“digits.png”的图像文件,这个文件应该包含了一些手写数字。然后,它将这个图像从彩色模式转化为灰度模式,这样做可以减少数据的维度,使得处理更加简单。通过使用numpy数组,图像数据被分割成10行,每行90个像素,这样的块被称为“cells”。

            接下来,这些cells被组合成一个大数组,然后调整其形状为(-1, 400),这是k-NN算法需要的输入格式。这个调整形状的操作通过numpy的reshape函数实现。

            然后,这个调整后的数组被用作训练数据,训练一个k-最近邻(k-NN)分类器。这个分类器用于识别和分类图像中的数字。k-NN是一种常见的机器学习算法,它假设样本在特征空间中的邻近情况可以反映其类别。

            在主循环中,代码读取另一个名为“6.png”的图像文件,并对其进行一系列操作:先将其从BGR颜色空间转化为HSV颜色空间,然后通过取反操作将颜色值反转,这可以使图像中的白色区域变为黑色,黑色区域变为白色。

            然后,使用OpenCV的findContours函数找出图像中的轮廓。一般来说,数字的轮廓会被找出,然后可以使用boundingRect函数得到这个轮廓的边界矩形。这个边界矩形可以确定数字的大致位置。

            接下来,通过裁剪和重新调整大小,将数字图像处理为26x26像素大小。这样做可以使得处理简单化,因为所有的数字图像都有相同的大小。最后,使用k-NN分类器对处理后的数字图像进行分类。

            这段代码的主要目的是对一个包含手写数字的图像进行识别。用户可以在屏幕上看到识别结果。如果用户按下“q”键,代码会结束运行并关闭所有打开的窗口。

    二、程序代码

    1. import numpy as np
    2. import cv2 as cv
    3. img = cv.imread('digits.png') # 读取名为'digits.png'的图像
    4. gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY) # 将图像转换为灰度图像
    5. # 现在我们将图像分割为900个单元格,每个单元格为20x20
    6. cells = [np.hsplit(row,90) for row in np.vsplit(gray,10)] # 将图像分割成10行90列的单元格,每个单元格为20x20像素
    7. # 使其成为一个Numpy数组。它的大小将是(10,90,20,20)
    8. x = np.array(cells) # 将分割后的图像转换为一个Numpy数组
    9. # 现在我们准备train_data和test_data。
    10. train = x[:,:90].reshape(-1,400).astype(np.float32) # 取数组作为训练数据,并将其形状转换为(450,400)的浮点数类型
    11. # 为训练和测试数据创建标签
    12. k = np.arange(10) # 创建一个包含数字0到10的一维数组
    13. train_labels = np.repeat(k,90)[:,np.newaxis] # 将数组重复90次,得到一个(900,1)的二维数组,作为训练数据的标签
    14. # 初始化kNN,训练数据,然后使用k = 1的测试数据对其进行测试
    15. knn = cv.ml.KNearest_create() # 创建一个kNN分类器对象
    16. knn.train(train, cv.ml.ROW_SAMPLE, train_labels) # 使用训练数据和标签训练分类器
    17. while True:
    18. img = cv.imread('6.png')
    19. # 转换颜色空间 BGR 到 HSV
    20. hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
    21. # 定义HSV中黑色的范围
    22. lower_blue = np.array([0,0,0])
    23. upper_blue = np.array([0,0,50])
    24. # 设置HSV的阈值使得只取黑色
    25. mask = cv.inRange(hsv, lower_blue, upper_blue)
    26. # 查找图像轮廓
    27. contours,hierarchy = cv.findContours(mask, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
    28. # 判断是否检测到轮廓
    29. if contours:
    30. # 取最大的轮廓
    31. cnt = contours[0]
    32. # 计算轮廓的边界矩形
    33. x, y, w, h = cv.boundingRect(cnt)
    34. # 复制选中的图像为新变量
    35. buf = mask[y:y+h, x:x+w]
    36. # 显示结果帧
    37. cv.imshow('buf', buf)
    38. # 获取缩小的比例
    39. num_x = 1/(w/20)
    40. num_y = 1/((h)/20)
    41. # 对图像进行缩放
    42. res = cv.resize(buf,None,fx=num_x, fy=num_y, interpolation = cv.INTER_CUBIC)
    43. # 创建一个新的图像,大小是26x26,三个通道,数据类型为8位无符号整数(即像素值范围从0到255)
    44. new_img = np.zeros((28, 28), dtype=np.uint8)
    45. # 将扩展后的 res 赋值给 new_img
    46. new_img[4:20+4, 4:20+4] = res
    47. # 获取缩小的比例
    48. new_num = 1/(28/20)
    49. # 对图像进行缩放
    50. res = cv.resize(new_img,None,fx=new_num, fy=new_num, interpolation = cv.INTER_CUBIC)
    51. # 将图像颜色值取反
    52. res = cv.bitwise_not(res)
    53. # 显示结果帧
    54. cv.imshow('res', res)
    55. # 将图像转换为一个Numpy数组
    56. gray1_array = np.array(res)
    57. # 取数组作为测试数据,并将其形状转换为(450,400)的浮点数类型
    58. test = gray1_array[:,:].reshape(-1,400).astype(np.float32)
    59. # 使用测试数据和k=1的参数调用分类器的findNearest方法,得到返回值、预测结果、最近邻样本和距离
    60. ret,result,neighbours,dist = knn.findNearest(test,k=1)
    61. print( "result:\n{}\n".format(result) )
    62. if cv.waitKey(1) == ord('q'):
    63. # 完成所有操作后,释放捕获器
    64. cv.destroyAllWindows()
    65. break
    66. # 完成所有操作后,释放捕获器
    67. cv.destroyAllWindows()

    三、使用的图片资源

    1、图片digits.png

    2、图片6.png 

  • 相关阅读:
    Kotlin高仿微信-第8篇-单聊
    超分辨率技术
    图像去雾易语言代码
    C# 第三方曲线库及其特点
    在配置了 el-table 组件的合计行后,由于elementUI 表格el-table设置高度之后,合计行功能不会显示
    【前端】彻底搞懂HTTP协议
    【Linux】——使用xshell在Linux上安装MySQL及实现Webapp的部署
    【构建并发程序】8-并发队列之阻塞队列
    LabVIEW​能否​像​C​语言​一样
    asp.net core mvc 控制器使用配置
  • 原文地址:https://blog.csdn.net/qq_26043945/article/details/133899779