#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\opencv.hpp>
#include<iostream>
#include<fstream> using namespace std;
using namespace cv; #define Max 100 class Cell{
private:
int pixel_x; //cell的像素的起始位置行坐标;
int pixel_y; //cell的像素的起始位置纵坐标;
Mat img; //待处理的图像,通常该该图像是经过Gamma校正的灰度图;
double pixel[][]; //我们一般默认cell为8*8的像素大小,但是为了储存周边店的像素,需要多加两个像素储存点的位置;
double gradient_M[][]; //保存梯度的幅值;
double gradient_Angle[][]; //保存像素梯度的方向;
double gradient_h[][];
double gradient_v[][]; public:
double bin[]; //将梯度方向分成九个方向,在根据具体像素梯度的方向大小,进行投票;
Cell(Mat src){ //构造函数;
img=src;
} void Set_Cell(int x,int y);
void Get_Pixel(); //为了计算机使用方便,我们把一个cell当中的像素先读下来,用pixel[][]数组储存;
void Gradient_Pixel(); //计算机图像像素的梯度幅值和梯度角度;
void Bin_Selection_Normalization(); //根据每个像素的幅值进行维度的区分和归一化,并且返回bin[]数组;
}; void Cell::Set_Cell(int x,int y){
pixel_x=x;
pixel_y=y;
} void Cell::Get_Pixel(){
for(int i=pixel_x-,m=;i<pixel_x+;i++,m++){
uchar *data=img.ptr<uchar>(i);
for(int j=pixel_y-,n=;j<pixel_y+;j++,n++){
pixel[m][n]=data[j];
}
}
// for(int i=0;i<9;i++){
// for(int j=0;j<9;j++){
// cout<<i<<j<<" "<<pixel[i][j]<<"\n";
// }
// }
} void Cell::Gradient_Pixel(){
for(int i=;i<;i++){
for(int j=;j<;j++){
gradient_h[i][j]=pixel[i+][j]-pixel[i-][j];
gradient_v[i][j]=pixel[i][j+]-pixel[i][j-];
gradient_M[i][j]=sqrt(gradient_h[i][j]*gradient_h[i][j]+gradient_v[i][j]*gradient_v[i][j]);
gradient_Angle[i][j]=atan2(gradient_h[i][j],gradient_v[i][j])*;
}
} // for(int i=0;i<9;i++){
// for(int j=0;j<9;j++){
// cout<<i<<j<<" "<<gradient_h[i][j]<<" "<<gradient_v[i][j]<<" "<<gradient_M[i][j]<<" "<<gradient_Angle[i][j]<<"\n";
// }
// }
} void Cell::Bin_Selection_Normalization(){
for(int i=;i<;i++){
bin[i]=;
} for(int i=;i<;i++){
for(int j=;j<;j++){
if((gradient_Angle[i][j]>=&&gradient_Angle[i][j]<)||(gradient_Angle[i][j]>=&&gradient_Angle[i][j]<)){
bin[]=bin[]+gradient_M[i][j];
}
if((gradient_Angle[i][j]>=&&gradient_Angle[i][j]<)||(gradient_Angle[i][j]>=&&gradient_Angle[i][j]<)){
bin[]=bin[]+gradient_M[i][j];
}
if((gradient_Angle[i][j]>=&&gradient_Angle[i][j]<)||(gradient_Angle[i][j]>=&&gradient_Angle[i][j]<)){
bin[]=bin[]+gradient_M[i][j];
}
if((gradient_Angle[i][j]>=&&gradient_Angle[i][j]<)||(gradient_Angle[i][j]>=&&gradient_Angle[i][j]<)){
bin[]=bin[]+gradient_M[i][j];
}
if((gradient_Angle[i][j]>=&&gradient_Angle[i][j]<)||(gradient_Angle[i][j]>=&&gradient_Angle[i][j]<)){
bin[]=bin[]+gradient_M[i][j];
}
if((gradient_Angle[i][j]>=&&gradient_Angle[i][j]<)||(gradient_Angle[i][j]>=&&gradient_Angle[i][j]<)){
bin[]=bin[]+gradient_M[i][j];
}
if((gradient_Angle[i][j]>=&&gradient_Angle[i][j]<)||(gradient_Angle[i][j]>=&&gradient_Angle[i][j]<)){
bin[]=bin[]+gradient_M[i][j];
}
if((gradient_Angle[i][j]>=&&gradient_Angle[i][j]<)||(gradient_Angle[i][j]>=&&gradient_Angle[i][j]<)){
bin[]=bin[]+gradient_M[i][j];
}
if((gradient_Angle[i][j]>=&&gradient_Angle[i][j]<=)||(gradient_Angle[i][j]>=&&gradient_Angle[i][j]<=)){
bin[]=bin[]+gradient_M[i][j];
}
}
}
////////////////////////////////////
//归一化;
double sum_bin=;
for(int i=;i<;i++){
sum_bin=sum_bin+bin[i];
}
for(int i=;i<;i++){
bin[i]=bin[i]/sum_bin;
if(bin[i]>0.2){
bin[i]=0.2;
}
}
sum_bin=;
for(int i=;i<;i++){
sum_bin=sum_bin+bin[i];
}
for(int i=;i<;i++){
bin[i]=bin[i]/sum_bin;
}
}
//Block类部分****************
class Block{
int block_pixel_x; //block的起始像素点横坐标位置;
int block_pixel_y; //block的起始像素点纵坐标位置;
Mat src; //图像必须是灰度图;
double bins[]; //该类主要是对block进行相关处理,我们默认block为四个cell,即2*2;所以bins为36维;
int k; public:
Block(Mat img){
src=img;
k=;
} void Set_Block(int x,int y);
void Cut_Block(); //本人认为这是整个算法当中比较重要的一部分,即图像切割划分部分;
void Block_into_HistImage();
void output_bins();
}; void Block::Set_Block(int x,int y){
block_pixel_x=x;
block_pixel_y=y;
} void Block::Cut_Block(){
k=;
Cell cell(src);
for(int i=block_pixel_x, m=;m<;i=i+,m++){
for(int j=block_pixel_y, n=;n<;j=j+,n++){
cell.Set_Cell(i,j);
cell.Get_Pixel();
cell.Gradient_Pixel();
cell.Bin_Selection_Normalization();
for(int i=;i<;i++){
bins[k++]=cell.bin[i];
}
}
}
} void Block::Block_into_HistImage(){ //该部分算法是将bins生成直方图;
int hight=;
int width=;
IplImage *hist_image=cvCreateImage(Size(,),,);
for(int i=;i<;i++){
cvRectangle(hist_image,CvPoint(i*,hight-),CvPoint((i+)*-,hight-bins[i]*),CV_RGB(,,));
} cvNamedWindow("",);
cvShowImage("",hist_image);
cvWaitKey();
} void Block::output_bins(){
//ofstream out ("1.txt");
for(int i=;i<;i++){
cout<<bins[i]<<"\n";
}
cout<<"*******************************************\n";
} int main(){
Mat img=imread("G:/2.png",); //载入图片;
if(img.empty())
{
return -;
}
Mat gray1;
Mat gray;
cvtColor(img,gray1,COLOR_RGB2GRAY);
resize(gray1,gray,Size(,),,,);
namedWindow("gray",);
imshow("gray",gray);
// cvWaitKey(0);
Block block(gray);
for(int i=,m=;m<;m++,i=i+){
for(int j=,n=;n<;n++,j=j+){
block.Set_Block(i,j);
block.Cut_Block();
//block.Block_into_HistImage();
block.output_bins();
}
}
}

