機器學習——KNN實現手寫數字識別:基于 OpenCV 和 scikit-learn 的實戰教學 (超級超級超級簡單)

用KNN實現手寫數字識別:基于 OpenCV 和 scikit-learn 的實戰教學

在這篇文章中,我們將使用 KNN(K-Nearest Neighbors)算法對手寫數字進行分類識別。我們會用 OpenCV 讀取圖像并預處理數據,用 scikit-learn 構建并訓練模型,最終識別新的數字圖像。

為什么像素可以被代碼讀取為數據:

圖像的本質:像素的數字矩陣

任何數字圖像(如照片、截圖、手寫數字圖片)都是由無數個微小的 “像素點”(Pixel)組成的

  • 每個像素點的數值含義

    • 對于灰度圖(如代碼中的手寫數字),每個像素用一個 0-255 的整數表示亮度:0 代表純黑,255 代表純白,中間值表示不同深淺的灰色。
    • 對于彩色圖(如 RGB 格式),每個像素由三個數值(R、G、B)組成,分別對應紅、綠、藍三種顏色的亮度,組合后呈現出各種顏色。

(可以在調試時看一看代碼里的‘gray’參數里面 單個數字圖像的矩陣)

此20×20 像素的數字圖像就是一個數字矩陣顯示出的一個大大的 0

使用的數據集

我們使用的是一個包含 5000 個手寫數字(0-9) 的圖像文件(digits5000.png),每種數字500個,總共10類。圖像被排布成了一個 50 行 × 100 列 的網格,每個小格是一個 20×20 像素的數字圖像

數據圖像:

保存下面代碼所需的三張圖片:

?

上面的 ‘3’,‘6’ 圖片可在‘開始’里的‘畫圖’中,可以創建我們想要自定義的數字圖片:


然后使用畫筆寫一個數字后(筆粗一點):

把比例調到? ?20×20 像素

即可得到。

?完整代碼:

