OpenCV3特征提取与目标检测之HOG(一)——HOG的概述与原理

2023-10-30

1.HOG(Histogram of Oriented Gradient)是方向梯度直方图的意思,是一种特性描述子。通过计算与统计图像局部区域的梯度方向直方图来构成特征。边缘是图像颜色剧变的区域,在一副图像中,局部目标的表象与形状能够被梯度或边缘的方向密度分布很好地描述,而梯度主要存在于存在于局部目标边缘的地方。
(1) 局部目标的边缘,可以把图转为灰度图后按二值映射到0和1输出,就很明显的看出来。
在这里插入图片描述
而梯度可分解为 x 方向的梯度 G{x} 和 y 方向的梯度 G{y} 。某个像素点的 x 方向的梯度的计算可以通过这个像素点左右两边的像素值的差值的绝对值计算出来,而 y 方向的梯度可以通过该像素点上下两边的像素值的差值的绝对值计算。而根据下面的两个公式可以计算每一个像素点的梯度方向和梯度幅值。
在这里插入图片描述
(2)直方图是图像中像素强度分布的图形表达方式,一张图像可以看成一个数字矩阵,矩阵的每个元素取值在0~255之间,而用直方图来统计了每个强度值所具有的像素个数。那么已知数字的范围包含256个值,将这个范围分割成子区域就是bins,然后再统计在每一个bin的像素数目。这样统计右边的数字矩阵我们可以得到左图(x轴表示bin, y轴表示各个bin中的像素个数)。
在这里插入图片描述在这里插入图片描述
(3) HOG是通过上面公式计算出来的梯度方向的角度是一个范围在0-360度的弧度值,为了计算简单,将梯度向的范围约束为0-180度,并且分割为9个方向,每个方向20度,再将约束后的角度除以20,则现在的梯度方向角度值就变为范围在[0,9)。
在这里插入图片描述
2.HOG特征提取具体实现方法是将图像分成小的连通区域,叫细胞单元(cell),将每个小Cell里面的梯度幅值按照9个方向进行统计,计算完之后,将会产生一个横坐标X为梯度方向,纵坐标Y为梯度幅值的方向梯度直方图。然后采集细胞单元中各像素点的梯度的或边缘的方向直方图,最后把这些直方图组合起来就可以构成特征描述器。把这些局部直方图在图像的更大的范围内(block)进行对比度归一化。 归一化是为了克服光照不均匀的变化以及前景和背景测对比差异。
大概步骤:
(1)灰度化。
(2)对输入图像进行颜色空间的标准化(归一化);调节图像的对比度,降低图像局部的阴影和光照变化所造成的影响,同时可以抑制噪音的干扰。
(3)计算图像每个像素的梯度(包括大小和方向);主要是为了捕获轮廓信息,同时进一步弱化光照的干扰。
(4)将图像划分成小cells(例如8*8像素/cell)。
(5)统计每个cell的梯度直方图(不同梯度的个数),即可形成每个cell的特性描述子。
(6)将每几个cell组成一个block(2X2个cell/block),一个block内所有cell的特性描述子串联起来便得到该block的HOG特性描述子。
(7)将图像内的所有block的HOG特征描述子串联起来就可以得到该图像的HOG特征描述子。这个就是最终的可供分类使用的特征向量了。
在这里插入图片描述
3.cell、block、windowsSize、stride的关系。
在这里插入图片描述
上图中单个cell的为8X8个像素,把cell对应的方向直方图转换为单维向量,按规定组距对对应方向梯度个数进行编码,得到单个cell的9个特征,每个block包含2X2个cell,那么每个block包含2X2个cell也就是2X2X9=36个特征,而每个block移动(stride)这里选择overlap,就是为2分之一重叠,一个64X128大小的图像横着有15个block,坚着有7个,最后得到的特征数为36X7X15=3780维。
5.代码实现
这时的代码环境是win7 64位,vs2015,opencv3.3。
(1)代码流程
在这里插入图片描述
(2)具体代码
头文件

#pragma once
#include <opencv2\core\core.hpp>
#include <opencv2\highgui.hpp>
#include <opencv2\xfeatures2d\nonfree.hpp>
#include <opencv2\opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

class HogFeatureExtraction
{
public:
	//构造函数
	HogFeatureExtraction();
	//构造函数
	HogFeatureExtraction(int _bins, int _theta, int _cell_size, int _block_size, float _R);
	~HogFeatureExtraction();

