使用opencv作物件识别(一) —— 积分直方图加速HOG特征计算

  • 博客分类:
  • 图像识别、机器学习、数据挖掘
CC++C# 
方向梯度直方图(Histograms of Oriented Gradients,简称HOG特征)结合支持向量机( support vector machine, 简称SVM),被广泛应用于图像识别中,尤其在行人检测中获得了极大的成功。

积分直方图可以用于快速计算原始图像矩形区域内的HOG特征。积分直方图的概念类似与viola和jones在脸部识别中所用的积分图像。

下面的代码给出了,对于一幅给定的图像,如何快速计算积分直方图,以及如何使用其进行HOG特征的演算(关键处以给出注释):

C代码  
  1. /*Function to calculate the integral histogram*/
  2. IplImage** calculateIntegralHOG(IplImage* in)
  3. {
  4. /*Convert the input image to grayscale*/
  5. IplImage* img_gray = cvCreateImage(cvGetSize(in), IPL_DEPTH_8U,1);
  6. cvCvtColor(in, img_gray, CV_BGR2GRAY);
  7. cvEqualizeHist(img_gray,img_gray);
  8. /*Calculate the derivates of the grayscale image in the x and y directions using a sobel operator and obtain 2 gradient images for the x and y directions*/
  9. IplImage *xsobel, *ysobel;
  10. xsobel = doSobel(img_gray, 1, 0, 3);
  11. ysobel = doSobel(img_gray, 0, 1, 3);
  12. cvReleaseImage(&img_gray);
  13. /* Create an array of 9 images (9 because I assume bin size 20 degrees and unsigned gradient ( 180/20 = 9), one for each bin which will have zeroes for all pixels, except for the pixels in the original image for which the gradient values correspond to the particular bin. These will be referred to as bin images. These bin images will be then used to calculate the integral histogram, which will quicken the calculation of HOG descriptors */
  14. IplImage** bins = (IplImage**) malloc(9 * sizeof(IplImage*));
  15. for (int i = 0; i < 9 ; i++) {
  16. bins[i] = cvCreateImage(cvGetSize(in), IPL_DEPTH_32F,1);
  17. cvSetZero(bins);
  18. }
  19. /* Create an array of 9 images ( note the dimensions of the image, the cvIntegral() function requires the size to be that), to store the integral images calculated from the above bin images. These 9 integral images together constitute the integral histogram */
  20. IplImage** integrals = (IplImage**) malloc(9 * sizeof(IplImage*));
  21. for (int i = 0; i < 9 ; i++) {
  22. integrals[i] = cvCreateImage(cvSize(in->width + 1, in->height + 1),
  23. IPL_DEPTH_64F,1);
  24. }
  25. /* Calculate the bin images. The magnitude and orientation of the gradient at each pixel is calculated using the xsobel and ysobel images.{Magnitude = sqrt(sq(xsobel) + sq(ysobel) ), gradient = itan (ysobel/xsobel) }. Then according to the orientation of the gradient, the value of the corresponding pixel in the corresponding image is set */
  26. int x, y;
  27. float temp_gradient, temp_magnitude;
  28. for (y = 0; y < in->height; y++) {
  29. /* ptr1 and ptr2 point to beginning of the current row in the xsobel and ysobel images respectively. ptrs point to the beginning of the current rows in the bin images */
  30. float* ptr1 = (float*) (xsobel->imageData + y * (xsobel->widthStep));
  31. float* ptr2 = (float*) (ysobel->imageData + y * (ysobel->widthStep));
  32. float** ptrs = (float**) malloc(9 * sizeof(float*));
  33. for (int i = 0; i < 9 ;i++){
  34. ptrs[i] = (float*) (bins[i]->imageData + y * (bins->widthStep));
  35. }
  36. /*For every pixel in a row gradient orientation and magnitude are calculated and corresponding values set for the bin images. */
  37. for (x = 0; x <in->width; x++) {
  38. /* if the xsobel derivative is zero for a pixel, a small value is added to it, to avoid division by zero. atan returns values in radians, which on being converted to degrees, correspond to values between -90 and 90 degrees. 90 is added to each orientation, to shift the orientation values range from {-90-90} to {0-180}. This is just a matter of convention. {-90-90} values can also be used for the calculation. */
  39. if (ptr1[x] == 0){
  40. temp_gradient = ((atan(ptr2[x] / (ptr1[x] + 0.00001))) * (180/   PI)) + 90;
  41. }
  42. else{
  43. temp_gradient = ((atan(ptr2[x] / ptr1[x])) * (180 / PI)) + 90;
  44. }
  45. temp_magnitude = sqrt((ptr1[x] * ptr1[x]) + (ptr2[x] * ptr2[x]));
  46. /*The bin image is selected according to the gradient values. The corresponding pixel value is made equal to the gradient magnitude at that pixel in the corresponding bin image */
  47. if (temp_gradient <= 20) {
  48. ptrs[0][x] = temp_magnitude;
  49. }
  50. else if (temp_gradient <= 40) {
  51. ptrs[1][x] = temp_magnitude;
  52. }
  53. else if (temp_gradient <= 60) {
  54. ptrs[2][x] = temp_magnitude;
  55. }
  56. else if (temp_gradient <= 80) {
  57. ptrs[3][x] = temp_magnitude;
  58. }
  59. else if (temp_gradient <= 100) {
  60. ptrs[4][x] = temp_magnitude;
  61. }
  62. else if (temp_gradient <= 120) {
  63. ptrs[5][x] = temp_magnitude;
  64. }
  65. else if (temp_gradient <= 140) {
  66. ptrs[6][x] = temp_magnitude;
  67. }
  68. else if (temp_gradient <= 160) {
  69. ptrs[7][x] = temp_magnitude;
  70. }
  71. else {
  72. ptrs[8][x] = temp_magnitude;
  73. }
  74. }
  75. }
  76. cvReleaseImage(&xsobel);
  77. cvReleaseImage(&ysobel);
  78. /*Integral images for each of the bin images are calculated*/
  79. for (int i = 0; i <9 ; i++){
  80. cvIntegral(bins[i], integrals[i]);
  81. }
  82. for (int i = 0; i <9 ; i++){
  83. cvReleaseImage(&bins[i]);
  84. }
  85. /*The function returns an array of 9 images which consitute the integral histogram*/
  86. return (integrals);
  87. }

