OpenCV4.2 Java HOG 图像特征提取

什么是HOG特征提取

HOG 即 定向梯度柱状图(Histograms of Oriented Gradients),它是由 Navneet Dalal 和 Bill Triggs 于 2005 年首次引入的。

Hog 算法的工作原理是创建图像中梯度方向分布的柱状图,然后以一种非常特殊的方式对其进行归一化。这种特殊的归一化使得Hog 能够有效地检测物体的边缘,即使在对比度很低的情况下也是如此。这些标准化的柱状图被放在一个特征向量(称为 HOG 描述符)中,可以用来训练机器学习算法,例如支持向量机(SVM),以根据图像中的边界(边)检测对象。由于它的巨大成功和可靠性,HOG 已成为计算机视觉中应用最广泛的目标检测算法之一。

方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。HOG特征通过计算和统计图像局部区域的梯度方向直方图来构成特征。

为什么HOG在对比度很低的情况下能够有效地检测物体的边缘

HOG 通过在图像的局部区域中添加特定方向的梯度大小来创建柱状图,称为“cells”。通过这样做可以保证更强的梯度对它们各自的角度柱状图的大小贡献更大,同时最小化由噪声引起的弱梯度和随机定向梯度的影响。通过这种方式,柱状图告诉我们每个单元格的主要梯度方向。

为了考虑背景-前景对比度的差异,HOG 算法尝试在局部检测边缘。为了做到这一点,它定义了称为块的单元格组,并使用该局部单元格组规范化柱状图。通过局部归一化,HOG 算法可以非常可靠地检测每个块中的边缘,这称为块归一化。

除了使用块规范化之外,HOG 算法还使用重叠块来提高其性能。通过使用重叠块,每个单元为最终的 HOG 描述符提供几个独立的组成部分,其中每个组成部分对应于一个针对不同块进行规范化的单元。这似乎是多余的,但是经验表明,通过对每个单元对不同的局部块进行多次规格化,HOG 算法的性能显著提高。

HOH算法步骤

  1. 给定特定对象的图像,设置一个覆盖图像中整个对象的检测窗口(感兴趣区域)(见下图)。
  2. 计算检测窗口中每个像素的梯度大小和方向。
  3. 将检测窗口分成像素的连接单元格,所有单元格的大小相同(见下图)。单元的大小是一个自由参数,通常选择它来匹配要检测的特征的比例。例如,在一个 64 x 128 像素的检测窗口中,6 到 8 像素宽的方形单元适用于检测人体肢体。
  4. 为每个单元创建一个柱状图,首先将每个单元中所有像素的渐变方向分组为特定数量的方向(角度)箱,然后将每个角度箱中渐变的渐变幅度相加(见下图)。柱状图中的箱数是一个自由参数,通常设置为9个角箱。
  5. 将相邻单元分组成块(见下图)。每个块中的单元格数是一个自由参数,所有块的大小都必须相同。每个块之间的距离(称为跨距)是一个自由参数,但它通常设置为块大小的一半,在这种情况下,将得到重叠块(见动图)。经验表明,该算法能更好地处理重叠块。
  6. 使用每个块中包含的单元格来规范化该块中的单元格柱状图(见下图)。如果有重叠的块,这意味着大多数单元格将针对不同的块进行规格化(见动图)。因此,同一个单元可能有几个不同的归一化。
  7. 将所有块中的所有标准化柱状图收集到一个称为 HOG 描述符的特征向量中。
  8. 使用从包含同一对象的许多图像中得到的 HOG 描述符训练机器学习算法,例如使用 SVM,以检测图像中的这些对象。例如,可以使用来自许多行人图像的 HOG 描述符来训练 SVM 以检测图像中的行人。训练通过使用包含目标的正例和不包含目标的负例完成。
  9. 一旦对支持向量机进行了训练,就使用滑动窗口方法来尝试检测和定位图像中的对象。检测图像中的对象需要找到图像中与 SVM 学习到的 HOG 模式相似的部分。

OpenCV4.2 Java HOG 图像特征提取_第1张图片OpenCV4.2 Java HOG 图像特征提取_第2张图片
以上内容主要来自:https://www.cnblogs.com/alexme/p/11361563.html

OpenCV Java HOG实现

package com.opencv;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfFloat;
import org.opencv.core.Size;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.HOGDescriptor;

public class OpenCvMain {
	
	//静态代码块加载动态链接库
	static {
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
	}

	public static void main(String[] args) {
		/*
		 * IMREAD_UNCHANGED = -1 :不进行转化,比如保存为了16位的图片,读取出来仍然为16位。
		 * IMREAD_GRAYSCALE = 0 :进行转化为灰度图,比如保存为了16位的图片,读取出来为8位,类型为CV_8UC1。
		 * IMREAD_COLOR = 1 :进行转化为三通道图像。
		 * IMREAD_ANYDEPTH = 2 :如果图像深度为16位则读出为16位,32位则读出为32位,其余的转化为8位。
		 * IMREAD_ANYCOLOR = 4 :图像以任何可能的颜色格式读取
		 * IMREAD_LOAD_GDAL = 8 :使用GDAL驱动读取文件,GDAL(Geospatial Data Abstraction
		 * Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库。它利用抽象数据模型来表达所支持的各种文件格式。
		 *	它还有一系列命令行工具来进行数据转换和处理。
		 */
		Mat src = Imgcodecs.imread("D:\\123.jpg");//待匹配图片
		
		HighGui.imshow("原图", src);
		HighGui.waitKey();
		
		Mat gary=new Mat();
		// 图片转为单通道 https://blog.csdn.net/ren365880/article/details/103869207
		Imgproc.cvtColor(src, gary, Imgproc.COLOR_BGR2GRAY);
		
		/*
		 * 初始化特征提取器
		 * @param _winSize 特征提取检测的窗口大小
		 * @param _blockSize 块大小,。
		 * @param _blockStride 检测步长。
		 * @param _cellSize 胞元,胞元是在块中。
		 * @param _nbins 检测方向 在一个胞元内统计9个方向的梯度直方图,每个方向为180/9=20度。
		 * 详细内容可参考:https://blog.csdn.net/qq_26898461/article/details/46786285
		 */
		HOGDescriptor hog=new HOGDescriptor(new Size(64,128), new Size(16,16), new Size(8,8), new Size(8,8), 9);
		MatOfFloat descriptors=new MatOfFloat();
		/*
		 * 计算给定图像的HOG描述符。
		 * @param img类型CV_8U的矩阵,其中包含要计算HOG特征的图像。
		 * @param描述符类型为CV_32F的矩阵
		 * @param winStride窗口跨度。 它必须是跨步的倍数。
		 * @param padding填充
		 */
		hog.compute(gary, descriptors,new Size(0,0),new Size(0,0));
		
		System.out.println(descriptors.size());
	}     
}

你可能感兴趣的:(OpenCV4.2,For,Java,Java,算法,计算机视觉,opencv)