当前位置:网站首页>Opencv feature extraction - hog

Opencv feature extraction - hog

2022-07-03 10:05:00 Σίσυφος one thousand and nine hundred

One 、HOG features

HOG(Histograms of Oriented Gradients) Gradient direction histogram

Two 、HOG Feature extraction process

1) Grayscale image transformation ( Think of the image as a x,y,z( Grayscale ) Three dimensional images of );


2) use Gamma The input image is normalized in color space by correction method ( normalization ); The purpose is to adjust the contrast of the image , Reduce the impact of local shadow and light changes in the image , At the same time, it can suppress the interference of noise ;

#if 1 //  Image enhancement algorithm  --gamma
int  Gamma = 2;
int main(int args, char* arg)
{
	Mat	src = imread("C:\\Users\\19473\\Desktop\\opencv_images\\88.jpg");
	if (!src.data)
	{
		printf("could not  load  image....\n");
	}
	imshow(" Original image ", src);
	//  Be careful  : CV_32FC3
	Mat dst(src.size(), CV_32FC3);

	for (int i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{
			//  Yes bgr  Each channel of is calculated 
			dst.at<Vec3f>(i, j)[0] = pow(src.at<Vec3b>(i, j)[0], Gamma);
			dst.at<Vec3f>(i, j)[1] = pow(src.at<Vec3b>(i, j)[1], Gamma);
			dst.at<Vec3f>(i, j)[2] = pow(src.at<Vec3b>(i, j)[2], Gamma);
		}
	}
	//  normalization 
	normalize(dst, dst, 0, 255, CV_MINMAX);

	convertScaleAbs(dst, dst);

	imshow(" Enhanced image ", dst);
	waitKey(0);
	return -1;
}
#endif

3) Calculate the gradient of each pixel in the image ( Including size and direction ); The main purpose is to capture the contour information , At the same time, further weaken the interference of light

Mat non_max_supprusion(Mat  dx, Mat dy)  // What comes in is the difference matrix in two directions   3*3  Mask of 
{
	// Edge strength =sqrt(dx  The square of +dy  The square of ) 
	Mat  edge;
	magnitude(dx, dy, edge);//  Calculate the amplitude value 
	int  rows = dx.rows;
	int  cols = dy.cols;
	// Non maximum suppression of edge strength 
	Mat edgemag_nonMaxSup = Mat::zeros(dx.size(), dx.type());
	//  Use two steps to calculate    And gradient direction   And convert it to angleMatrix
	for (int row = 1; row < rows - 1; row++)
	{
		for (int col = 1; col < cols - 1; col++)
		{
			float x = dx.at<float>(row, col);
			float y = dx.at<float>(row, col);
			//  The direction of the gradient ---atan2f

			float  angle = atan2f(y, x) / CV_PI * 180;
			//  Edge strength of current position 
			float  mag = edge.at<float>(row, col);
			//  Find the left and right directions 
			if (abs(angle) < 22.5 || abs(angle) > 157.5)
			{
				float  left = edge.at<float>(row, col - 1);
				float  right = edge.at<float>(row, col + 1);
				//  Judge in two directions 
				if (mag > left && mag > right) {
					edgemag_nonMaxSup.at<float>(row, col) = mag;
				}

			}
			//  Top left and bottom right 
			if ((abs(angle) >= 22.5 && abs(angle) < 67.5) || (abs(angle) < -112.5 && abs(angle) > 157.5))
			{
				float  lefttop = edge.at<float>(row - 1, col - 1);
				float  rightbottom = edge.at<float>(row + 1, col + 1);
				//  Judge in two directions 
				if (mag > lefttop && mag > rightbottom) {
					edgemag_nonMaxSup.at<float>(row, col) = mag;
				}
			}

			//   On    Next   Direction 
			if ((abs(angle) >= 67.5 && abs(angle) <= 112.5) || (abs(angle) >= -112.5 && abs(angle) <= -67.5))
			{
				float  top = edge.at<float>(row - 1, col);
				float  down = edge.at<float>(row + 1, col);
				//  Judge in two directions 
				if (mag > top && mag > down) {
					edgemag_nonMaxSup.at<float>(row, col) = mag;
				}
			}




			//   The upper right    The lower left   Direction 
			if ((abs(angle) > 122.5 && abs(angle) < 157.5) || (abs(angle) > -67.5 && abs(angle) <= -22.5))
			{
				float  leftdown = edge.at<float>(row - 1, col + 1);
				float  rightup = edge.at<float>(row + 1, col - 1);
				//  Judge in two directions 
				if (mag > leftdown && mag > rightup) {
					edgemag_nonMaxSup.at<float>(row, col) = mag;
				}
			}
		}
	}
	return  edgemag_nonMaxSup;
}


