基于 OpenCV 與 sklearn 的數字識別:KNN 算法實踐

在計算機視覺領域,數字識別是一個經典問題,廣泛應用于郵政編碼識別、車牌識別等場景。本文將介紹如何使用 OpenCV 進行圖像處理,并結合 KNN(K 近鄰)算法實現數字識別,同時對比 OpenCV 內置 KNN 與 scikit-learn 庫中 KNN 的實現差異。

準備工作

首先,我們需要導入所需的庫:

import numpy as np
import cv2
from sklearn.neighbors import KNeighborsClassifier

其中,numpy用于數值計算,cv2(OpenCV)用于圖像處理,KNeighborsClassifier則是 scikit-learn 庫中的 KNN 分類器。

圖像讀取與預處理

我們需要讀取兩張圖像:一張包含大量數字樣本的訓練圖像,另一張作為測試圖像。

# 讀取訓練圖像和測試圖像
img = cv2.imread(r'D:\pythonProject11\class\aa.png')
c_img = cv2.imread(r'D:\pythonProject11\class\ccc.png')# 將彩色圖像轉換為灰度圖像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
c_gray = cv2.cvtColor(c_img, cv2.COLOR_BGR2GRAY)

彩色圖像包含 RGB 三個通道,轉換為灰度圖像可以減少計算量,同時保留圖像的主要特征。cv2.cvtColor函數用于顏色空間轉換,COLOR_BGR2GRAY參數表示從 BGR 格式(OpenCV 默認的彩色圖像格式)轉換為灰度格式。

數據準備

圖像分割

我們假設訓練圖像是一個包含 50 行 100 列數字的網格圖像,每個數字占據一個 20×20 像素的區域。我們需要將這個大圖像分割成多個小圖像,每個小圖像對應一個數字樣本。

python

運行

# 先垂直分割成50行,再對每行水平分割成100列
cell = np.array([np.hsplit(row, 100) for row in np.split(gray, 50)])

這里使用了np.splitnp.hsplit兩個函數:

  • np.split(gray, 50)將灰度圖像垂直分割成 50 個等高度的子數組
  • np.hsplit(row, 100)將每個子數組水平分割成 100 個等寬度的子數組

最終得到的cell是一個形狀為 (50, 100, 20, 20) 的數組,表示 50 行 100 列,每個元素是 20×20 像素的數字圖像。

訓練集和測試集劃分

我們將前 50 列作為訓練集,后 50 列作為測試集:

python

運行

# 劃分訓練集和測試集
train_ma = cell[:, :50]  # 前50列作為訓練集
test_ma = cell[:, 50:100]  # 后50列作為測試集# 轉換為二維數組(樣本數×特征數)
train_ma = train_ma.reshape(-1, 400).astype(np.float32)  # 50×50=2500個樣本,每個樣本20×20=400個特征
test_ma = test_ma.reshape(-1, 400).astype(np.float32)

reshape(-1, 400)將每個 20×20 的圖像轉換為一個長度為 400 的一維數組,便于作為機器學習算法的輸入。-1表示自動計算該維度的大小,這里計算結果為 2500(50×50)。

標簽生成

我們需要為每個樣本生成對應的標簽(即該樣本對應的數字)。假設圖像中的數字是按 0-9 的順序重復排列的:

python

運行

# 生成標簽
kernel = np.arange(10)  # 生成0-9的數字
train_la = np.repeat(kernel, 250)[:, np.newaxis]  # 每個數字重復250次,形成2500個標簽
test_la = np.repeat(kernel, 250)[:, np.newaxis]

np.repeat(kernel, 250)將 0-9 每個數字重復 250 次,得到一個長度為 2500 的數組,與我們的樣本數量一致。[:, np.newaxis]將一維數組轉換為二維列向量,以滿足 OpenCV 中 KNN 算法對標簽格式的要求。

測試圖像預處理

我們需要對測試圖像進行同樣的預處理:

python

運行

# 預處理測試圖像
c_test = np.array(c_gray).reshape(-1, 400).astype(np.float32)