	//计算积分图
	vector<Mat> calculateIntegralHOG(Mat& srcMat);
	//单个cell的HOG
	void cacHOGinCell(Mat& m_HOGCell, Rect roi, vector<Mat>& m_integrals);
	//单个block的HOG
	Mat  getBlockHog(cv::Point pt, std::vector<cv::Mat>& integrals);
	//整个图像的HOG
	Mat cacHOGFeature(cv::Mat srcImage);

private:
	int bins;
	int theta;
	int cell_size;
	int block_size;
	float R;
};


实现文件

#include "HogFeatureExtraction.h"

HogFeatureExtraction::HogFeatureExtraction()
{
	bins = 9;
	theta = 180 / bins;
	cell_size = 20;
	block_size = 2;
	R = cell_size*(block_size)*0.5;
}
HogFeatureExtraction::HogFeatureExtraction(int _bins, int _theta, int _cell_size, int _block_size)
{
	bins = _bins;
	theta = 180 / bins;
	block_size = _block_size;
	cell_size = _cell_size;
	R = _cell_size*(_block_size)*0.5;
}

HogFeatureExtraction::~HogFeatureExtraction()
{
}
// 计算积分图
vector<Mat> HogFeatureExtraction::calculateIntegralHOG(Mat& m_src)
{
	Mat m_sobel_x,m_sobel_y,m_magn,m_angle;

	//x 方向上的差分阶数
	Sobel(m_src, m_sobel_x, CV_32F, 1, 0);
	//y 方向上的差分阶数
	Sobel(m_src, m_sobel_y, CV_32F, 0, 1);

	//根据每一个点X方向和Y方向上的梯度,实现笛卡尔坐标和极坐标的转换
	//得到梯度幅值和梯度方向
	cartToPolar(m_sobel_x, m_sobel_y, m_magn, m_angle, true);
	//将笛卡尔坐标转换为极坐标之后,角度的范围在[0,360],但要转成[0,180]
	//如果m_angle<0,则加180
	add(m_angle, Scalar(180), m_angle, m_angle<0);
	//如果m_angle>=180,则减180
	add(m_angle, Scalar(-180), m_angle, m_angle >= 180);

	//将角度矩阵转换为一个灰度值范围在0~9之间的图像
	m_angle = m_angle /theta;
	//新建9个矩阵
	vector<Mat> m_bins(bins);
	for (int i = 0; i < bins; i++)
	{
		//初始化为全0矩阵
		m_bins[i] = Mat::zeros(m_src.size(), CV_32F);
	}	
	//把图像的梯度幅值矩阵按九个不同方向的梯度角度,将每个角度范围内相应点的梯度幅值存储在相应的矩阵图像之上
	for (int y = 0; y < m_src.rows; y++)
	{
		for (int x = 0; x < m_src.cols; x++)
		{
			int ind = m_angle.at<float>(y, x);
			m_bins[ind].at<float>(y, x) += m_magn.at<float>(y, x);
		}
	}
	/*根据上面生成的9张不同角度的梯度幅值矩阵生成9张不同的梯度幅值的积分图像,至此以后,
	  积分图像的每一点就代表,这一点左上角,所有梯度幅值之和;生成的9幅积分图也就是9个
	  bins,不同bins上的HOG强度*/
	vector<Mat> integrals(bins);
	for (int i = 0; i < bins; i++)
	{
		//得到积分图
		integral(m_bins[i], integrals[i]);
	}
	return integrals;
}
//计算单个cell的HOG特征
void HogFeatureExtraction::cacHOGinCell(Mat& m_HOGCell, Rect roi, vector<Mat>& vm_integrals)
{
	//通过9幅积分图像快速实现HOG的计算,HOG这个直方图有9个bins,每个bins就对应一张积分图像
	//确定单个矩形cell的左上角点坐标
	int x0 = roi.x;                             
	int y0 = roi.y;
	//确定单个矩形cell的右下角点坐标
	int x1 = x0 + roi.width;
	int y1 = y0 + roi.height;                   

	for (int i = 0; i <bins; i++)
	{
		//初始化容器
		Mat integral = vm_integrals[i];
		float a = integral.at<double>(y0, x0);
		float b = integral.at<double>(y1, x1);
		float c = integral.at<double>(y0, x1);
		float d = integral.at<double>(y1, x0);
		/*每循环一次,计算一个梯度方向上的HOG特征,*/
		/*每循环一次,就计算梯度方向直方图上的一个bins*/
		m_HOGCell.at<float>(0, i) = b - c - d + a;
	}
}
//计算单个Block的HOG梯度方向直方图
Mat HogFeatureExtraction::getBlockHog(Point pt, vector<Mat>& m_integrals)
{
	if (pt.x - R<0 || pt.y - R<0 || pt.x + R >= m_integrals[0].cols || pt.y + R >= m_integrals[0].rows)
	{
		return Mat();
	}
	//初始化一个矩阵
	Mat hist(Size(bins*block_size*block_size, 1), CV_32F);
	Point  t1(0, pt.y - R);
	int c = 0;
	//遍历单个block,就是遍历4个cell,并且将4个cell的HOG特征向量组成了一个维数比较大的block的HOG特征向量
	for (int i = 0; i<block_size; i++)
	{
		t1.x = pt.x - R;
		for (int j = 0; j<block_size; j++)
		{
			//获取当前窗口,进行局部HOG直方图计算
			Rect roi(t1, t1 + Point(cell_size, cell_size));
			Mat  hist_temp = hist.colRange(c, c + bins);
			//根据roi确定的矩形区域,计算单个cell的HOG直方图(其本质就是一个行特征向量)
			cacHOGinCell(hist_temp, roi, m_integrals);
			t1.x += cell_size;
			c += bins;
		}
		t1.y = cell_size;
	}
	 //归一化
	normalize(hist, hist, 1, 0, NORM_L2);
	return hist;
}