如何使用上面的函数来计算9维的方向梯度直方图呢?如下:

C代码  
  1. /* The following function takes as input the rectangular cell for which the histogram of oriented gradients has to be calculated, a matrix hog_cell of dimensions 1x9 to store the bin values for the histogram, the integral histogram, and the normalization scheme to be used. No normalization is done if normalization = -1 */
  2. void calculateHOG_rect(CvRect cell, CvMat* hog_cell,
  3. IplImage** integrals, int normalization) {
  4. /* Calculate the bin values for each of the bin of the histogram one by one */
  5. for (int i = 0; i < 9 ; i++){
  6. float a =((double*)(integrals[i]->imageData + (cell.y) * (integrals->
  7. widthStep)))[cell.x];
  8. float b = ((double*) (integrals->imageData + (cell.y + cell.height) *
  9. (integrals->widthStep)))[cell.x + cell.width];
  10. float c = ((double*) (integrals->imageData + (cell.y) * (integrals-
  11. >widthStep)))[cell.x + cell.width];
  12. float d = ((double*) (integrals->imageData + (cell.y + cell.height) *
  13. (integrals->widthStep)))[cell.x];
  14. ((float*) hog_cell->data.fl) = (a + b) - (c + d);
  15. }
  16. /*Normalize the matrix*/
  17. if (normalization != -1){
  18. cvNormalize(hog_cell, hog_cell, 1, 0, normalization);
  19. }
  20. }