4) Divide the image into small cells( for example 8* 8 Pixels / cell); Work out each cell Gradient size and direction . Then set the gradient direction of each pixel in   Within the interval ( Undirected :0-180, Directed :0-360) The average is divided into 9 individual bins, Every cell Pixels in the are represented by amplitude , Weighted voting for its gradient histogram .

 

5) Count each one cell The gradient histogram of ( The number of different gradients ), You can form each cell Of descriptor;   Quick description seed
6) Will each several cell Form a block( for example 3 * 3 individual cell / block), One block All in cell Characteristics of descriptor In series, you get this block Of HOG features descriptor. Quickly describe seed normalization


7) The image image In all of the block Of HOG features descriptor In series, you can get the image( The target you want to detect ) Of HOG features descriptor 了 . This is the final feature vector for classification Feature data and detection window

For size 128×64 Size image , use 8*8 Pixel sell,2×2 individual cell Composed of 16×16 Pixel block, use 8 Pixel block Move step , In this way, the detection window block There are ((128-16)/8+1)×((64-16)/8+1)=15×7. be HOG The dimension of the feature descriptor is 15×7×4×9.

8)  Match method

 

HOG The shortcomings of :


Slow speed , Poor real-time performance ; Difficult to deal with occlusion

3、 ... and 、 Code demonstration

int main(int args, char* arg)
{
	// Target image 
	src = imread("C:\\Users\\19473\\Desktop\\opencv_images\\153.jpg");
	if (!src.data)
	{
		printf("could not  load  image....\n");
	}
	namedWindow(INPUT_TITLE, CV_WINDOW_AUTOSIZE);

	//namedWindow(OUT_TITLE, CV_WINDOW_AUTOSIZE);
	imshow(INPUT_TITLE, src);
	/*
	 //  Resize the image 
	resize(src, dst,Size(64,128));

	cvtColor(dst, src_gary, CV_BGR2GRAY);

	HOGDescriptor  detector(Size(64,128), Size(16,16), Size(8,8),Size(8,8),9);
	vector<float>  descripers;
	vector<Point>  locations;
	detector.compute(src_gary, descripers, Size(0,0), Size(0, 0), locations);
	printf("num  of  HOG:  %d\n", descripers.size());
	*/


	//SVM classifier  -- Narrator 
	HOGDescriptor  hog = HOGDescriptor();
	hog.setSVMDetector(hog.getDefaultPeopleDetector());
	vector<Rect>   foundloactions;
	//  Multiscale detection 
	hog.detectMultiScale(src, foundloactions, 0, Size(8, 8), Size(32, 32), 1.05, 2, false);
	// if rects Nested , Then take the outermost rectangle and store it rect
	for (size_t i = 0; i < foundloactions.size(); i++)
	{
		rectangle(src, foundloactions[i], Scalar(0, 0, 255), 2, 8.0);
	}

	namedWindow(OUT_TITLE, CV_WINDOW_AUTOSIZE);
	imshow(OUT_TITLE, src);
	waitKey(0);
	return 0;
}

 

 

 

 

原网站

版权声明
本文为[Σίσυφος one thousand and nine hundred]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202150539425270.html