//计算整幅图像的HOG梯度方向直方图
Mat HogFeatureExtraction::cacHOGFeature(Mat src_image)
{
	Mat gray_image, dst_image;
	vector<Mat> wm_HOG;
	//灰度图
	cvtColor(src_image, gray_image, CV_RGB2GRAY);
	//转换类型
	gray_image.convertTo(gray_image, CV_8UC1);
	//生成9个不同梯度方向上的梯度幅值的积分图像
	vector<Mat> integrals = calculateIntegralHOG(gray_image);
	dst_image = gray_image.clone();
	dst_image = dst_image * 0.5;
	
	Mat m_HOGBlock(Size(bins, 1), CV_32F);
	//遍历全图像,计算最终的梯度方向直方图HOG
	for (int y = cell_size / 2; y < gray_image.rows; y += cell_size)
	{
		for (int x = cell_size / 2; x < gray_image.cols; x += cell_size)
		{
			//获取当前block的HOG特征,每个block由四个clee组成,每个cel由8*8个像素组成
			Mat hist = getBlockHog(Point(x, y), integrals);
			if (hist.empty())
			{
				continue;
			}
			//赋值为全0的矩阵
			m_HOGBlock = Scalar(0);
			//计算的就是单个Block的梯度方向直方图HOG
			for (int i = 0; i < bins; i++)
			{
				for (int j = 0; j < block_size; j++)
				{
					m_HOGBlock.at<float>(0, i) += hist.at<float>(0, i + j*bins);
				}
			}
			//对其得到的每个Block的的矩阵进行归一化,使其转变为一个block的HOG特征向量
			normalize(m_HOGBlock, m_HOGBlock, 1, 0, CV_L2);
		
			//每得到一个Block的HOG特征向量就存入wm_HOG,等到整个图像的HOG特征向量
			wm_HOG.push_back(m_HOGBlock);
			Point center(x, y);
			//绘制HOG特征图
			for (int i = 0; i < bins; i++)
			{
				double d_theta = (i * theta) * CV_PI / 180.0;
				Point rd(cell_size*0.5*cos(d_theta), cell_size*0.5*sin(d_theta));
				Point rp = center - rd;
				Point lp = center + rd;
				line(dst_image, rp, lp, Scalar(255 * m_HOGBlock.at<float>(0, i), 255, 255));
			}
		}
	}
	return dst_image;
}

主函数

#include "HogFeatureExtraction.h"

using namespace std;
using namespace cv;
using namespace cv::ml;

int main(void)
{
	Mat src = imread("C:/Users/matt/Desktop/demo/04.jpg");
	namedWindow("src", WINDOW_NORMAL);
	imshow("src", src);
	HogFeatureExtraction hogFeature(9, 180, 8, 2);
	Mat dst = hogFeature.cacHOGFeature(src);
	namedWindow("HOG", WINDOW_NORMAL);
	imshow("HOG", dst);
	waitKey(0);
	return 0;
}

