OpenCV3之——查找并绘制轮廓findContours()和drawContours(),我们先来看看下面的基础示例:
#include
using namespace cv;
using namespace std;
int main() {
Mat srcImage = imread("1.jpg", 0);
imshow("原始图", srcImage);
Mat dstImage = Mat::zeros(srcImage.rows, srcImage.cols, CV_8UC3);
srcImage = srcImage > 119;//srcImage取大于阈值119的那部分
imshow("取阈值后的原始图", srcImage);
//定义轮廓和层次结构
vector
vector
findContours(srcImage, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
int index = 0;
for (; index >= 0; index = hierarchy[index][0]) {
Scalar color(rand() & 255, rand() & 255, rand() & 255);
drawContours(dstImage, contours, index, color, CV_FILLED, 8, hierarchy);
}
imshow("轮廓图", dstImage);
waitKey(0);
return 0;
}
运行效果如下图:
再看下综合示例:
#include
#include
using namespace std;
using namespace cv;
#define WINDOW_NAME1 "原始窗口"
#define WINDOW_NAME2 "轮廓图"
//全局变量声明
Mat g_srcImage;
Mat g_grayImage;
int g_nThresh = 80;
int g_nThresh_max = 255;
RNG g_rng(12345);
Mat g_cannyMat_output;
vector
vector
//全局函数声明部分
void on_ThreshChange(int, void *);
int main() {
system("color 1F");
g_srcImage = imread("1.jpg", 1);
if (!g_srcImage.data) {
printf("图片读入错误!\n");
return false;
}
cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
blur(g_grayImage, g_grayImage, Size(3, 3));
//创建窗口
namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
imshow(WINDOW_NAME1, g_srcImage);
//创建滚动条并初始化
createTrackbar("canny阈值", WINDOW_NAME1, &g_nThresh, g_nThresh_max, on_ThreshChange);
on_ThreshChange(0, 0);
waitKey(0);
return 0;
}
void on_ThreshChange(int, void*) {
//用Canny算子检测边缘
Canny(g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh * 2, 3);
//寻找轮廓
findContours(g_cannyMat_output, g_vContours, g_vHierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
//绘出轮廓
Mat drawing = Mat::zeros(g_cannyMat_output.size(), CV_8UC3);
for (int i = 0; i < g_vContours.size(); i++) {
Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));
drawContours(drawing, g_vContours, i, color, 2, 8, g_vHierarchy, 0, Point());
}
imshow(WINDOW_NAME2, drawing);
}
运行效果如下图:
#include "cv.h"
#include "highgui.h"
using namespace cv;
int main( int argc, char** argv )
{
Mat src;
// the first command-line parameter must be a filename of the binary
// (black-n-white) image
if( argc != 2 || !(src=imread(argv[1], 0)).data)
return -1;
Mat dst = Mat::zeros(src.rows, src.cols, CV_8UC3);
src = src > 1;
namedWindow( "Source", 1 );
imshow( "Source", src );
vector > contours;
vector hierarchy;
findContours( src, contours, hierarchy,
CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
// iterate through all the top-level contours,
// draw each connected component with its own random color
int idx = 0;
for( ; idx >= 0; idx = hierarchy[idx][0] )
{
Scalar color( rand()&255, rand()&255, rand()&255 );
drawContours( dst, contours, idx, color, CV_FILLED, 8, hierarchy );
}
namedWindow( "Components", 1 );
imshow( "Components", dst );
waitKey(0);
}
注意基本学习方法,查看官方文档,不会的方法查看官方文档和相关参数方法
ht t p ://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=findcontours#void findContours(InputOutputArray image, OutputArrayOfArrays contours, int mode, int method, Point offset)
也可以采用如下方式
Mat g_grayImage,g_cannayMat_output;
int g_nThresh = 80;
RNG g_rng(12345);
// canny算子检测边缘
Canny(g_grayImage,g_cannyMat_output,g_nThresh,g_nThresh*2,3);
//寻找轮廓
findContours(g_cannyMat_output,contours,hierarchy,RETR_TREE,
CHAIN_APPROX_SIMPLE,Point(0,0));
Mat drawing = Mat::zero(g_cannyMat_output.size(),CV_8UC3);
//绘制轮廓
for(int i = 0;i
Scalar color = Scalar(g_rng.uniform(0,255),g_rng.uniform(0,255),
g_rng.uniform(0,255)); //任意值
drawContours(drawing,contours,i,color,2,8,hierarchy,0,Point());
}
imshow(WINDOW_NAME,drawing);
1、可以变成灰度图也可以不变。这里假设你的图像都是IPL_DEPTH_8U类型。
2、如果变成灰度图,就是单通道图像,获取的就是每一个像素点的灰度值。
IplImage* img = cvLoadImage("test.bmp", 0);
for (int i = 0; i height; i++)
{
for (int j = 0; j width; j++)
{
//方法一:使用cvGet2D()函数间接访问
CvScalar s = cvGet2D(img, i, j); //其中i代表y轴(第i行),即height;j代表x轴(第j列),即width。
printf("gray value=%f\n",s.val[0]);
//方法二:使用直接访问
uchar val = ((uchar *)(img->imageData + i*img->widthStep))[j]; //i和j的意义同上
printf("gray value=%d\n",val);
}
}
3、如果不变成灰度图,就是3通道图像,获取的就是每一个像素点的BGR值,然后分别获取B值,G值和R值。
IplImage* img = cvLoadImage("test.bmp", 1);
for (int i = 0; i height; i++)
{
for (int j = 0; j width; j++)
{
//方法一:使用cvGet2D()函数间接访问
CvScalar s=cvGet2D(img,i,j); //其中i代表y轴(第i行),即height;j代表x轴(第j列),即width。
printf("B=%f, G=%f, R=%f\n",s.val[0],s.val[1],s.val[2]); //注意是BGR顺序
//方法二:使用直接访问
int bVal = ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]; // B
int gVal = ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]; // G
int rVal = ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]; // R
printf("B=%d, G=%d, R=%d\n",bVal,gVal,rVal); //注意是BGR顺序
}
}
opencv中的imread函数用法为:
Mat imread(const string& filename, intflags=1 );
其中第一个参数是载入图片名,第二个参数是int类型的flags,为载入标识,它指定一个加载图像的颜色类型。可以看到它自带缺省值1.在higui_c.h中发现这个枚举的定义是这样的:
enum
{
/* 8bit, color or not */
CV_LOAD_IMAGE_UNCHANGED =-1,
/* 8bit, gray */
CV_LOAD_IMAGE_GRAYSCALE =0,
/* ?, color */
CV_LOAD_IMAGE_COLOR =1,
/* any depth, ? */
CV_LOAD_IMAGE_ANYDEPTH =2,
/* ?, any color */
CV_LOAD_IMAGE_ANYCOLOR =4
};
其中:
flags >0返回一个3通道的彩色图像。
flags =0返回灰度图像。
flags <0返回包含Alpha通道的加载的图像。
你用函数的时候没有设置第二个参数,就会默认值为1。尽管你读入的是灰度图,还是自动转化成三通道图像。可以将第二个参数置为0得到灰度图像
先灰度化->二值化,弄成二值图,你就会提取了
给你个例子
C/C++ code
#include
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include
using namespace std;
#pragma comment(lib,"cv.lib")
#pragma comment(lib,"cxcore.lib")
#pragma comment(lib,"highgui.lib")
struct Position
{
int x,y;
};
double per[256];// 保存灰度概率
IplImage *FindCountours(IplImage* src,IplImage *pContourImg);
int ImageStretchByHistogram(IplImage *src,IplImage *dst);
IplImage* Hist_Equalization(IplImage *srcimg);
void proBorder(IplImage *src); // 边界的处理
void GetBackImage(IplImage* src,IplImage* src_back);
void Threshold(IplImage *src);
int GetThreshold(double *const prob);
void Getprobability(IplImage *src);
double Eccentricity(IplImage *src);
void main()
{
//IplImage * src = cvLoadImage("C:\\image19\\A634.jpg",-1);//灰度图的方式载入
IplImage * src = cvLoadImage("C:\\image19\\A857.jpg",-1);
IplImage * dst = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,3);
IplImage *src_back = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,src->nChannels);
GetBackImage(src,src_back);
dst = FindCountours(src_back,dst);
cvNamedWindow("test",CV_WINDOW_AUTOSIZE);
cvShowImage("test",dst);
cvWaitKey(0);
cvReleaseImage(&src);
cvReleaseImage(&dst);
}
void GetBackImage(IplImage* src,IplImage* src_back)
{
//cvCvtColor(src,src,CV_RGB2GRAY);//灰度化
IplImage *tmp = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,3);
// 创建结构元素
IplConvKernel *element = cvCreateStructuringElementEx( 2, 2, 0, 0, CV_SHAPE_ELLIPSE,0);
//用该结构对源图象进行数学形态学的开操作后,估计背景亮度
cvErode(src,tmp,element,9);
//使用任意结构元素腐蚀图像
cvDilate(tmp,src_back, element,9);
//使用任意结构元素膨胀图像
}
IplImage *FindCountours(IplImage* src,IplImage *pContourImg)
{
CvMemStorage *storage = cvCreateMemStorage(0); //提取轮廓需要的储存容量为默认KB
CvSeq * pcontour = 0; //提取轮廓的序列指针
IplImage *temp = cvCreateImage(cvGetSize(src),src->depth,1);
//cvSmooth(src,temp,CV_GAUSSIAN,3,1,0);
cvSmooth(src,src,CV_GAUSSIAN,3,1,0);//平滑处理
cvCvtColor(src,temp,CV_RGB2GRAY);//灰度化
Getprobability(temp);
printf("最好的阈值:%d\n",GetThreshold(per));
//Threshold(temp);
proBorder(temp);
cvThreshold(temp,temp,GetThreshold(per),255,CV_THRESH_BINARY_INV);
int contoursNum = 0; // 轮廓数量
//int mode = CV_RETR_LIST;
int mode = CV_RETR_EXTERNAL;// 提取最外层轮廓
contoursNum = cvFindContours(temp,storage,&pcontour,sizeof(CvContour),mode,CV_CHAIN_APPROX_NONE);
// contoursNum = cvFindContours(temp,storage,&pcontour,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));
//二值图, 得到轮廓存储,轮廓指针序列,header_size,提取模式,逼近方法
CvScalar externalColor;// 保存颜色值
CvScalar holeColor;
//————–画轮廓—————-//
for (; pcontour != 0; pcontour=pcontour -> h_next)
{
//holeColor=CV_RGB(rand()&255,rand()&255,rand()&255);
//externalColor=CV_RGB(rand()&255,rand()&255,rand()&255);
CvRect r = ((CvContour *)pcontour)->rect;
if(r.height * r.width < 800)
{
holeColor=CV_RGB(0,0,0);
externalColor=CV_RGB(0,0,0);
cvDrawContours(pContourImg,pcontour,externalColor,holeColor,1,1,8);
}
else
{
//取得轮廓面积
double contArea = fabs(cvContourArea(pcontour,CV_WHOLE_SEQ));
//取得轮廓长度
double contLenth = cvArcLength(pcontour,CV_WHOLE_SEQ,-1);
// 圆形度
double contcircularity = contLenth * contLenth / contArea;
double pxl =Eccentricity(temp);
cout<<"面积为:"<
cout<<"周长为:"<
cout<<"圆形度为:"<
holeColor=CV_RGB(255,255,255);
externalColor=CV_RGB(255,255,255);
cvDrawContours(pContourImg,pcontour,externalColor,holeColor,1,1,8);
}
}
//IplConvKernel *element = cvCreateStructuringElementEx( 2, 2, 0, 0, CV_SHAPE_ELLIPSE,0);
//cvDilate(pContourImg,pContourImg, element,9);
return pContourImg;
}
double Eccentricity(IplImage *src)//偏心率
{
Position pos[4];
int width = src->width;
int height = src->height;
int i,j;
for(i = 0; i < height; i++)
{
for(j = 0; j < width; j++)
{
int pixel = (int)cvGet2D(src,i,j).val[0];
if(pixel != 0)
{
pos[0].x = j;
pos[0].y = i;//
goto s;
}
}
}
s:
for(i = height – 1; i >= 0; i–)
{
for(j = 0; j < width ; j++)
{
int pixel = (int)cvGet2D(src,i,j).val[0];
if(pixel != 0)
{
pos[1].x = j;
pos[1].y = i;//
goto w;
}
}
}
w:
for(i = 0 ; i < width ; i++)
{
for(j = 0;j < height; j++)
{
int pixel = (int)cvGet2D(src,j,i).val[0];
if(pixel != 0)
{
pos[2].x = j;//
pos[2].y = i;
goto e;
}
}
}
e:
for(i = width – 1; i >= 0; i–)
{
for(j = 0 ; j < height ; j++)
{
int pixel = (int)cvGet2D(src,j,i).val[0];
if(pixel != 0)
{
pos[3].x = j;//
pos[3].y = i;
goto f;
}
}
}
f:
int l_dis = abs(pos[0].y – pos[1].y);
int s_dis = abs(pos[2].x – pos[3].x);
int tmp_dis;
if(l_dis > s_dis)
{
printf("偏心率:%f\n",l_dis*1.0/s_dis);
}
else
{
tmp_dis = l_dis;
l_dis = s_dis;
s_dis = tmp_dis;
printf("偏心率:%f\n",l_dis*1.0/s_dis);
}
return 0;
}
void Getprobability(IplImage *src)
{
memset(per,0,sizeof(per));
int width = src->width;
int height = src->height;
for(int i = 0; i < height; i++) {
for(int j = 0; j < width; j++) {
per[(int)cvGet2D(src,i,j).val[0]]++;
}
}
int PixlNum = width * height;
for(i = 0; i < 256; i++)
per[i] = per[i] / PixlNum;
}
int GetThreshold(double *const prob)
{
int threshold = 0;
double maxf = 0;
for (int crrctThrshld = 1; crrctThrshld < 256 – 1; ++crrctThrshld) {
double W0 = 0, W1 = 0, U0 = 0, U1 = 0;
int i = 0;
for (i = 0; i <= crrctThrshld; ++i) {
U0 += i * prob[i];
W0 += prob[i];
}
for (; i < 256; ++i) {
U1 += i * prob[i];
W1 += prob[i];
}
if (W1 == 0 || W1 == 0)
continue;
U0 /= W0;
U1 /= W1;
double D0 = 0, D1= 0;
for (i = 0; i <= crrctThrshld; ++i)
D0 += pow((i – U0) * prob[i], 2.0);
for (; i < 256; ++i)
D1 += pow((i – U1) * prob[i], 2.0);
D0 /= W0;
D1 /= W1;
double Dw = pow(D0, 2.0) * W0 + pow(D1, 2.0) * W1;
double Db = W0 * W1 * pow((U1 – U0), 2.0);
double f = Db / (Db + Dw);
if (maxf < f) {
maxf = f;
threshold = crrctThrshld;
}
}
return threshold;
}
void proBorder(IplImage *src) // 边界的处理
{
int i,j;
int height = src->height;
int width = src->width;
int N = 100;
for(i = 0; i < N * width; i += width) // i表示向下走左上角
{
for(j = 0; j < N ; j++)
{
int index = i + j;
src->imageData[index] = (char)255;
}
}
int NN = 150;
int sw = width * (height – NN);// 左下角 三角形
int t = 1;
for(i = sw; i < sw + NN * width; i += width,t++)
{
for(j = 0; j < t; j++)
{
int index = i + j;
src->imageData[index] = (char)255;
}
}
int se = (height – NN – 1) * width; // 右下角
t = 0;
for(i = se; i < width * height ; i += width,t++)
{
for(j = 0; j < t; j++)
{
int index = i + j – t;
src->imageData[index] = (char)255;
}
}
int ne = width – NN; // 右上角 三角形剪切
t = 0;
for(i = ne; i < NN * width; i +=width,t++)
{
for(j = 0; j < NN – t; j++)
{
int index = i + j + t;
src->imageData[index] = (char)255;
}
}
}
void Threshold(IplImage *src)
{
int width = src->width;
int height = src->height;
float minpixel = cvGet2D(src,0,0).val[0];
float maxpixel = cvGet2D(src,0,0).val[0];
CvScalar s;
for(int i = 0; i < height; i++){
for(int j = 0; j < width; j++){
s = cvGet2D(src,i,j);
if(s.val[0] > maxpixel)
maxpixel = s.val[0];
if(s.val[0] < minpixel)
minpixel = s.val[0];
}
}
float firstgrey = (maxpixel + minpixel) / 2;
printf("%f\n",firstgrey);
float lastgrey;
float sum1 = 0,sum2 = 0;
int num1 = 0,num2 = 0;
int result = 0;
1、cvLoadImage:将图像文件加载至内存;
2、cvNamedWindow:在屏幕上创建一个窗口;
3、cvShowImage:在一个已创建好的窗口中显示图像;
4、cvWaitKey:使程序暂停,等待用户触发一个按键操作;
5、cvReleaseImage:释放图像文件所分配的内存;
6、cvDestroyWindow:销毁显示图像文件的窗口;
7、cvCreateFileCapture:通过参数设置确定要读入的AVI文件;
8、cvQueryFrame:用来将下一帧视频文件载入内存;
9、cvReleaseCapture:释放CvCapture结构开辟的内存空间;
10、cvCreateTrackbar:创建一个滚动条;
11、cvSetCaptureProperty:设置CvCapture对象的各种属性;
12、cvGetCaptureProperty:查询CvCapture对象的各种属性;
13、cvGetSize:当前图像结构的大小;
14、cvSmooth:对图像进行平滑处理;
15、cvPyrDown:图像金字塔,降采样,图像缩小为原来四分之一;
16、cvCanny:Canny边缘检测;
17、cvCreateCameraCapture:从摄像设备中读入数据;
18、cvCreateVideoWriter:创建一个写入设备以便逐帧将视频流写入视频文件;
19、cvWriteFrame:逐帧将视频流写入文件;
20、cvReleaseVideoWriter:释放CvVideoWriter结构开辟的内存空间;
21、CV_MAT_ELEM:从矩阵中得到一个元素;
22、cvAbs:计算数组中所有元素的绝对值;
23、cvAbsDiff:计算两个数组差值的绝对值;
24、cvAbsDiffS:计算数组和标量差值的绝对值;
25、cvAdd:两个数组的元素级的加运算;
26、cvAddS:一个数组和一个标量的元素级的相加运算;
27、cvAddWeighted:两个数组的元素级的加权相加运算(alpha运算);
28、cvAvg:计算数组中所有元素的平均值;
29、cvAvgSdv:计算数组中所有元素的绝对值和标准差;
30、cvCalcCovarMatrix:计算一组n维空间向量的协方差;
31、cvCmp:对两个数组中的所有元素运用设置的比较操作;
32、cvCmpS:对数组和标量运用设置的比较操作;
33、cvConvertScale:用可选的缩放值转换数组元素类型;
34、cvCopy:把数组中的值复制到另一个数组中;
35、cvCountNonZero:计算数组中非0值的个数;
36、cvCrossProduct:计算两个三维向量的向量积(叉积);
37、cvCvtColor:将数组的通道从一个颜色空间转换另外一个颜色空间;
38、cvDet:计算方阵的行列式;
39、cvDiv:用另外一个数组对一个数组进行元素级的除法运算;
40、cvDotProduct:计算两个向量的点积;
41、cvEigenVV:计算方阵的特征值和特征向量;
42、cvFlip:围绕选定轴翻转;
43、cvGEMM:矩阵乘法;
44、cvGetCol:从一个数组的列中复制元素;
45、cvGetCols:从数据的相邻的多列中复制元素;
46、cvGetDiag:复制数组中对角线上的所有元素;
47、cvGetDims:返回数组的维数;
48、cvGetDimSize:返回一个数组的所有维的大小;
49、cvGetRow:从一个数组的行中复制元素值;
50、cvGetRows:从一个数组的多个相邻的行中复制元素值;
51、cvGetSize:得到二维的数组的尺寸,以CvSize返回;
52、cvGetSubRect:从一个数组的子区域复制元素值;
53、cvInRange:检查一个数组的元素是否在另外两个数组中的值的范围内;
54、cvInRangeS:检查一个数组的元素的值是否在另外两个标量的范围内;
55、cvInvert:求矩阵的逆;
56、cvMahalonobis:计算两个向量间的马氏距离;
57、cvMax:在两个数组中进行元素级的取最大值操作;
58、cvMaxS:在一个数组和一个标量中进行元素级的取最大值操作;
59、cvMerge:把几个单通道图像合并为一个多通道图像;
60、cvMin:在两个数组中进行元素级的取最小值操作;
61、cvMinS:在一个数组和一个标量中进行元素级的取最小值操作;
62、cvMinMaxLoc:寻找数组中的最大最小值;
63、cvMul:计算两个数组的元素级的乘积(点乘);
64、cvNot:按位对数组中的每一个元素求反;
65、cvNormalize:将数组中元素进行归一化;
66、cvOr:对两个数组进行按位或操作;
67、cvOrs:在数组与标量之间进行按位或操作;
68、cvReduce:通过给定的操作符将二维数组简为向量;
69、cvRepeat:以平铺的方式进行数组复制;
70、cvSet:用给定值初始化数组;
71、cvSetZero:将数组中所有元素初始化为0;
72、cvSetIdentity:将数组中对角线上的元素设为1,其他置0;
73、cvSolve:求出线性方程组的解;
74、cvSplit:将多通道数组分割成多个单通道数组;
75、cvSub:两个数组元素级的相减;
76、cvSubS:元素级的从数组中减去标量;
77、cvSubRS:元素级的从标量中减去数组;
78、cvSum:对数组中的所有元素求和;
79、cvSVD:二维矩阵的奇异值分解;
80、cvSVBkSb:奇异值回代计算;
81、cvTrace:计算矩阵迹;
82、cvTranspose:矩阵的转置运算;
83、cvXor:对两个数组进行按位异或操作;
84、cvXorS:在数组和标量之间进行按位异或操作;
85、cvZero:将所有数组中的元素置为0;
86、cvConvertScaleAbs:计算可选的缩放值的绝对值之后再转换数组元素的类型;
87、cvNorm:计算数组的绝对范数, 绝对差分范数或者相对差分范数;
88、cvAnd:对两个数组进行按位与操作;
89、cvAndS:在数组和标量之间进行按位与操作;
90、cvScale:是cvConvertScale的一个宏,可以用来重新调整数组的内容,并且可以将参数从一种数
据类型转换为另一种;
91、cvT:是函数cvTranspose的缩写;
92、cvLine:画直线;
93、cvRectangle:画矩形;
94、cvCircle:画圆;
95、cvEllipse:画椭圆;
96、cvEllipseBox:使用外接矩形描述椭圆;
97、cvFillPoly、cvFillConvexPoly、cvPolyLine:画多边形;
98、cvPutText:在图像上输出一些文本;
99、cvInitFont:采用一组参数配置一些用于屏幕输出的基本个特定字体;
100、cvSave:矩阵保存;
101、cvLoad:矩阵读取;
102、cvOpenFileStorage:为读/写打开存储文件;
103、cvReleaseFileStorage:释放存储的数据;
104、cvStartWriteStruct:开始写入新的数据结构;
105、cvEndWriteStruct:结束写入数据结构;
106、cvWriteInt:写入整数型;
107、cvWriteReal:写入浮点型;
108、cvWriteString:写入字符型;
109、cvWriteComment:写一个XML或YAML的注释字串;
110、cvWrite:写一个对象;
111、cvWriteRawData:写入多个数值;
112、cvWriteFileNode:将文件节点写入另一个文件存储器;
113、cvGetRootFileNode:获取存储器最顶层的节点;
114、cvGetFileNodeByName:在映图或存储器中找到相应节点;
115、cvGetHashedKey:为名称返回一个惟一的指针;
116、cvGetFileNode:在映图或文件存储器中找到节点;
117、cvGetFileNodeName:返回文件的节点名;
118、cvReadInt:读取一个无名称的整数型;
119、cvReadIntByName:读取一个有名称的整数型;
120、cvReadReal:读取一个无名称的浮点型;
121、cvReadRealByName:读取一个有名称的浮点型;
122、cvReadString:从文件节点中寻找字符串;
123、cvReadStringByName:找到一个有名称的文件节点并返回它;
124、cvRead:将对象解码并返回它的指针;
125、cvReadByName:找到对象并解码;
126、cvReadRawData:读取多个数值;
127、cvStartReadRawData:初始化文件节点序列的读取;
128、cvReadRawDataSlice:读取文件节点的内容;
129、cvGetModuleInfo:检查IPP库是否已经正常安装并且检验运行是否正常;
130、cvResizeWindow:用来调整窗口的大小;
131、cvSaveImage:保存图像;
132、cvMoveWindow:将窗口移动到其左上角为x,y的位置;
133、cvDestroyAllWindow:用来关闭所有窗口并释放窗口相关的内存空间;
134、cvGetTrackbarPos:读取滑动条的值;
135、cvSetTrackbarPos:设置滑动条的值;
136、cvGrabFrame:用于快速将视频帧读入内存;
137、cvRetrieveFrame:对读入帧做所有必须的处理;
138、cvConvertImage:用于在常用的不同图像格式之间转换;
139、cvErode:形态腐蚀;
140、cvDilate:形态学膨胀;
141、cvMorphologyEx:更通用的形态学函数;
142、cvFloodFill:漫水填充算法,用来进一步控制哪些区域将被填充颜色;
143、cvResize:放大或缩小图像;
144、cvPyrUp:图像金字塔,将现有的图像在每个维度上都放大两倍;
145、cvPyrSegmentation:利用金字塔实现图像分割;
146、cvThreshold:图像阈值化;
147、cvAcc:可以将8位整数类型图像累加为浮点图像;
148、cvAdaptiveThreshold:图像自适应阈值;
149、cvFilter2D:图像卷积;
150、cvCopyMakeBorder:将特定的图像轻微变大,然后以各种方式自动填充图像边界;
151、cvSobel:图像边缘检测,Sobel算子;
152、cvLaplace:拉普拉斯变换、图像边缘检测;
153、cvHoughLines2:霍夫直线变换;
154、cvHoughCircles:霍夫圆变换;
155、cvRemap:图像重映射,校正标定图像,图像插值;
156、cvWarpAffine:稠密仿射变换;
157、cvGetQuadrangleSubPix:仿射变换;
158、cvGetAffineTransform:仿射映射矩阵的计算;
159、cvCloneImage:将整个IplImage结构复制到新的IplImage中;
160、cv2DRotationMatrix:仿射映射矩阵的计算;
161、cvTransform:稀疏仿射变换;
162、cvWarpPerspective:密集透视变换(单应性);
163、cvGetPerspectiveTransform:计算透视映射矩阵;
164、cvPerspectiveTransform:稀疏透视变换;
165、cvCartToPolar:将数值从笛卡尔空间到极坐标(极性空间)进行映射;
166、cvPolarToCart:将数值从极性空间到笛卡尔空间进行映射;
167、cvLogPolar:对数极坐标变换;
168、cvDFT:离散傅里叶变换;
169、cvMulSpectrums:频谱乘法;
170、cvDCT:离散余弦变换;
171、cvIntegral:计算积分图像;
172、cvDistTransform:图像的距离变换;
173、cvEqualizeHist:直方图均衡化;
174、cvCreateHist:创建一新直方图;
175、cvMakeHistHeaderForArray:根据已给出的数据创建直方图;
176、cvNormalizeHist:归一化直方图;
177、cvThreshHist:直方图阈值函数;
178、cvCalcHist:从图像中自动计算直方图;
179、cvCompareHist:用于对比两个直方图的相似度;
180、cvCalcEMD2:陆地移动距离(EMD)算法;
181、cvCalcBackProject:反向投影;
182、cvCalcBackProjectPatch:图块的方向投影;
183、cvMatchTemplate:模板匹配;
184、cvCreateMemStorage:用于创建一个内存存储器;
185、cvCreateSeq:创建序列;
186、cvSeqInvert:将序列进行逆序操作;
187、cvCvtSeqToArray:复制序列的全部或部分到一个连续内存数组中;
188、cvFindContours:从二值图像中寻找轮廓;
189、cvDrawContours:绘制轮廓;
190、cvApproxPoly:使用多边形逼近一个轮廓;
191、cvContourPerimeter:轮廓长度;
192、cvContoursMoments:计算轮廓矩;
193、cvMoments:计算Hu不变矩;
194、cvMatchShapes:使用矩进行匹配;
195、cvInitLineIterator:对任意直线上的像素进行采样;
196、cvSampleLine:对直线采样;
197、cvAbsDiff:帧差;
198、cvWatershed:分水岭算法;
199、cvInpaint:修补图像;
200、cvGoodFeaturesToTrack:寻找角点;
201、cvFindCornerSubPix:用于发现亚像素精度的角点位置;
202、cvCalcOpticalFlowLK:实现非金字塔的Lucas-Kanade稠密光流算法;
203、cvMeanShift:mean-shift跟踪算法;
204、cvCamShift:camshift跟踪算法;
205、cvCreateKalman:创建Kalman滤波器;
206、cvCreateConDensation:创建condensation滤波器;
207、cvConvertPointsHomogenious:对齐次坐标进行转换;
208、cvFindChessboardCorners:定位棋盘角点;
209、cvFindHomography:计算单应性矩阵;
210、cvRodrigues2:罗德里格斯变换;
211、cvFitLine:直线拟合算法;
212、cvCalcCovarMatrix:计算协方差矩阵;
213、cvInvert:计算协方差矩阵的逆矩阵;
214、cvMahalanobis:计算Mahalanobis距离;
215、cvKMeans2:K均值;
216、cvCloneMat:根据一个已有的矩阵创建一个新矩阵;
217、cvPreCornerDetect:计算用于角点检测的特征图;
218、cvGetImage:CvMat图像数据格式转换成IplImage图像数据格式;
219、cvMatMul:两矩阵相乘;
对图像的不规则区域设置ROI
OpenCV自带的函数cvSetImageROI( IplImage* image, CvRect rect )只能设置矩形的敏感区域,而实际图像处理中遇到的处理对象都是非矩形的不规则形状,此时用cvSetImageROI( IplImage* image, CvRect rect )显然达不到目的。我们可以用以下操作进行代替。
//----------------------------------------------------------
方法一:
cvCopy(src,dst,mask);
//mask与src,dst通道数可以不一样。
方法二:
cvXor(src,mask,dst);
//三者通道数必须一样。
//----------------------------------------------------------
用上面语句就可以将不规则区域图像抠出来(不改变图像的大小),进而做相应的处理。然而如何生成不规则区域的mask图像呢?
不规则区域的mask图像的生成(假设目标是实现对一不规则物体区域设置ROI)
步骤:
1. 提取物体的最外围轮廓contour,使之为一连通域。
//----------------------------------------------------------
cvFindContours( gray, storage, &contour, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
//----------------------------------------------------------
2. 对轮廓连通域进行颜色填充。
//----------------------------------------------------------
方法一:
获取轮廓内的任意一点作为cvFloodFill操作的起始种子点:
CvRect s;
CvPoint pt;
s=cvBoundingRect(contour);
pt = cvPoint(s.x+s.width/2,s.y+s.height/2);//-------可以用其他方式获得连通域的一个内点作为起始种子点
对轮廓连通域进行颜色填充:
cvFloodFill(gray, pt ,cvScalarAll(255));
方法二:
将轮廓内部填充为白色,其他区域为黑色:
cvDrawContours(gray, contour, CV_RGB(255,255,255), CV_RGB(255,255 ,255), -1, CV_FILLED, 8);
//----------------------------------------------------------
3. 此时获得的图像gray即为不规则区域的mask。