Opencv学习之路——自己编写的HOG算法的更多相关文章

  1. opencv学习笔记(七)SVM+HOG

    opencv学习笔记(七)SVM+HOG 一.简介 方向梯度直方图(Histogram of Oriented Gradient,HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子 ...

  2. Opencv学习之路—Opencv下基于HOG特征的KNN算法分类训练

    在计算机视觉研究当中,HOG算法和LBP算法算是基础算法,但是却十分重要.后期很多图像特征提取的算法都是基于HOG和LBP,所以了解和掌握HOG,是学习计算机视觉的前提和基础. HOG算法的原理很多资 ...

  3. OpenCV 学习之路(2) -- 操作像素

    本节内容: 访问像素值 用指针扫描图像 用迭代器扫描图像 编写高效的图像扫描循环 扫描图像并访问相邻像素 实现简单的图像运算 图像重映射 访问像素值 准备工作: 创建一个简单函数,用它在图像中加入椒盐 ...

  4. OpenCV 学习之路(1)

    OpenCV的第一个代码: #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #i ...

  5. opencv学习之路(41)、人脸识别

    一.人脸检测并采集个人图像 //take_photo.cpp #include<opencv2/opencv.hpp> using namespace cv; using namespac ...

  6. opencv学习之路(40)、人脸识别算法——EigenFace、FisherFace、LBPH

    一.人脸识别算法之特征脸方法(Eigenface) 1.原理介绍及数据收集 特征脸方法主要是基于PCA降维实现. 详细介绍和主要思想可以参考 http://blog.csdn.net/u0100066 ...

  7. opencv学习之路(39)、PCA

    一.PCA理论介绍 网上已经有许多介绍pca原理的博客,这里就不重复介绍了.详情可参考 http://blog.csdn.net/zhongkelee/article/details/44064401 ...

  8. opencv学习之路(38)、Mat像素统计基础——均值,标准差,协方差;特征值,特征向量

    本文部分内容转自 https://www.cnblogs.com/chaosimple/p/3182157.html 一.统计学概念 二.为什么需要协方差 三.协方差矩阵 注:上述协方差矩阵还需要除以 ...

  9. opencv学习之路(37)、运动物体检测(二)

    一.运动物体轮廓椭圆拟合及中心 #include "opencv2/opencv.hpp" #include<iostream> using namespace std ...

随机推荐

  1. Python学习笔记9:标准库之日期时间(time包,datetime包)

    一 time包 sleep([float time]) 延迟一段以浮点数表示的秒数 time包基于C语言的库函数(library functions). Python的解释器一般是用C编写的,Pyth ...

  2. windowActionModeOverlay

    windowActionModeOverlay: android:windowActionModeOverlay=“true|false”  : actionmode 弹出时覆盖部分布局      若 ...

  3. Solution:Cannot pull with rebase: You have unstaged changes in Github

    You can do this to work around using following steps 1. stash your changes with: git stash 2. pull f ...

  4. 【BZOJ 2160】 拉拉队排练

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2160 [算法] 先简化题意 : 给定一个字符串,求最长的k个奇回文子串长度的乘积 先 ...

  5. [Django基础] gunicorn启动django时静态文件的加载

    目前在用nginx+gunicorn对django进行部署 当我用gunicorn -w 4 -b 127.0.0.1:8080 myproject.wsig:application启动django时 ...

  6. Coursera Algorithms week4 基础标签表 练习测验:Java autoboxing and equals

    1. Java autoboxing and equals(). Consider two double values a and b and their corresponding Double v ...

  7. hibernate类或方法---备忘录

  8. FTP FtpWebRequest 异步上传文件

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  9. [Swift通天遁地]二、表格表单-(10)快速添加日期选择/多选/动作表单/地图等自定义表单

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  10. [Swift通天遁地]四、网络和线程-(6)检测网络连接状态

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...