使用 OpenCV 的 KNN 進行識別

OpenCV 庫中內置了 KNN 算法的實現:

python

運行

# 創建并訓練OpenCV的KNN模型
knn = cv2.ml.KNearest_create()
knn.train(train_ma, cv2.ml.ROW_SAMPLE, train_la)  # ROW_SAMPLE表示每行是一個樣本# 預測
ret, results, neigh, dist = knn.findNearest(c_test, 4)  # 尋找4個最近鄰
print("OpenCV KNN預測結果:", results)

cv2.ml.KNearest_create()創建一個 KNN 模型實例,train方法用于訓練模型,findNearest方法用于預測。findNearest的第二個參數表示要尋找的最近鄰數量 K。

使用 scikit-learn 的 KNN 進行識別

我們也可以使用 scikit-learn 庫中的 KNN 實現:

python

運行

# 為scikit-learn準備標簽(一維數組)
train_la = np.repeat(kernel, 250)
test_la = np.repeat(kernel, 250)# 創建并訓練scikit-learn的KNN模型
knnl = KNeighborsClassifier(n_neighbors=5)  # K=5
knnl.fit(train_ma, train_la)# 評估模型準確率
a = knnl.score(test_ma, test_la)
print("模型準確率:", a)# 預測
b = knnl.predict(c_test)
print("scikit-learn KNN預測結果:", b)

scikit-learn 的 KNN 使用起來更加簡潔,KNeighborsClassifiern_neighbors參數指定 K 值,fit方法用于訓練,score方法用于評估模型準確率,predict方法用于預測。

總代碼

import numpy as np
import cv2
from sklearn.neighbors import KNeighborsClassifier
img = cv2.imread(r'D:\pythonProject11\class\aa.png')
c_img = cv2.imread(r'D:\pythonProject11\class\ccc.png')
# c_img = cv2.imread('img_1.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#轉化為灰度圖像
c_gray = cv2.cvtColor(c_img,cv2.COLOR_BGR2GRAY)
c_test = np.array(c_gray).reshape(-1,400).astype(np.float32)cell =np.array([np.hsplit(row,100) for row innp.split(gray,50)])
train_ma = cell[:,:50]
test_ma = cell[:,50:100]
train_ma = train_ma.reshape(-1,400).astype(np.float32)
test_ma = test_ma.reshape(-1,400).astype(np.float32)
kernel = np.arange(10)
train_la = np.repeat(kernel,250)[:,np.newaxis]#cv2的方法
test_la = np.repeat(kernel,250)[:,np.newaxis]
knn = cv2.ml.KNearest_create()
knn.train(train_ma,cv2.ml.ROW_SAMPLE,train_la)#cv2.mL.ROW_SAMPLE:這是一個標志,告訴0pencv訓練數據是按行組織的,即每一行是一個樣本。
ret, results, neigh, dist = knn.findNearest(c_test,4)
print(results)
train_la = np.repeat(kernel,250)#sklearn的方法
test_la = np.repeat(kernel,250)
knnl = KNeighborsClassifier(n_neighbors=5)
knnl.fit(train_ma,train_la)
a=knnl.score(test_ma,test_la)
b=knnl.predict(c_test)
print(a,b)

兩種實現的對比

  1. 接口設計:OpenCV 的 KNN 接口更偏向于計算機視覺領域的使用習慣,而 scikit-learn 的接口則更符合機器學習的通用范式。

  2. 輸入格式:OpenCV 的 KNN 要求標簽是列向量,而 scikit-learn 的 KNN 要求標簽是一維數組。

  3. 功能:scikit-learn 的 KNN 提供了更多的評估方法和參數設置,而 OpenCV 的 KNN 則更輕量,與圖像處理功能結合更緊密。

  4. 結果:在相同的 K 值設置下,兩種實現的預測結果應該是相似的,但可能會因為具體實現細節的不同而略有差異。

總結

本文介紹了如何使用 OpenCV 進行圖像預處理,以及如何使用 KNN 算法實現數字識別。通過對比 OpenCV 和 scikit-learn 中 KNN 的實現,我們可以看到不同庫在接口設計和使用方式上的差異。