运行效果
在这里插入图片描述
这个像素只有128*64,效果不明显,可以放张大一些的图像试试。
结语:
1.以上只是介绍了HOG特性的提取,之后会试着跑官方行人检测的demo,和如何应用HOG训练自己的分类模型。
2.关于整个工程的源码,运行程序时的bug,或者有如何优代码的想法都可以加这个群(487350510)互相讨论学习。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCV3特征提取与目标检测之HOG(一)——HOG的概述与原理 的相关文章

  • 如何使用 OpenCV 从图像中获取调色板 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想提取图像的调色板 类似于此 来自 我需要它来提取特定的颜色 如黄色 绿色和棕色 并显示该颜色覆盖的区域的百分比 另外 我可以添加更
  • 有人曾经在 MacOS 10.6 上使用过 OpenCV 和 Python 2.7 吗?

    在过去的 6 个月里 我一直断断续续地尝试让 OpenCV 在 MacOS 上与 Python 配合使用 每次有新版本发布时 我都会再次尝试并失败 我已经尝试过 64 位和 32 位 并且 xcode gcc 和 gcc 都是通过 macp
  • OpenCV 完美识别物体

    我有一个应用程序 我想一次跟踪 2 个在图片中相当小的对象 该应用程序应该在 Android 和 iPhone 上运行 因此算法应该是高效的 对于我的客户来说 如果我们提供一些模式以及附加到要跟踪的对象的软件 以获得易于识别的目标 那就完全
  • 从 2 个摄像头捕获(OpenCV、Python)[重复]

    这个问题在这里已经有答案了 所以我试图从 openCV 中的两个摄像头 python 和 windows 7 进行捕获 我用一台相机拍摄的效果很好 你也会注意到我正在对图像做一些时髦的事情 但这并不重要 这是尝试使用两个的代码 import
  • 对同色像素块的边界进行着色

    我有一张有 5 种不同颜色的图像 在这种情况下 随机生成 w h 40 27 img Image new RGB w h pixels img load available colors r 255 13 18 b 72 64 255 y
  • 使用 cv2 在 python 中创建多通道零垫

    我想用 cv2 opencv 包装器在 python 中创建一个多通道 mat 对象 我在网上找到了一些例子 其中 c Mat zeros 被 numpy zeros 替换 这看起来不错 但似乎没有多通道类型适合 看代码 import cv
  • 使用 OpenCV VideoWriter 将 RTSP 流存储为视频文件

    我正在使用 OpenCV 开发一个 Python 模块 该模块连接到 RTSP 流以对视频执行一些预处理 主要是降低 fps 和分辨率 然后将其存储在文件系统中 但是 即使在尝试了几种编解码器 寻找类似的开发之后 我总是得到一个空的视频 我
  • opencv如何使用鼠标事件不规则地选择图像区域? c/c++ [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 最近在学习opencv 有没有办法使用鼠标事件选择图像区域 我已经尝试过三角形的了 如果我想选择特定区域而不是三角形怎么办 谢谢你 我对此进
  • 如何确定透视变换后的点在新图像平面中的位置?

    我使用 OpenCV Python Numpy 图像中有三个点 我知道这些点的确切位置 P1 P2 N1 我要将图像转换为另一个视图 例如 我将透视图转换为侧视图 如果这样做 我将无法获得图像平面中这三个点的确切位置 我应该以一种可以获得这
  • Android API人脸检测与OpenCV/JavaCV人脸检测

    我在 Android 设备上使用了本地 Android 人脸检测 但它似乎很慢 而且我不太确定其可靠性 我还使用了 OpenCV 的人脸检测 但仅限于 PC 而不是 Android 设备 对于 Android 我猜我必须使用 JavaCV
  • 将yuv420p原始数据转换为opencv图像

    我有来自 rtmp 服务器的原始数据 像素格式为 yuv420p 我使用管道来读取数据 但我不知道如何将原始数据解码为图像 command ffmpeg command extend loglevel fatal i rtmp localh
  • 在OpenCV中将YUV转换为BGR或RGB

    我有一个电视采集卡 其输入内容为 YUV 格式 我在这里看到了与此问题类似的其他帖子 并尝试尝试所述的所有可能的方法 但它们都没有提供清晰的图像 目前最好的结果是 OpenCVcvCvtColor scr dst CV YUV2BGR 函数
  • OpenCV 中的 Gabor 内核参数

    我必须在我的应用程序中使用 Gabor 过滤器 但我不知道这个 OpenCV 方法参数值 我想对虹膜进行编码 启动 Gabor 过滤器并获取特征 我想对 12 组 Gabor 参数值执行此操作 然后我想计算 Hamming Dystans
  • 如何将 Opencv VideoWriter 与 GStreamer 结合使用?

    我正在尝试使用 Opencv VideoWriter 传输 h264 流 以使用 VideoCapture 将其传输到网络上的另一台电脑上 但是 我被困在 VideoWriter 上 执行此代码会返回错误 并且 out isOpened 始
  • OpenCV:将垫子除以标量的最简单方法是什么

    我认为标题中已经包含了很多内容 显然我可以迭代和划分 但我认为有一种内置的方法 我看见cvConvertScale但这不适用于类型cv Mat 我知道标量乘法的缩放运算 cv Mat M float alpha cv Mat Result
  • 计数物体和更好的填充孔的方法

    我是 OpenCV 新手 正在尝试计算物体的数量在图像中 我在使用 MATLAB 图像处理工具箱之前已经完成了此操作 并在 OpenCV Android 中也采用了相同的方法 第一步是将图像转换为灰度 然后对其进行阈值计算 然后计算斑点的数
  • 在 HSV 颜色空间内定义组织学图像掩模的颜色范围(Python、OpenCV、图像分析):

    为了根据颜色将组织学切片分成多个层 我修改了 OpenCV 社区提供的一些广泛分布的代码 1 我们的染色程序用不同的颜色标记组织横截面的不同细胞类型 B 细胞为红色 巨噬细胞为棕色 背景细胞核为蓝色 I m interested in se
  • 如何将本机库链接到 IntelliJ 中的 jar?

    我正在尝试在 IntelliJ 中设置 OpenCV 但是我一直在弄清楚如何告诉 IntelliJ 在哪里可以找到本机库位置 在 Eclipse 中 添加 jar 后 您可以在 Build Config 屏幕中设置 Native 库的位置
  • opencv - 在图像中绘制轮廓

    我正在尝试在图像周围绘制轮廓 我可以看到找到了轮廓 但无法绘制轮廓 轮廓的颜色似乎是两种 黑色和白色 颜色中的一种 import cv2 import numpy as np import matplotlib pyplot as plt
  • 如何根据图像中的对象大小(以像素为单位)来测量现实世界中的对象大小(例如英寸、厘米等)?

    我计算了物体的大小pixel来自包含对象的图像 我想测量现实世界中物体的大小 有没有办法找出乘数来测量实际尺寸 我目前正在使用python以便实施 通常 您将使用相机获取图像 该相机通过镜头将 3 维场景投影到 2 维传感器上 垂直 高度

随机推荐

  • android开发:Android Studio的Signature Versions选择

    参考 https blog csdn net jiangjingxuan article details 66970552
  • Anaconda安装jieba库和wordcloud库安装实现词云

    一 jieba库安装 1 从官网下载jieba压缩包 https pypi org project jieba files 2 将压缩包解压到anaconda的pkgs目录 3 打开anaconda prompt 切换目录至比如 C ana
  • Linux环境下编程遇到“fatal error:stdio.h:没有那个文件或目录”错误解决办法

    我是荔园微风 作为一名在IT界整整25年的老兵 今天总结一下linux环境下如何解决一个常见的问题 也就是 fatal error stdio h 没有那个文件或目录 错误 不少初学者在linux环境下用gcc编译C语言时 经常会遇到这个问
  • Linux wc命令

    Linux wc命令 作用 统计字节数 字符数 行数 最长的行的长度 单词数 格式 wc OPTION FILE wc OPTION files0 from F OPTION c 或 bytes 计算字节数 m 或 chars 计算字符数
  • SPA项目开发之首页导航+左侧栏菜单

    文章目录 后台主界面搭建 左侧树收缩功能 vue总线的概念 后台主界面搭建 在搭建主界面之前 来给大家介绍一个MOCK js 是一个模拟数据的生成器 用来帮助前端调试开发 进行前后端的原型分离以及用来提高自动化测试效率 众所周知Mock j
  • hex码和ascii码的转换

    hex码和ascii码的转换 2017年01月09日 17 48 25 changeyourmind 阅读数 4784 版权声明 本文为博主原创文章 未经博主允许不得转载 https blog csdn net changyourmind
  • PRT(Precomputed Radiance Transfer【2002】)原理实现

    声明 本文源自对Games202课程 作业2的总结 参考 手把手教你写GAMES202作业 GAMES202 作业2 Precomputed Radiance Transfer 球谐函数 GAMES 202 作业2 Games202课程 个
  • Apache Beam 模型

    背景 Apache Beam 是Google 开源的一个统一编程框架 它本身不是一个流式处理平台 而是提供了统一的编程模型 帮助用户创建自己的数据处理流水线 实现可以运行在任意执行引擎之上批处理和流式处理任务 它包含 一个可以涵盖批处理和流
  • C++工程实践经验

    1 C 工程实践经验谈 陈硕 giantchen gmail com 最后更新 2012 4 20 版权声明 本作品采用 Creative Commons 署名 非商业性使用 禁止演绎 3 0 Unported 许可 协议 cc by nc
  • DF标志和串移动指令(movsb/movsw)

    1 标志寄存器的第10位DF 方向标志位 在串处理指令中 控制每次操作后si di的增减 DF 0 每次操作后 si di增加 DF 1 每次操作后 si di减小 我们可以用汇编语法描述movsb的功能如下 mov es di byte
  • 读写分离(主从复制,Sharding-JDBC)

    目录 1 介绍 2 配置 2 1配置准备 2 2配置主库Master 2 3配置从库Slave 3 读写分离案例 3 1Sharding JDBC 3 2入门案例 1 介绍 MySQL主从复制是一个异步的复制过程 底层是基于MySQL数据库
  • 数控直流电压源的设计与制作【keil5 & AD20]

    目录 1 设计任务与要求 1 1 设计任务 1 2 设计要求 2 设计方案 2 1 系统方案设计 2 1 1 滤波电路 2 2 2 辅助电源电路 2 2 3 三端可调稳压电路 2 2 4 电压 电流采样电路 2 2 元器件选型 2 2 1电
  • 浅析数据库case when 用法

    背景 今天在做一个需求 大致就是根据卡的logo去匹配 卡片的主卡数量 附属卡数量 激活卡数量 未激活卡数量 销卡数量等 当时以为要写很多sql 后来问了下同事说可以用case when写一条sql就能搞定 当时那个开心啊就是这样的O O哈
  • YoloV8改进策略:SPD-Conv加入到YoloV8中,让小目标无处遁形

    摘要 SPD Conv是一种新的构建块 用于替代现有的CNN体系结构中的步长卷积和池化层 它由一个空间到深度 SPD 层和一个非步长卷积 Conv 层组成 空间到深度 SPD 层的作用是将输入特征图的每个空间维度降低到通道维度 同时保留通道
  • arxiv国内镜像——快速下载

    arXiv org是一个收录科学文献预印本的在线数据库 目前包含了超过50万篇文章 并且以每个月5000篇的速度增长着 目前 这个数据库包含 数学 物理 计算机 非线性科学 定量生物学 定量财务以及统计学几大分类 其最重要的特点就是 开放式
  • php结合验证码实现登陆,thinkPHP实现的验证码登录功能示例

    本文实例讲述了thinkPHP实现的验证码登录功能 分享给大家供大家参考 具体如下 使用thinkphp自带的验证 实现登录页面的账号密码 验证码的验证 namespace Admin Controller use Think Contro
  • hashmap的扩容机制

    1 hashmap扩容的代码实现 hashMap的扩容机制 final Node
  • springboot整合IJPay实现微信支付-V3---微信小程序

    前言 微信支付适用于许多场合 如小程序 网页支付 但微信支付相对于其他支付方式略显麻烦 我们使用IJpay框架进行整合 一 IJpay是什么 JPay 让支付触手可及 封装了微信支付 支付宝支付 银联支付常用的支付方式以及各种常用的接口 不
  • Flutter

    看到有不少人在用 CustomScrollView 我实在心痛 杀鸡焉用牛刀 好好看代码 一个小小的 Column 就能解决问题 class AddHeaderFooterListPageState extends State
  • OpenCV3特征提取与目标检测之HOG(一)——HOG的概述与原理

    1 HOG Histogram of Oriented Gradient 是方向梯度直方图的意思 是一种特性描述子 通过计算与统计图像局部区域的梯度方向直方图来构成特征 边缘是图像颜色剧变的区域 在一副图像中 局部目标的表象与形状能够被梯度