使用opencv作物件识别(一) —— 积分直方图加速HOG特征计算相关推荐

  1. OpenCV For Python识别图片中的米粒个数,并计算米粒的面积平均面积

    精确分割请看分水岭算法实现https://blog.csdn.net/qq_36623595/article/details/109273629 使用OpenCV构建图像识别算法,识别图片中的米粒个数 ...

  2. python opencv 人体/人脸识别 简易demo

    前言 参考文章: pythonopencv检测行人_[图像处理]使用OpenCV实现人脸和行人检测 Python如何实现行人识别-人体识别 本文主要讲述关于opencv官方提供的现成模型,采取Hog特 ...

  3. OpenCV:使用python-cv2+Hog特征+SVM实现狮子识别

    文章目录 SVM Hog特征 Hog特征+SVM实现狮子识别 SVM 支持向量机:寻求一个最优的超平面,实现样本的分类 下面我们用SVM实现一个根据身高体重对男女生分类的问题 import cv2 i ...

  4. svm性别识别及HOG特征原理浅析

     HOG特征原理主要参考http://blog.csdn.net/abcjennifer/article/details/7365651 HOG即histogram of oriented gra ...

  5. 基于LBP纹理特征计算GLCM的纹理特征统计量+SVM/RF识别纹理图片

    作者 | Raini 出品 | 北京图特摩斯科技有限公司 (thutmose.cn) 说在前头: 局部特征检测方法 斑点Blob检测,LoG检测 , DoG,DoH检测,SIFT算法,SUFT算法 边 ...

  6. youcans 的 OpenCV 学习课—6.灰度变换与直方图处理

    youcans 的 OpenCV 学习课-6.灰度变换与直方图处理 本系列面向 Python 小白,从零开始实战解说 OpenCV 项目实战. 空间域的图像处理方法直接对图像的像素点进行处理,空间域图 ...

  7. OpenCV 识别图片中的米粒个数,并计算米粒的平均面积和长度(转)

    介绍 OpenCV+Python 使用OpenCV构建图像识别算法,识别图片中的米粒个数,并计算米粒的平均面积和长度 软件架构 模块:OpenCV 4.0.0.21 编程语言:Python 3.7.2 ...

  8. OpenCV 识别图片中的米粒个数,并计算米粒的平均面积和长度

    介绍 OpenCV+Python 使用OpenCV构建图像识别算法,识别图片中的米粒个数,并计算米粒的平均面积和长度 软件架构 模块:OpenCV 4.0.0.21 编程语言:Python 3.7.2 ...

  9. 【OpenCV 4开发详解】直方图应用

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

最新文章

  1. 除了缺少点创意,GPT-3写出了及格的大学毕业论文,只需20分钟
  2. 对于sync.Mutex使用注意事项
  3. R 包 pathview 代谢通路可视化
  4. keepalived + glusterfs实现高可用
  5. python中的日志操作和发送邮件
  6. Python面向对象反射,双下方法
  7. 分享两个JavaScript打乱数组顺序实现随机排序洗牌的方法(应用于音乐视频的随机播放等)
  8. 33 MM配置-采购-采购订单-定义凭证层的屏幕格式
  9. 美团提出具有「位置编码」的Transformer,性能优于ViT和DeiT
  10. 小一爬取一季度 15646 只基金持仓数据,下半年重点关注这些机会!
  11. SAP License:最近的FICO面试题目
  12. 比特币的服务器作用,比特币白皮书解读-时间戳服务器
  13. QQ音乐下载器、爬虫
  14. svn下载项目到指定文件夹,以及更新提交
  15. 计算机连接网络是飞行模式怎么办,电脑wifi界面只有飞行模式怎么办
  16. eureka自我保护机制EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY‘RE NOT
  17. 制作一个私有的docker habor仓库
  18. 基于snipe-it v5.1.2开源资产管理软件二次开发安卓端管理app
  19. 比Linken Sphere(林肯法球)更多更新浏览器指纹的国产防关联工具-VMLogin中文版
  20. bukgu 杂项 图穷匕见

热门文章

  1. Sql Server 2005的1433端口打开和进行远程连接
  2. client-go入门之2:Job相关操作
  3. Infiniband网络抓包
  4. OVS端口镜像(十五)
  5. OVS DPDK--介绍(二)
  6. Mac-连接Windows远程桌面软件
  7. oracle 连接查询--内连接与外连接
  8. bugzilla迁移需要修改的文件
  9. python requests post 中文乱码问题
  10. 【原创】modb 功能设计之“跨线程通信”