如果一个点在两个正交方向上都有明显的导数,则我们认为此点更倾向于是独一无二的,所以许多可跟踪的特征点都是角点。
一下为角点检测中用到的一些函数
cvGoodFeaturesToTrack采用Shi和Tomasi提出的方法,先计算二阶导数,再计算特征值,它返回满足易于跟踪的定义的一系列点。
一下为角点检测中用到的一些函数
cvGoodFeaturesToTrack采用Shi和Tomasi提出的方法,先计算二阶导数,再计算特征值,它返回满足易于跟踪的定义的一系列点。
void cvGoodFeaturesToTrack(
const CvArr* image,
CvArr* eig_image,
CvArr* temp_image,
const CvArr* image,
CvArr* eig_image,
CvArr* temp_image,
CvPoint2D32f* corners,
int* corner_count,
int* corner_count,
double quality_level,
double min_distance,
double min_distance,
const CvArr* mask=NULL
int block_size =3,
int use_harris =0,
double k = 0.4
);
int block_size =3,
int use_harris =0,
double k = 0.4
);
image
输入图像必须为8位或32位单通道图像
eig_image
当做临时变量使用,计算后eig_image 中的内容是有效的,其中每个元素包含了输入图像中对应点的最小特征值
temp_image
另外一个临时图像,格式与尺寸与 eig_image 一致
corners
是函数的输出,为检测到的32位的角点数组,在调用函数之前需要为它分配空间
corner_count
函数调用完成后,该值表示实际检测到的角点数目
quality_level
表示一点被认为是角点的可接受的最小特征值。
min_distance
检测完角点之后还要剔除一些距离比较近的角点,min_distance保证返回的角点之间的距离不小于min_distance.
mask
可选参数,一幅像素值为bool类型的图像,用于指定输入图像中参与角点计算的像素点。如果mask为NULL,则选择整个图像。
block_size
计算导数的自相关矩阵时指定的邻域。
use_harris
如果use_harris为0,则使用Shi-Tomasi定义,非零则使用Harris的角点定义
运行结果:
不知道是不是格式的问题,,,,这个程序还有点问题,,,待考试完了再处理一下..block_size
计算导数的自相关矩阵时指定的邻域。
use_harris
如果use_harris为0,则使用Shi-Tomasi定义,非零则使用Harris的角点定义
void cvCvtColor( const CvArr* src, CvArr* dst, int code );
该函数是opencv中的颜色空间转换函数
该函数是opencv中的颜色空间转换函数
src
输入的 8-bit,16-bit或 32-bit单倍精度浮点数图像。
dst
输出的8-bit, 16-bit或 32-bit单倍精度浮点数图像。
code
色彩空间转换的模式,该code来实现不同类型的颜色空间转换。
void cvCircle(CvArr* img, CvPoint center, int radius, CvScalar color, int thickness=1, int lineType=8, int shift=0)
img – 要画圆的图像
center – 圆心坐标
radius – 半径
color – 颜色
thickness – 线宽
lineType – Type of the circle boundary, see Line description shift –圆心坐标和和半径的小数点的数目
center – 圆心坐标
radius – 半径
color – 颜色
thickness – 线宽
lineType – Type of the circle boundary, see Line description shift –圆心坐标和和半径的小数点的数目
#include "StdAfx.h"
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include<opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
const int max_corners=100;
const char* filename = "JINGLONGLONG.jpg";
int main()
{
int cornerCount =max_corners;//角点的最大数目
//用于保存角点的坐标
CvPoint2D32f corners[max_corners];
IplImage* sourceImage=0,*grayImage=0,*corners1=0,*corners2=0;
cvNamedWindow("IMAGE",CV_WINDOW_AUTOSIZE);
//读入图像,检测
sourceImage=cvLoadImage(filename,1);
grayImage=cvCreateImage(cvGetSize(sourceImage),IPL_DEPTH_8U,1);
cvCvtColor(sourceImage,grayImage,CV_RGB2GRAY);
corners1=cvCreateImage(cvGetSize(sourceImage),IPL_DEPTH_32F,1);
corners2=cvCreateImage(cvGetSize(sourceImage),IPL_DEPTH_32F,1);
cvGoodFeaturesToTrack(
grayImage,
corners1,
corners2,
corners,
&cornerCount,
0.05,
5,
0,
3,
0,
0.4
);
if(cornerCount)
{
int i=0;
CvScalar color=CV_RGB(0,0,255);
for(i;i<cornerCount;i++)
cvCircle(
sourceImage, //要画圆的图像
cvPoint((int)(corners[i].x),(int)(corners[i].y)), //圆心
6, //半径
color,//颜色
2, //貌似是线宽
CV_AA,//线型
0 //圆心坐标和和半径的小数点的数目
);
}
cvShowImage("IMAGE",sourceImage);
cvWaitKey(0);
//释放资源
cvReleaseImage(&sourceImage);
cvReleaseImage(&corners1);
cvReleaseImage(&corners2);
cvReleaseImage(&grayImage);
cvDestroyWindow("IMAGE");
return 0;
}
运行结果:
Reference《学习opencv》