C语言实现HOG特征提取

5星 · 超过95%的资源 需积分: 50 384 下载量 160 浏览量 更新于2024-09-11 4 收藏 3KB TXT 举报
"这篇文章主要介绍了如何使用C语言实现HOG(Histogram of Oriented Gradients,方向梯度直方图)特征提取的过程。代码处理的是IPLImage格式的单通道图像,要求输入图像尺寸大于4*4,输出为9*9大小的图像(81维特征)。代码中涉及到对图像进行x方向和y方向的梯度计算,以及角度计算和归一化步骤,可以适配调整为处理其他格式的图像。" HOG特征提取是一种在计算机视觉领域广泛应用的特征描述符,主要用于目标检测,尤其是行人检测。它的基本思想是通过计算和统计图像局部区域的梯度方向直方图来描述图像特征。下面是这段C代码实现HOG特征提取的关键步骤: 1. **梯度计算**:首先,代码分别计算了图像在x和y方向的梯度。对于x方向梯度,使用中心像素与左右相邻像素的差值;对于y方向梯度,采用上、下相邻行的像素差值。为了处理边缘,代码在计算时对首尾像素进行了特殊处理。 ```c xsub[y*wi+x]=(unsignedchar)(pImg->imageData+y*ki)[x+1]-(unsignedchar)(pImg->imageData+y*ki)[x-1]; ysub[y*wi+x]=(unsignedchar)(pImg->imageData+(y+1)*ki)[x]-(unsignedchar)(pImg->imageData+(y-1)*ki)[x]; ``` 2. **角度计算**:接下来,使用`atan2()`函数计算每个像素点的梯度角度,这一步是将梯度的大小转换为方向信息。 ```c ang[y*wi+x]=atan2((double)ysub[y*wi+x],(double)xsub[y*wi+x]); ``` 3. **归一化**:通常,HOG特征提取还包括细胞归一化和块归一化步骤,以提高特征的鲁棒性。在这个例子中,可能会有一个后续的步骤来执行这个过程,但具体实现没有在提供的代码中给出。归一化通常包括计算每个小细胞(cell)内梯度直方图的总和,并用这个总和来标准化每个bin的值。 4. **直方图构建**:最后,根据计算出的梯度角度,构建方向直方图。在标准的HOG方法中,通常使用9个bins来表示0到180度的范围。 5. **块结构**:HOG特征通常在一个更大的“块”结构中组织,其中多个细胞的直方图被组合在一起,然后进行进一步的归一化。这有助于消除光照变化和局部形状的影响。 6. **维度计算**:由于输出是9*9的图像,意味着每个像素点对应一个9-bin的直方图,因此每个像素点的特征向量是9维的。如果图像有多个这样的块,最终的特征向量将是所有块中像素点特征向量的串联,形成81维特征向量。 这段代码提供了一个基础的HOG特征提取实现,但实际应用中可能需要对参数进行调整,如细胞大小、块大小、直方图bins数量等,以适应不同的任务需求。此外,为了提高效率和兼容性,开发者可能会选择使用像OpenCV这样的库来实现HOG,OpenCV提供了现成的接口来执行完整的HOG特征提取流程。

import cv2 from skimage.feature import hog from sklearn.neighbors import KNeighborsClassifier import joblib import numpy as np # 加载已经训练好的分类器 model_location = "C:/Users/27745/数字图像处理/knn.pkl" knn = joblib.load(model_location) def predict_digit(image): #获取一幅手写数字图像的输入,返回预测结果 # 将图像转换为灰度图 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 应用高斯模糊和大津二值化来预处理图像 blur = cv2.GaussianBlur(gray, (5, 5), 0) _, thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # Find the contours and sort them largest-to-smallest contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours = sorted(contours, key=lambda ctr: cv2.boundingRect(ctr)[0]) # 提取每个字符的 ROI 并使用 HOG 特征提取方法进行特征提取 features = [] for cnt in contours: (x, y, w, h) = cv2.boundingRect(cnt) # 添加一定的边框,避免过小的ROI被压缩过多而失去特征 border_size = 20 roi = thresh[max(y - border_size, 0):min(y + h + border_size, image.shape[0]), max(x - border_size, 0):min(x + w + border_size, image.shape[1])] # 将ROI调整为28x28大小,并根据特征提取器生成的HOG描述符提取特征 resized_roi = cv2.resize(roi, (28, 28), interpolation=cv2.INTER_AREA) fd = hog(resized_roi, orientations=9, pixels_per_cell=(8, 8), cells_per_block=(2, 2), block_norm='L2-Hys') features.append(fd.reshape(-1, 1)) # 将提取的特征向量输入KNN模型进行预测 results = knn.predict(np.hstack(features)) # 返回数字串预测结果 return ''.join(str(result) for result in results) # 载入测试图片并进行预测 image_name = "C:/Users/27745/Desktop/test1.png" image = cv2.imread(image_name) # 将目标图像统一调整为相同的大小 image = cv2.resize(image, (300, 300)) # 利用封装的函数进行预测 result = predict_digit(image) print("The number is:", result)以上代码出现了X has 216 features, but KNeighborsClassifier is expecting 784 features as input.的问题,请帮我更正

2023-05-24 上传
cijixinpianku
  • 粉丝: 0
  • 资源: 1
上传资源 快速赚钱