如何在cv2.HOGDescriptor中使用自定义SVM检测器?遇尺寸断言错误
自定义HOG-SVM检测器报错:checkDetectorSize()断言失败
问题背景
我正在学习HOG相关内容,尝试用自定义训练的SVM目标检测器替代cv2.HOGDescriptor_getDefaultPeopleDetector()。官方示例代码如下:
hog = cv2.HOGDescriptor() hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
但在应用自定义检测器时遇到了问题。
训练阶段代码
# 即使使用默认参数(不传入任何参数),问题仍然存在 hog = cv2.HOGDescriptor(_winSize = (64, 64), _blockSize = (16, 16), _blockStride = (2, 2), _cellSize = (8, 8), _nbins = 9) # 所有正负样本图像均为裁剪后的边界框,已调整大小为(128, 128) positive_features = np.array([hog.compute(img) for img in positive_images]) negative_features = np.array([hog.compute(img) for img in negative_images]) feature_matrix = np.concatenate((positive_features, negative_features), axis=0) labels = np.concatenate((np.zeros(len(positive_features)), np.ones(len(negative_features))), axis=0) # 这违反直觉,但OpenCV SVM配合cv2.detectMultiScale()使用时,似乎期望正类为0,负类为1 train_matrix = np.concatenate((feature_matrix, np.expand_dims(labels, 0).T), axis = 1) np.random.seed(int(SEED)) np.random.shuffle(train_matrix) feature_matrix = train_matrix[:, :-1] labels = train_matrix[:, -1] # OpenCV格式处理 feature_matrix = feature_matrix.astype(np.float32) # 转换为32位浮点数 labels = labels.astype(np.int32) # 将标签转换为32位有符号整数 model = cv2.ml.SVM_create() model.setType(cv2.ml.SVM_C_SVC) model.setKernel(cv2.ml.SVM_LINEAR) model.setTermCriteria((cv2.TERM_CRITERIA_MAX_ITER, 100, 1e-6)) model.train(feature_matrix, cv2.ml.ROW_SAMPLE, labels) model.save("model.svm")
预测阶段代码
# 即使使用默认参数(不传入任何参数),问题仍然存在 hog = cv2.HOGDescriptor(_winSize = (64, 64), _blockSize = (16, 16), _blockStride = (2, 2), _cellSize = (8, 8), _nbins = 9) model = cv2.ml.SVM_load("model.svm") support_vectors = model.getSupportVectors() coefficients = -model.getDecisionFunction(0)[0] coefficients = np.array(coefficients).reshape(1, -1) svmdetector = np.concatenate((support_vectors, coefficients), axis=1) hog.setSVMDetector(svmdetector.T.flatten())
报错信息
hog.setSVMDetector(svmdetector.T.flatten()) cv2.error: OpenCV(4.7.0) /io/opencv/modules/objdetect/src/hog.cpp:120: error: (-215:Assertion failed) checkDetectorSize() in function 'setSVMDetector'
查看OpenCV源码,错误来自checkDetectorSize()函数,其定义如下:
bool HOGDescriptor::checkDetectorSize() const { size_t detectorSize = svmDetector.size(), descriptorSize = getDescriptorSize(); return detectorSize == 0 || detectorSize == descriptorSize || detectorSize == descriptorSize + 1; }
另外还发现一个奇怪现象:
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector()) # 正常工作 [形状: (3781,)] hog.setSVMDetector(cv2.HOGDescriptor_getDaimlerPeopleDetector()) # 无法工作 [形状: (1981,)]
内容的提问来源于stack exchange,提问作者hafiz031
相关产品推荐
相关产品推荐