import numpy as np
from sklearn.neighbors import KNeighborsClassifier
import cv2# 讀取包含5000個手寫數字的大圖,每個數字為20x20像素
img = cv2.imread('digits5000.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 轉換為灰度圖# 將大圖分割為50行100列的小單元格,每個單元格包含一個手寫數字
cells = [np.hsplit(row,100) for row in np.vsplit(gray,50)]# 將單元格列表轉換為四維數組: (50行, 100列, 20像素高, 20像素寬)
x = np.array(cells)# 準備訓練集和測試集數據
# 前50列作為訓練集,后50列作為測試集
# 數據重塑為: (樣本數, 特征數),每個樣本包含400個像素值
train = x[:,:50].reshape(-1,400)
test = x[:,50:].reshape(-1,400)# 創建標簽數據
n = np.arange(10)  # 創建數字0-9的數組
# 每個數字對應250個樣本(50行×5列),生成訓練標簽
tags = np.repeat(n,250)
tag = tags[:,np.newaxis]  # 轉換為二維數組,形狀為(2500, 1)# 創建并訓練KNN分類器,使用k=5最近鄰
knn = KNeighborsClassifier(n_neighbors=5)    #給初學者的建議:在此處設置斷點 或 直接在import處設置斷點,開啟調試一行一行地運行,更好的看到每一個參數的變化
knn.fit(train, tag)# 評估模型在訓練集上的準確率
predictions_train = knn.predict(train)    #此行結果沒有運行,建議在開啟調試,可看到
accuracy_train = knn.score(train, tag)
print(f"訓練集準確率: {accuracy_train:.4f}")# 評估模型在測試集上的準確率
predictions_test = knn.predict(test)
accuracy_test = knn.score(test, tag)
print(f"測試集準確率: {accuracy_test:.4f}")# 預測外部數字3的圖像
digit3 = cv2.imread('digit3.png')
digit3gray = cv2.cvtColor(digit3, cv2.COLOR_BGR2GRAY)
digit3test = digit3gray.reshape(-1,400)  # 重塑為模型期望的輸入格式
predictions_digit3 = knn.predict(digit3test)
print(f"預測數字3的結果: {predictions_digit3}")# 預測外部數字6的圖像
digit6 = cv2.imread('digit6.png')
digit6gray = cv2.cvtColor(digit6, cv2.COLOR_BGR2GRAY)
digit6test = digit6gray.reshape(-1,400)  # 重塑為模型期望的輸入格式
predictions_digit6 = knn.predict(digit6test)
print(f"預測數字6的結果: {predictions_digit6}")

紅色斷點:

調試:

點擊 單步執行 或 其他? ?,多嘗試嘗試

點擊“作為...查看”即可清晰查看


所需庫導入

import numpy as np
from sklearn.neighbors import KNeighborsClassifier
import cv2
  • numpy: 用于矩陣操作。

  • sklearn.neighbors.KNeighborsClassifier: 實現KNN分類器。

  • cv2: OpenCV庫,用于圖像讀取與處理。


圖像加載與預處理

img = cv2.imread('digits5000.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

  • cv2.imread() 讀取圖像。

  • cv2.cvtColor() 將圖像從彩色(BGR)轉換為灰度(GRAY),便于處理。


圖像分割成小數字圖塊

cells = [np.hsplit(row,100) for row in np.vsplit(gray,50)]
x = np.array(cells)
  • 使用 np.vsplit() 將圖像豎直切成50行(每行包含100個數字)。

  • 對每行使用 np.hsplit() 水平切分成100列,最終每個小格是一個20x20的數字圖像。

  • 得到的 x 是一個形狀為 (50, 100, 20, 20) 的數組。


構建訓練集與測試集

train = x[:,:50].reshape(-1,400)
test = x[:,50:].reshape(-1,400)
  • 將每個 20×20 圖像展開為 1×400 的一維向量。

  • 前 50 列作為訓練集,后 50 列作為測試集。

  • traintest 的形狀均為 (2500, 400)


構造標簽

n = np.arange(10)                   #(0123456789)
tags = np.repeat(n,250)            #每個數字重復250次 -> [0,...0,1,...,1,...9,...9]
tag = tags[:,np.newaxis]           #添加新維度,變成列向量
# test_tag = np.repeat(n,250)[:np.newaxis]   
  • tags 是長度為 2500 的一維標簽數組。

  • tag 是形狀為 (2500, 1) 的列向量,作為訓練和測試的真實標簽。

為什么重復250次,因為我們把數據從中間對半切開,每個數字有500個,左二百五十為訓練集,右二百五十個為測試集。

所以其實訓練集和測試集的標簽是一樣的,標簽就是每一個20x20數字圖像所顯示的數字。


訓練模型并評估準確率

knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(train, tag)predictions_train = knn.predict(train)
accuracy_train = knn.score(train, tag)
print(accuracy_train)predictions_test = knn.predict(test)
accuracy_test = knn.score(test, tag)
print(accuracy_test)
  • 初始化一個 KNN 分類器,選擇 k=5

  • 使用 .fit() 訓練模型。

  • 使用 .predict().score() 對訓練集和測試集進行預測和評分。

  • 打印準確率:理論上訓練集精度應很高,測試集略低(但通常也超過 97%)。


識別自定義手寫數字

digit3 = cv2.imread('digit3.png')   #圖片中的數字是3
digit3gray = cv2.cvtColor(digit3, cv2.COLOR_BGR2GRAY)
digit3test = digit3gray.reshape(-1,400)
predictions_digit3 = knn.predict(digit3test)
print(predictions_digit3)digit6 = cv2.imread('digit6.png')   #圖片中的數字是6
digit6gray = cv2.cvtColor(digit6, cv2.COLOR_BGR2GRAY)
digit6test = digit6gray.reshape(-1,400)
predictions_digit6 = knn.predict(digit6test)
print(predictions_digit6)
  • 讀取兩張額外圖像 digit3.pngdigit6.png

  • 將其轉換為灰度、再reshape成與訓練數據一致的 (1, 400) 形狀。

  • 使用模型預測數字類別。


總結

我們用 KNN 成功實現了手寫數字的分類識別,關鍵步驟包括:

  1. 圖像預處理和切分

  2. 標簽構造與數據 reshape

  3. 使用 KNeighborsClassifier 建模

  4. 預測未知圖像的數字類別

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/91139.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/91139.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/91139.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Git】分支

文章目錄理解分支創建分支切換分支合并分支刪除分支合并沖突分支管理策略分支策略bug 分支刪除臨時分支小結理解分支 本章開始介紹 Git 的殺手級功能之一(注意是之一,也就是后面還有之二,之三……):分支。分支就是科幻…

【32】C# WinForm入門到精通 ——打開文件OpenFileDialog 【屬性、方法、事件、實例、源碼】

WinForm 是 Windows Form 的簡稱,是基于 .NET Framework 平臺的客戶端(PC軟件)開發技術,是 C# 語言中的一個重要應用。 .NET 提供了大量 Windows 風格的控件和事件,可以直接拿來使用。 本專欄內容是按照標題序號逐漸…

Wan2.2開源第1天:動態燈光功能開啟創意氛圍新境界

在開源軟件蓬勃發展的今天,每一次新版本的發布都如同在創意的星空中點亮了一顆璀璨的新星。今天,(通義萬相國際版wan)Wan2.2正式開源,它帶著令人眼前一亮的動態燈光功能驚艷登場,為所有追求創意與氛圍營造的…

Excel制作滑珠圖、啞鈴圖

Excel制作滑珠圖、啞鈴圖效果展示在較長時間周期內,很多參數都是在一定范圍內浮動的,并不是一成不變的,為了直觀表達各類別的浮動范圍,使用“滑珠圖”就是一個不錯的選擇,當滑珠圖兩側均有珠子的時候,又稱為…

Day07 JDBC+MyBatis

1.JDBC入門程序2.JDBC執行DQL語句3.JDBC預編譯SQL 防止SQL注入隨便輸入用戶名,密碼為or1 1,sql注入4.Mybatis入門 Mapper 持久層XxxMapper替代Dao4.1調用接口的findAll()方法時自動執行上方的SQL語句,并將SQL查詢的語句自動封裝到返回值中5.Mybatis輔助…

OSS-服務端簽名Web端直傳+STS獲取臨時憑證+POST簽名v4版本開發過程中的細節

這里寫自定義目錄標題配置OSS服務端代碼初始化STS Client獲取STS臨時憑證創建policy計算SigningKeyOSSUtil.javaSTSPolicyDTO.java提供接口Apifox模擬Web端文件直傳本文主要結合服務端STS獲取臨時憑證(簽名)直傳官方文檔對開發中比較容易出錯的地方加以提醒;建議主要…

uniapp實現微信小程序導航功能

1.導航按鈕<button click"navigation()">導航到倉庫</button>2.導航功能const navigation (item) > {let address item.province item.city item.district item.address //地址let latitude Number(item.latitude) …

07.4-使用 use 關鍵字引入路徑

使用 use 關鍵字引入路徑 每次調用函數時都必須寫出完整路徑&#xff0c;可能會感覺不便且重復。在清單7-7中&#xff0c;無論我們選擇絕對路徑還是相對路徑來調用 add_to_waitlist 函數&#xff0c;每次調用時都必須指定 front_of_house 和 hosting。幸運的是&#xff0c;有一…

7.Linux :進程管理,進程控制與計劃任務

Linux &#xff1a;進程管理&#xff0c;進程控制與計劃任務 一、進程管理 1. 進程與程序 程序&#xff1a;靜態的可執行文件&#xff08;存儲于磁盤&#xff09;。進程&#xff1a;動態執行的程序實例&#xff08;占用CPU/內存&#xff09;。 2. 查看進程命令作用常用組合ps靜…

Matplotlib(四)- 圖表樣式美化

文章目錄一、Matplotlib圖表樣式介紹1. 圖表樣式簡介2. 默認圖表樣式2.1 查看默認配置2.2 常用的配置3. 圖表樣式修改3.1 局部修改3.1.1 通過繪圖方法設置參數修改3.1.2 通過rcParams修改3.1.3 通過rc()方法修改3.2 全局修改二、顏色設置1. 顏色的三種表示方式1.1 顏色單詞1.2 …

三十四、【Linux常用工具】rsync+inotify實時同步演示

實時同步演示技術架構全景核心組件詳解1. inotify 內核子系統2. Rsync 高效同步工具實踐演示一、環境準備與安裝1. 檢查內核支持2. 安裝 inotify-tools二、配置 Rsync 服務端&#xff08;目標機&#xff09;1. 創建 Rsync 配置文件2. 啟動 Rsync 守護進程三、配置實時同步腳本&…

windows環境下MySQL 8.0 修改或重置密碼

windows環境下MySQL 8.0 修改或重置密碼 1打開命令窗口cmd&#xff0c;輸入命令&#xff1a;net stop mysql&#xff0c; 停止MySQL服務&#xff0c; 開啟跳過密碼驗證登錄的MySQL服務 2輸入命令 mysqld --console --skip-grant-tables --shared-memory 再打開一個新的cmd&…

基于YOLOP與GAN的圖像修復與防御系統設計與實現

基于YOLOP與GAN的圖像修復與防御系統設計與實現 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家&#xff0c;覺得好請收藏。點擊跳轉到網站。 1. 引言 1.1 研究背景 隨著深度學習技術在計算機視覺領域的…

將目錄文件轉移到D盤,使之后的下載緩存數據轉移,不再存入c盤

將 C:\Users 文件夾&#xff08;用戶文件夾&#xff09;轉移到其他盤是一個復雜且風險較高的操作。C:\Users 文件夾包含了系統中每個用戶的個人數據和配置文件&#xff0c;修改這個路徑可能會導致系統出現問題&#xff0c;包括程序無法正常工作或無法登錄。因此&#xff0c; 強…

Cesium大氣散射效果

由于做全球體積云效果的需要&#xff0c;再來研究下大氣散射效果和體積云類似&#xff0c;關于大氣散射顏色計算的過程也僅發生在這兩個球體之間。如圖所示。計算從相機出發的視線與球殼的交點&#xff0c;如果不相交&#xff0c;則該視線方向上不會發生大氣散射&#xff0c;直…

預過濾環境光貼圖制作教程:第二步 - 生成環境貼圖圖集

核心目標 本步驟的核心是生成一張包含 6 級分辨率的環境貼圖圖集(envAtlas),實現: 將第一步的立方體貼圖(sourceCube)重新映射為等矩形投影(適合存儲和采樣); 生成 6 級不同分辨率的等矩形數據(0 級最高清,5 級最模糊); 用 RGBP 編碼壓縮 HDR 數據(平衡精度與存…

1. ESP開發之實體按鍵(KEYPADBUTTON)控制LVGL控件

說明LV_INDEV_TYPE_BUTTON的使用LV_INDEV_TYPE_KEYPAD的使用 說明 本實驗使用LVGL版本為v9.2 LVGL中有四種輸入設備,如下LV_INDEV_TYPE_POINTER, /**< Touch pad, mouse, external button*/ LV_INDEV_TYPE_KEYPAD, /**< Keypad or keyboard*/ LV_INDEV_TYPE_BUTTON, /*…

C++:STL中list的使用和模擬實現

C中的list是標準模板庫&#xff08;STL&#xff09;提供的雙向鏈表容器&#xff0c;支持高效的元素插入和刪除操作。在上一篇中講解了vector的使用和模擬實現&#xff0c;vector是具有連續的空間&#xff0c;迭代器是可以隨機的&#xff0c;而list卻于vector不同&#xff0c;li…

【編號58-61】我國四大高原矢量示意圖shp數據

今天分享的是&#xff1a;中國四大高原&#xff0c;分別是青藏高原、內蒙古高原、黃土高原、云貴高原。青藏高原位置與范圍&#xff1a;位于中國西南部&#xff0c;包括西藏、青海的全部&#xff0c;川西高原及滇西北高原等部分地區。它的邊界&#xff0c;向東是橫斷山脈&#…

【AI落地應用實戰】利用 Amazon Bedrock Claude3 打造個性化 AI Character 應用

目錄一、引言&#xff1a;AI Character應用的市場前景與技術基礎二、技術架構設計2.1、整體方案概述2.2、核心組件介紹2.3、部署架構圖三、系統部署方案3.1、方案總述3.2、實踐流程1??. Bedrock 配置2??. 安裝 SillyTavern3??. 配置 SillyTavern 使用 Claude3 模型4??.…