`
grunt1223
  • 浏览: 421947 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

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

阅读更多
方向梯度直方图(Histograms of Oriented Gradients,简称HOG特征)结合支持向量机( support vector machine, 简称SVM),被广泛应用于图像识别中,尤其在行人检测中获得了极大的成功。

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

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

/*Function to calculate the integral histogram*/
IplImage** calculateIntegralHOG(IplImage* in)
{
    /*Convert the input image to grayscale*/
    IplImage* img_gray = cvCreateImage(cvGetSize(in), IPL_DEPTH_8U,1);
    cvCvtColor(in, img_gray, CV_BGR2GRAY);
    cvEqualizeHist(img_gray,img_gray);

/*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*/

    IplImage *xsobel, *ysobel;
    xsobel = doSobel(img_gray, 1, 0, 3);
    ysobel = doSobel(img_gray, 0, 1, 3);
    cvReleaseImage(&img_gray);


/* 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 */

    IplImage** bins = (IplImage**) malloc(9 * sizeof(IplImage*));
    for (int i = 0; i < 9 ; i++) {
        bins[i] = cvCreateImage(cvGetSize(in), IPL_DEPTH_32F,1);
        cvSetZero(bins);
    }


/* 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 */

    IplImage** integrals = (IplImage**) malloc(9 * sizeof(IplImage*)); 
    for (int i = 0; i < 9 ; i++) {
        integrals[i] = cvCreateImage(cvSize(in->width + 1, in->height + 1),
        IPL_DEPTH_64F,1);
    }

/* 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 */

    int x, y;
    float temp_gradient, temp_magnitude;
    for (y = 0; y < in->height; y++) {

/* 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 */

        float* ptr1 = (float*) (xsobel->imageData + y * (xsobel->widthStep));
        float* ptr2 = (float*) (ysobel->imageData + y * (ysobel->widthStep));
        float** ptrs = (float**) malloc(9 * sizeof(float*));
        for (int i = 0; i < 9 ;i++){
            ptrs[i] = (float*) (bins[i]->imageData + y * (bins->widthStep));
        }

/*For every pixel in a row gradient orientation and magnitude are calculated and corresponding values set for the bin images. */

        for (x = 0; x <in->width; x++) {

/* 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. */

            if (ptr1[x] == 0){
                temp_gradient = ((atan(ptr2[x] / (ptr1[x] + 0.00001))) * (180/   PI)) + 90;
            }
            else{
                temp_gradient = ((atan(ptr2[x] / ptr1[x])) * (180 / PI)) + 90;
            }
            temp_magnitude = sqrt((ptr1[x] * ptr1[x]) + (ptr2[x] * ptr2[x]));

/*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 */

            if (temp_gradient <= 20) {
                ptrs[0][x] = temp_magnitude;
            }
            else if (temp_gradient <= 40) {
                ptrs[1][x] = temp_magnitude;
            }
            else if (temp_gradient <= 60) {
                ptrs[2][x] = temp_magnitude;
            }
            else if (temp_gradient <= 80) {
                ptrs[3][x] = temp_magnitude;
            }
            else if (temp_gradient <= 100) {
                ptrs[4][x] = temp_magnitude;
            }
            else if (temp_gradient <= 120) {
                ptrs[5][x] = temp_magnitude;
            }
            else if (temp_gradient <= 140) {
                ptrs[6][x] = temp_magnitude;
            }
            else if (temp_gradient <= 160) {
                ptrs[7][x] = temp_magnitude;
            }
            else {
                ptrs[8][x] = temp_magnitude;
            }
        }
    }

    cvReleaseImage(&xsobel);
    cvReleaseImage(&ysobel);

/*Integral images for each of the bin images are calculated*/

    for (int i = 0; i <9 ; i++){
        cvIntegral(bins[i], integrals[i]);
    }

    for (int i = 0; i <9 ; i++){
        cvReleaseImage(&bins[i]);
    }

/*The function returns an array of 9 images which consitute the integral histogram*/

    return (integrals);

}


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

/* 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 */

void calculateHOG_rect(CvRect cell, CvMat* hog_cell,
IplImage** integrals, int normalization) {

/* Calculate the bin values for each of the bin of the histogram one by one */

    for (int i = 0; i < 9 ; i++){

        float a =((double*)(integrals[i]->imageData + (cell.y) * (integrals->
            widthStep)))[cell.x];

        float b = ((double*) (integrals->imageData + (cell.y + cell.height) * 
            (integrals->widthStep)))[cell.x + cell.width];

        float c = ((double*) (integrals->imageData + (cell.y) * (integrals- 
            >widthStep)))[cell.x + cell.width];

        float d = ((double*) (integrals->imageData + (cell.y + cell.height) * 
            (integrals->widthStep)))[cell.x];

        ((float*) hog_cell->data.fl) = (a + b) - (c + d);

    }


    /*Normalize the matrix*/
    if (normalization != -1){
        cvNormalize(hog_cell, hog_cell, 1, 0, normalization);
    }

}
1
5
分享到:
评论

相关推荐

    opencv直方图计算

    本篇文章将深入探讨如何在Visual Studio 2010环境下使用OpenCV库实现图像直方图的计算,并介绍相关知识点。 1. **OpenCV简介** OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,包含了...

    Opencv3.0 手写数字识别(Hog特征+SVM分类器)

    在本文中,我们将深入探讨如何使用OpenCV 3.0库进行手写数字识别,主要依赖于HOG(Histogram of Oriented Gradients)特征和SVM(Support Vector Machine)分类器。手写数字识别是计算机视觉领域的一个经典问题,...

    OpenCV计算机视觉学习(9)——图像直方图 & 直方图均衡化 - 战争热诚 - 博客园1

    本文主要介绍了OpenCV中的图像直方图和直方图均衡化概念,这两个技术在计算机视觉领域中用于改善图像的对比度和视觉效果。 1. 图像直方图的概念: 图像直方图是一种统计图像中像素灰度值分布的方法,它可以清晰地...

    VS2013+OPENCV2.4.10 提取HOG特征使用SVM多分类手势识别

    HOG特征是OpenCV中用于物体检测的一种有效方法,它通过计算图像局部区域中梯度的方向直方图来捕捉物体边缘和形状信息。HOG特征对光照变化、部分遮挡具有较好的鲁棒性,因此在行人检测、手势识别等领域得到广泛应用。...

    opencv基于颜色直方图进行模板图像匹配检测的程序

    颜色直方图是一种统计图像中颜色分布的方法,通过计算每个颜色通道的像素数量,可以形成一个反映图像颜色特征的图形。这种方法在图像检索、对象识别和图像分类等任务中非常有用。 首先,我们来理解颜色直方图的基本...

    HOG_opencv_HOG特征_图像处理_

    本篇将深入探讨HOG(Histogram of Oriented Gradients,方向梯度直方图)特征以及如何在OpenCV中实现这一技术。 **HOG特征详解** HOG特征是一种用于物体检测的强大局部特征描述符,由Dalal和Triggs于2005年提出。...

    人脸图像的HOG特征提取

    人脸图像的HOG(Histogram of Oriented Gradients,导向梯度直方图)特征提取是一种在计算机视觉领域广泛用于行人检测、人脸识别等任务的特征描述方法。它通过计算和统计图像局部区域内的梯度方向直方图来描述图像...

    openCV人脸跟踪小项目——打开摄像头标出人脸位置并跟踪

    在这个特定的项目中,“openCV人脸跟踪小项目——打开摄像头标出人脸位置并跟踪”,我们将会探讨如何使用OpenCV实现人脸检测和跟踪。这个项目包含了以下几个关键知识点: 1. **人脸检测**:OpenCV中的人脸检测主要...

    OpenCV_HOG.rar_hog算子_opencv 梯度_梯度 直方图_梯度直方图

    OpenCV提供了实现HOG算子的函数`cv::HOGDescriptor`,它包括了计算梯度、构建直方图、块归一化等一系列步骤。使用这个类,开发者可以轻松地应用HOG特征提取到自己的项目中。 文件`OpenCV_HOG.pdf`很可能包含了关于...

    基于opencv的图像直方图显示与直方图均衡

    基于opencv的图像直方图显示与直方图均衡 下载必看: 1.程序默认处理的是灰度图像,彩色图像将转换成灰度图处理 2.程序基于opencv2.2的c++ API编写,编译前确保你配置的是opencv2.x环境,1.0没试过。

    基于opencv的彩色图像直方图均衡

    3. **计算直方图**:使用`cv::calcHist()`函数计算灰度图像的直方图,这有助于了解图像像素分布情况。 4. **直方图均衡化**:对灰度图像的直方图应用`cv::equalizeHist()`函数进行均衡化处理。 5. **恢复彩色**:将...

    OPENCV输出直方图

    这个函数接受一个或多个输入图像、一个表示每个图像通道上考虑的范围的边界向量、一个表示在哪个通道上计算直方图的向量,以及一个直方图的大小。例如,对于灰度图像,我们可能只有一个通道;对于彩色图像,如BGR,...

    VS2013+opencv2.4.10提取HOG特征使用KNN识别手势

    在本文中,我们将深入探讨如何使用Visual Studio 2013(VS2013)结合OpenCV 2.4.10库来提取手部姿势的HOG(Histogram of Oriented Gradients)特征,并利用KNN(K-Nearest Neighbor)算法进行离线识别。HOG特征是一...

    基于OPENCV的计算图像颜色直方图代码

    OpenCV(开源计算机视觉库)是一个强大的跨平台库,提供了丰富的功能来处理图像和视频,包括计算颜色直方图。这个基于OpenCV和Visual C++(VC)的小程序就是用来实现这一功能的。 颜色直方图是通过统计图像中每个...

    直方图规定化

    直方图规定化,也称为直方图均衡化,是一种图像处理技术,用于增强图像的对比度,特别是在图像中存在大面积相近灰度值时。它通过改变图像的灰度级分布,使得整个图像的灰度级更加均匀,从而提高图像的可读性和视觉...

    基于Android的OpenCV图像直方图均衡的实现

    OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库,网络上一些小伙伴写的一些关于Android版OpenCV的博客,大部分都模糊不清,基本就复制粘贴的,有些甚至没有实践就直接贴上去了,这样...

    利用OpenCV获得图像直方图

    此外,OpenCV还提供了一种叫做累积直方图(cumulative histogram)的方法,这对于计算特定灰度级以下像素的数量非常有用。你可以通过累加直方图值实现这个功能。 总的来说,OpenCV提供的图像直方图功能是图像分析和...

    OPENCV HOG特征-SVM分类器行人识别(从训练到识别).zip

    本教程主要探讨如何使用OpenCV库的HOG(Histogram of Oriented Gradients)特征结合支持向量机(SVM,Support Vector Machine)进行行人识别。下面我们将深入理解HOG特征、SVM分类器以及它们在行人检测中的应用。 ...

Global site tag (gtag.js) - Google Analytics