在實際應用中,我們可以根據具體需求選擇合適的庫和算法。如果需要處理圖像并進行簡單的分類,OpenCV 的 KNN 可能是一個不錯的選擇;如果需要更復雜的機器學習功能和更全面的評估方法,scikit-learn 則更為適合。

此外,KNN 算法雖然簡單易懂,但在處理大規模數據集時效率較低。在實際應用中,我們可能需要考慮使用更高效的算法,如 SVM、神經網絡等,以獲得更好的性能。

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

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

相關文章

利用徑向條形圖探索華盛頓的徒步旅行

利用徑向條形圖探索華盛頓的徒步旅行 import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np import pandas as pdfrom matplotlib.cm import ScalarMappable from matplotlib.lines import Line2D from mpl_toolkits.axes_grid1.inset_locator impor…

火狐瀏覽器中國特供版關閉,如何下載 Firefox 國際版?如何備份數據?

火狐瀏覽器中國特供版關閉,如何下載 Firefox 國際版?如何備份數據?各位火狐老用戶注意了!7 月 27 日北京謀智火狐正式發布公告:2025 年 9 月 29 日 24:00 起,中國特供版賬戶服務將徹底關閉,所有…

C語言操作符詳解:從基礎到進階

在C語言中,操作符是構建表達式的基礎,掌握各類操作符的用法、優先級及特性,對寫出高效且正確的代碼至關重要。本文將系統梳理C語言操作符的核心知識點,包含實例代碼與詳細解析,助你徹底搞懂操作符。 1. 操作符的分類 C…

鴻蒙平臺運行Lua腳本

1. 目標 使用 rust 在移動端實現 Lua 腳本的運行。 2. 核心步驟 [Rust Host App]│├── [mLua VM] (通過 mlua 或 rlua 庫嵌入)│ ├── 獨立Lua狀態(隔離執行)│ ├── 受限標準庫(禁用危險函數)│ └── 內存/CPU限…

【Ubuntu】發展歷程

Ubuntu 是一個基于 Debian 的 Linux 發行版,由 Canonical 公司開發和維護。它以其易用性、穩定性和強大的社區支持而著稱。以下是 Ubuntu 從發布以來的主要版本和發展歷程:1. Ubuntu 4.10 "Warty Warthog" (2004)發布日期:2004年10…

k8s下springboot-admin 監控服務部署,客戶端接入

踩坑及解決以下問題 1、客戶端監控信息不顯示,需要暴露監控檢查接口路徑 2、服務端不顯示客戶端日志,需要啟用日志,并指定日志路徑 3、解決在k8s下,客戶端多實例注冊id相同,如2個實例只顯示一個 整體架構 springboot-admin 由服務端和客戶端組成 服務端負責 1、提供 We…

git刪除遠程分支和本地分支

1. git刪除遠程分支 git push origin --delete [branch_name]2. 刪除本地分支 2.1 git branch -d 會在刪除前檢查merge狀態(其與上游分支或者與head)。 git branch -d [branch_name] 2.2 git branch -D 直接刪除 git branch -D 是 git branch --delete…

Go 的時間包:理解單調時間與掛鐘時間

Go 的時間包:理解單調時間與掛鐘時間 📅 引言 Go 語言自版本 1.9 起在 time.Time 中同時支持 “掛鐘時間(wall?clock)” 和 “單調時間(monotonic clock)”,用于分別滿足時間戳與時間間隔測量…

Android啟動時間優化大全

1 修改Android mksh默認的列長度 不修改這個參數,adb shell后,輸入超過80個字符,就不能看到完整的命令行。external/mksh/src/sh.h EXTERN mksh_ari_t x_cols E_INIT(80); EXTERN mksh_ari_t x_lins E_INIT(24);2 Kernel優化 2.1 內核驅動模塊…

matplotlib.pyplot: 底層原理簡析與進階技巧

