环境:OpenCV3.4.0,linux操作系统,用CMake生成makefile。
openCV直方图基本知识介绍:
1)直方图的操作类似CvMat,本质上也是一个一维或者多维的离散的图,只不过是源自于图像的统计结果,一般也是用于图像信息统计、匹配。
2)从间隔划分上将直方图分为均匀划分直方图和非均匀划分直方图。
3)也可以像CvMat一样访问数据成员。当然,也包括归一化、阈值、复制、获取最大最小值等基本操作。
4)一般情况现,直方图操作处理的图像为单通道的IplImage,多通道的可以进行拆分为单通道后在进行处理。
5)两个直方图之间除了可以进行复制操作,也可以进行对比操作,根据对比的计算方式不同,分为相关、卡方、直方图相交、距离四种操作方式,其中,卡方和距离比较常用。
下面写一个一维的直方图统计程序(hist.cpp),代码如下:
#include "highgui.h"
#include "cv.h"
#define cvQueryHistValue_1D( hist, idx0 ) cvGetReal1D( (hist)->bins, (idx0) )
int main(int argc,char **argv)
{
IplImage * src;
if(argc==2 && (src=cvLoadImage(argv[1],1))!=0)//加载需要处理的图像进来
{
//将图像从BGR拆分成三个单通道图像
IplImage *B = cvCreateImage(cvGetSize(src),8,1);
IplImage *G = cvCreateImage(cvGetSize(src),8,1);
IplImage *R = cvCreateImage(cvGetSize(src),8,1);
//选择B通道进行计算
IplImage * BG[] = {B};
//将BGR图像拆分成三个通道
cvSplit(src,B,G,R,0);
//定义区间数量
int b_bins = 60;
//定义直方图
CvHistogram * hist ;
{
//直方图大小
int hist_size[] = {b_bins};
//直方图统计范围
float b_ranges[] = {0,255};
float *ranges[]={b_ranges};
//创建直方图
hist = cvCreateHist(
1,//维度
hist_size,
CV_HIST_ARRAY,
ranges,
1
);
}
//计算直方图
cvCalcHist(BG,hist,0,0);
//归一化
cvNormalizeHist(hist,1);
//寻找最大值
float max_value = 0;
cvGetMinMaxHistValue(hist,0,&max_value,0,0);
//用stdout打印输出到控制台
for(int b = 0 ;bfloat bin_value =cvQueryHistValue_1D(hist,b);
printf("the hist value %f\n",bin_value);
}
cvWaitKey(0);
}
}
CMakeLists.txt如下所示:
# cmake needs this line
cmake_minimum_required(VERSION 2.8)
# Define project name
project(opencv_example_project)
# Find OpenCV, you may need to set OpenCV_DIR variable
# to the absolute path to the directory containing OpenCVConfig.cmake file
# via the command line or GUI
find_package(OpenCV REQUIRED)
# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them
message(STATUS "OpenCV library status:")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
set(CMAKE_BUILD_TYPE DEBUG)
set(CMAKE_CXX_FLAGS_DEBUG "-g -Wall")
if(CMAKE_VERSION VERSION_LESS "2.8.11")
# Add OpenCV headers location to your include paths
include_directories(${OpenCV_INCLUDE_DIRS})
endif()
# Declare the executable target built from your sources
add_executable(opencv_example hist.cpp)
# Link your application with OpenCV libraries
target_link_libraries(opencv_example ${OpenCV_LIBS})
这个小例子主要是让大家对直方图有一个直观的认识。
下面开始介绍匹配的知识。
匹配是指在给定一个模板的情况下(直方图或者图像),在目标图像中寻找相似的区域,例如,寻找皮肤,寻找人脸等操作。
1)若给定直方图作为模板,分为两种情况。
此两种方法都是根据得到的先验知识来进行后验概率统计的方法。
2)若给定图像模板
- 调用cvMatchTemplate()完成匹配。
下面举一个关于给定图像模板的实例,代码(t_match.cpp)如下,输入为两张相同的图片即可。
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include "stdio.h"
int main(int argc,char ** argv)
{
IplImage *src,*temp1,*temp2,*ftmp[6];
int i ;
if(argc == 3)
{
//输入源图像
if((src=cvLoadImage(argv[1],1))==0)
{
printf("error on reading src ");
return -1;
}
//输入的需要裁剪的模板图像,一般就和源图像是一个图像即可,方便看效果
if((temp1 = cvLoadImage(argv[2],1))==0)
{
printf("error on reading template ");
return -1;
}else{
//在temp1上裁剪一块区域 ,制作模板
CvSize size = cvSize(200,200);
cvSetImageROI(temp1,cvRect(200,200,size.width,size.height));
temp2=cvCreateImage(size,temp1->depth,temp1->nChannels);
cvCopy(temp1,temp2);
cvResetImageROI(temp1);
cvSaveImage("template.jpg",temp2);
}
int iwidth = src->width-temp2->width+1;
int iheight = src->height-temp2->height+1;
//创建图像
for (i=0;i<6;i++)
{
ftmp[i] = cvCreateImage(cvSize(iwidth,iheight),32,1);
}
//匹配操作
for (i=0;i<6;i++)
{
cvMatchTemplate(src,temp2,ftmp[i],i);
cvNormalize(ftmp[i],ftmp[i],1,0,CV_MINMAX);
}
//显示
cvNamedWindow("template",0);
cvShowImage("template",temp2);
cvNamedWindow("src",0);
cvShowImage("src",src);
cvNamedWindow("result",0);
//更改ftmp数组中[]中的值,可以看到不同测试方法的结果
cvShowImage("result",ftmp[0]);
cvWaitKey(0);
}
}
CMakeLists.txt如下所示:
# cmake needs this line
cmake_minimum_required(VERSION 2.8)
# Define project name
project(opencv_example_project)
# Find OpenCV, you may need to set OpenCV_DIR variable
# to the absolute path to the directory containing OpenCVConfig.cmake file
# via the command line or GUI
find_package(OpenCV REQUIRED)
# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them
message(STATUS "OpenCV library status:")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
set(CMAKE_BUILD_TYPE DEBUG)
set(CMAKE_CXX_FLAGS_DEBUG "-g -Wall")
if(CMAKE_VERSION VERSION_LESS "2.8.11")
# Add OpenCV headers location to your include paths
include_directories(${OpenCV_INCLUDE_DIRS})
endif()
# Declare the executable target built from your sources
add_executable(opencv_example t_match.cpp)
# Link your application with OpenCV libraries
target_link_libraries(opencv_example ${OpenCV_LIBS})