唐山网站制作工具,大连网站空间,站长工具seo综合查询怎么看数据,西安百度推广外包hog适合做行人的识别和车辆识别 对一定区域的形状描述方法
可以表示较大的形状 把图像分成一个一个小的区域的直方图
用cell做单位做直方图
计算各个像素的梯度强度和方向
用3*3的像素组成一个cell 3*3的cell组成一个block来归一化 提高亮度不变性
常用SVM分类器一起使用…hog适合做行人的识别和车辆识别 对一定区域的形状描述方法
可以表示较大的形状 把图像分成一个一个小的区域的直方图
用cell做单位做直方图
计算各个像素的梯度强度和方向
用3*3的像素组成一个cell 3*3的cell组成一个block来归一化 提高亮度不变性
常用SVM分类器一起使用 进行行人分类
代码思路
将图像分成cell为单位 例如把图像分成9*9像素的cell为单位。用sobel计算梯度大小和方向。
遍历每一个cell一个cell可以分8类用角度当作数组的下标也就是分类的依据数组的大小也就是分类的一个类的大小就是梯度的大小相加。
计算两个图的直方图的直方图距离的大小累加值 计算hog直方图函数
int calcHOG(cv::Mat src, float* hist, int nAngle, int cellSize)
{int nX src.cols / cellSize;int nY src.rows / cellSize;int binAngle 360 / nAngle;Mat gx, gy;Mat mag, angle;Sobel(src, gx, CV_32F, 1, 0, 1);Sobel(src, gy, CV_32F, 0, 1, 1);cartToPolar(gx, gy, mag, angle, true);Rect roi;roi.x 0;roi.y 0;roi.width cellSize;roi.height cellSize;for (int i 0; i nY; i) {for (int j 0; j nX; j) {Mat roiMat;Mat roiMag;Mat roiAgl;roi.x j * cellSize;roi.y i * cellSize;//赋值图像roiMat src(roi);roiMag mag(roi);roiAgl angle(roi);//当前cell第一个元素在数组中的位置int head (i * nX j) * nAngle;for (int n 0; n roiMat.rows; n) {for (int m 0; m roiMat.cols; m) {//计算角度在哪个bin通过int自动取整实现int pos (int)(roiAgl.atfloat(n, m) / binAngle);//以像素点的值为权重hist[head pos] roiMag.atfloat(n, m);}}}}return 0;} mag梯度大小强度 angle是角度的mat
传入的参数就是图像直方图数组分成几个angle类型一般是8个cell的大小。
计算两个直方图的距离
float normL2(float* Hist1, float* Hist2, int size)
{float sum 0;for (int i 0; i size; i) {sum (Hist1[i] - Hist2[i]) * (Hist1[i] - Hist2[i]);}sum sqrt(sum);return sum;
} 第一种是自己申明数组 然后做hog Mat temple imread(hogTemplate.jpg,0);Mat img1 imread(img1.jpg,0);Mat img2 imread(img2.jpg,0);float his[3000] { 0 };float his1[3000] { 0 };float his2[3000] { 0 };printf(%d %d\r\n,temple.cols,temple.rows);calcHOG(temple, his, 8, 9);calcHOG(img1, his1, 8, 9);calcHOG(img2, his2, 8, 9);float summ normL2(his, his1, 3000);float summ2 normL2(his, his2, 3000);cout summ \r\n endl;cout ------ endl;cout summ2 \r\n endl; 用动态开辟内存数组来进行hog int nX refMat.cols / blockSize;int nY refMat.rows / blockSize;int bins nX * nY * nAngle;float* ref_hist new float[bins];memset(ref_hist, 0, sizeof(float) * bins);float* pl_hist new float[bins];memset(pl_hist, 0, sizeof(float) * bins);float* bg_hist new float[bins];memset(bg_hist, 0, sizeof(float) * bins); 这是比较关键的代码 就是动态开辟一个内存 delete[] ref_hist;delete[] pl_hist;delete[] bg_hist;destroyAllWindows();
记得要释放内存
完整代码 cv::Mat refMat imread(hogTemplate.jpg);cv::Mat plMat imread(img1.jpg);cv::Mat bgMat imread(img2.jpg);int nAngle 8;int blockSize 9;int nX refMat.cols / blockSize;int nY refMat.rows / blockSize;int bins nX * nY * nAngle;float* ref_hist new float[bins];memset(ref_hist, 0, sizeof(float) * bins);float* pl_hist new float[bins];memset(pl_hist, 0, sizeof(float) * bins);float* bg_hist new float[bins];memset(bg_hist, 0, sizeof(float) * bins);int reCode 0;reCode calcHOG(refMat, ref_hist, nAngle, blockSize);reCode calcHOG(plMat, pl_hist, nAngle, blockSize);reCode calcHOG(bgMat, bg_hist, nAngle, blockSize);float dis1 normL2(ref_hist, pl_hist, bins);float dis2 normL2(ref_hist, bg_hist, bins);std::cout distance between reference and img1: dis1 std::endl;std::cout distance between reference and img2: dis2 std::endl;(dis1 dis2) ? (std::cout img1 is similar std::endl) : (std::cout img2 is similar std::endl);delete[] ref_hist;delete[] pl_hist;delete[] bg_hist;destroyAllWindows();return 0;
}有没有很疑惑 为啥两种计算的方式 他们hog值不一样
因为第一种我把他灰度化了 所以值偏低我们现在把第二种方法的也灰度化 ok 简直一摸一样 结束实验