文章目錄 1 底層實現原理 1.1 核心架構 1.1 渲染流程 2 基礎用法 2.1 基本繪圖 2.2 多子圖系統 2.3 高階用法 2.3.1 自定義Artist對象 2.3.2 高級動畫技術 2.3.3 事件處理系統 2.3.4 混合渲染技術 3 性能優化技巧 4 擴展模塊 5 總結 5.1 底層原理關鍵點 5.2 進階技巧 1 底層實現…

深入理解現代前端開發中的 <script type=“module“> 與構建工具實踐

引言:模塊化開發的演進在早期的前端開發中,JavaScript 缺乏原生的模塊化支持,開發者不得不依賴 IIFE(立即調用函數表達式)或第三方庫(如 RequireJS)來實現代碼組織。隨著 ES6(ES2015…

yolo--qt可視化開發

qt5可能不支持我們的cuda版本,改用qt6 YOLO11QT6OpencvC訓練加載模型全過程講解_yolov11 模型轉換成opencv c模型-CSDN博客 下面是qt5版本的案例,和yolo及cuda有沖突 安裝qt 切換到虛擬環境,例如pyqt,conda activate pyqt pip …

SQL性能優化

show [session|global] status : 查看服務器狀態 show global status like Com_ : 查看各種語句的執行次數 開啟慢查詢: 在 MySQL 配置文件(/etc/my.cnf)配置: #開啟MySQL慢日志查詢開關 slow_query_log1 #設置慢日志的時間為2秒,SQL語句執…

ctfshow pwn40

目錄 1. 分析程序 2. 漏洞編寫 3. 漏洞驗證 1. 分析程序 首先檢查程序相關保護,發現程序為32位且只開啟了一個NX保護 checksec pwn 使用IDA進行逆向分析代碼,查看漏洞觸發點: 在main函數中,有一個ctfshow函數,這里…

SQL173 店鋪901國慶期間的7日動銷率和滯銷率

SQL173 店鋪901國慶期間的7日動銷率和滯銷率 SQL題解:店鋪動銷率與滯銷率計算 關鍵:只要當天任一店鋪有任何商品的銷量就輸出該天的結果,即使店鋪901當天的動銷率為0。 潛臺詞:?輸出邏輯與店鋪901的銷售情況無關,只取…

PytorchLightning最佳實踐基礎篇

PyTorch Lightning(簡稱 PL)是一個建立在 PyTorch 之上的高層框架,核心目標是剝離工程代碼與研究邏輯,讓研究者專注于模型設計和實驗思路,而非訓練循環、分布式配置、日志管理等重復性工程工作。本文從基礎到進階&…

Apache Flink 實時流處理性能優化實踐指南

Apache Flink 實時流處理性能優化實踐指南 隨著大數據和實時計算需求不斷增長,Apache Flink 已經成為主流的流處理引擎。然而,在生產環境中,高并發、大吞吐量和低延遲的業務場景對 Flink 作業的性能提出了更高要求。本文將從原理層面深入解析…

ubuntu上將TempMonitor加入開機自動運行的方法

1.新建一個TempMonitor.sh文件,內容如下:#!/bin/bashcd /fjrobot/ ./TempMonitor &2.執行以下命令chmod x TempMonitor chmod x TempMonitor.sh rm -rf /etc/rc2.d/S56TempMonitor rm -rf /etc/init.d/TempMonitor cp /fjrobot/TempMonitor.sh /etc/…

速賣通自養號測評技術解析:IP、瀏覽器與風控規避的實戰方案

一、速賣通的“春天”來了,賣家如何抓住機會?2025年的夏天,速賣通的風頭正勁。從沙特市場躍升為第二大電商平臺,到8月大促返傭力度升級,平臺對優質商家的扶持政策越來越清晰。但與此同時,競爭也愈發激烈——…

adb: CreateProcessW failed: 系統找不到指定的文件

具體錯誤 adb devices * daemon not running; starting now at tcp:5037 adb: CreateProcessW failed: 系統找不到指定的文件。 (2) * failed to start daemon adb.exe: failed to check server version: cannot connect to daemon 下載最新的platform-tools-windows 下載最新…