You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

摄像头输入手写数字识别:SVC维度错误(数组维度4,要求≤2)求助

问题分析与解决

核心错误原因

  1. 输入维度不匹配:SVM分类器(SVC)要求输入是2维数组(形状为(样本数, 特征数)),但你的代码里把处理后的图像reshape成了4维(1,28,28,1),直接触发了Found array with dim 4. SVC expected <=2的错误。
  2. 训练与预测的图像尺寸不匹配:你用的digits数据集是8×8的灰度图,每个样本展开为64维特征(digits['data']形状为(1797, 64)),但你把摄像头采集的图像缩成了28×28,即使展开也会是784维,和训练时的特征维度完全不兼容,就算解决维度问题,模型也无法正确预测。

修正步骤

1. 统一图像尺寸与训练数据一致

将摄像头采集的图像缩放到8×8,和digits数据集的图像尺寸匹配。

2. 正确调整输入维度

把处理后的8×8图像展开为1×64的2维数组,符合SVC的输入要求。

3. 修正代码中的其他问题

  • cap.release()和cv2.destroyAllWindows()放在了while循环内部,会导致摄像头刚启动就被释放,移到循环外。
  • SVC的predict()方法直接返回预测的类别标签,不需要用np.argmax()处理。

修正后的完整代码

from sklearn import svm
from sklearn import datasets
import numpy as np
import cv2
from skimage import img_as_ubyte    
from skimage.color import rgb2gray

# 训练SVM模型
svc = svm.SVC(gamma=0.001, C=100.)
digits = datasets.load_digits()
x = digits['data']
y = digits['target']
svc.fit(x, y)

# 摄像头配置
width = 640
height = 480
cameraNo = 0
 
cap = cv2.VideoCapture(cameraNo)
cap.set(3, width)
cap.set(4, height)

while True:
    success, img_orig = cap.read()
    if not success:
        break  # 读取失败时退出循环
    
    # 图像预处理
    img_gray = rgb2gray(img_orig)
    img_gray_u8 = img_as_ubyte(img_gray)
    (thresh, im_binary) = cv2.threshold(img_gray_u8, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    # 缩放到8×8,和训练数据尺寸一致
    img_resized = cv2.resize(im_binary, (8, 8))
    im_gray_invert = 255 - img_resized
    cv2.imshow("invert image", im_gray_invert)
    
    # 调整为SVC要求的输入形状:(1, 64)
    im_final = im_gray_invert.flatten().reshape(1, -1)
    # 直接预测,不需要argmax
    ans = svc.predict(im_final)[0]
    print(ans)
    
    # 在原图上显示预测结果
    cv2.putText(img_orig, 'Predicted Digit : ' + str(ans),
                (50, 50), cv2.FONT_HERSHEY_COMPLEX,
                1, (0, 0, 255), 1)
    cv2.imshow("Original Image", img_orig)
    
    # 按q退出
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放资源,放在循环外
cap.release()
cv2.destroyAllWindows()

可选优化:改用MNIST数据集(28×28)

如果你想保留28×28的图像尺寸,可以改用MNIST数据集训练SVM,示例代码如下:

from sklearn import svm
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split

# 加载MNIST数据集(28×28)
mnist = fetch_openml('mnist_784', version=1, cache=True, as_frame=False)
x = mnist.data / 255.0  # 归一化
y = mnist.target
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)

# 训练SVM
svc = svm.SVC(gamma=0.001, C=100.)
svc.fit(x_train, y_train)

# 后续摄像头处理部分,只需要把图像缩成28×28,然后展开为1×784即可
# im_final = im_gray_invert.flatten().reshape(1, -1)

内容的提问来源于stack exchange,提问作者william makarius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 17:54:28