学习OpenCV时做的笔记
1、文件操作:
#include "cv.h"
#include "highgui.h"
int main(int argc, char **argv) {
IplImage *pImg;
//载入图像
if(argc==2 && (pImg = cvLoadImage(argv[1],1))!=0)
{
cvNamedWindow("Image", 1);//创建窗口
cvShowImage("Image", pImg);//显示图像
cvWaitKey(0);//等待按键
cvDestroyWindow("Image");//销毁窗口
cvReleaseImage(&pImg);//释放图像
return 0;
}
else if(argc==3 && (pImg = cvLoadImage(argv[1],1))!=0)
{
IplImage *pImg2 = cvCreateImage(cvGetSize(pImg),
pImg->depth,
pImg->nChannels);
cvCopy(pImg, pImg2, NULL);
cvSaveImage(argv[2], pImg2);//把图像写入文件
cvNamedWindow("Image", 1);//创建窗口
cvShowImage("Image", pImg);//显示图像
cvWaitKey(0);//等待按键
cvDestroyWindow("Image");//销毁窗口
cvReleaseImage(&pImg);//释放图像
return 0;
}
return -1;
}
2、基本数据结构的声明和初始化:
#include
#include
void main()
{
CvPoint point;//二维整型点
point.x = 10;
point.y = 20;
CvPoint3D32f point_3d;//三维浮点型点
point_3d.x = 5.;
point_3d.y = 5.;
point_3d.z = 5.;
CvSize Rect_Size;//矩形框大小变量
Rect_Size.width = 100;
Rect_Size.height = 100;
CvRect Sub_Rect;//矩形框变量
Sub_Rect.x = 0;
Sub_Rect.y = 0;
Sub_Rect.width = 10;
Sub_Rect.height = 10;
CvScalar value;//TUPLE类型的捆绑数据的容量
value = cvScalar(0.0, 1.0, 2.0, 3.0);
//逐一赋值法,也可只赋值前面几个,后面缺省为0
value = cvScalarAll(1.0);//全部赋同样的值
value = cvRealScalar(1.0);//只赋值第一个,后面全部为0
/*矩阵CvMat的两种声明方法和初始化方法*/
//方法一:直接声明
CvMat mat_01;//矩阵变量
double a[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
mat_01 = cvMat(3, 3, CV_64FC1, a);//初始化矩阵的头
cvReleaseData(&mat_01);//释放矩阵
//方法二:矩阵变量(以指针方式声明)
CvMat *mat_ptr;
double b[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
mat_ptr = cvCreateMat(3, 3, CV_64FC1);
//指明矩阵头的类型:CV_64FC1
cvInitMatHeader(mat_ptr, 3, 3, CV_64FC1, b);
//初始化矩阵头
cvReleaseMat(&mat_ptr);//释放矩阵
/*图像头IplImage的声明和初始化*/
IplImage *src = cvLoadImage("zjut.jpg", -1);
//这里假定源文件下游zjut.jpg这幅图片
IplImage *dst;//声明一图像头指针
dst = cvCreateImage(cvSize(src->width, src->height),
src->depth, src->nChannels);
cvFlip(src, dst, 1);//图像zjut.jpg绕y轴翻转
//创建显示图像窗口
cvNamedWindow("zjut", CV_WINDOW_AUTOSIZE);
cvNamedWindow("zjut_flip", CV_WINDOW_AUTOSIZE);
cvShowImage("zjut", src);//显示源图像
cvShowImage("zjut_flip", dst);
cvWaitKey(0);
cvReleaseImage(&src);//释放图像头
cvReleaseImage(&dst);
}
3、 IplImage结构的一些基本信息:
#include
#include
#include
void main()
{
IplImage *src_img = cvLoadImage("stuff.jpg", -1);
IplImage *dst_img;
//以下为显示读入图像的一些信息
cout << "????????????????????" << endl << endl;
cout << "lena.bmp的图像信息" << endl << endl;
cout << "????????????????????" << endl << endl;
//IplImage该结构体的大小:112字节
cout << "Img's size: " << src_img->nSize << endl;
//版本ID:0
cout << "Img's ID: " << src_img->ID << endl;
//显示读入图像信道数:3
cout << "Img's channel's nums: " << src_img->nChannels << endl;
//像素的位深度:8
cout << "Img's depth: " << src_img->depth << endl;
//0-交叉存取颜色信道
cout << "Img's dataOrder: " << src_img->dataOrder << endl;
//0-图像数据分布结构:顶-左结构
cout << "Img's origin: " << src_img->origin << endl;
//图像宽像素数:400
cout << "Img's width: " << src_img->width << endl;
//图像高度像素数:600
cout << "Img's height: " << src_img->height << endl;
//未指定ROI区域指针为空:0x00000000:
cout << "Img's ROI: " << src_img->roi << endl;
//排列的图像行大小:1200
cout << "Img's widthStep:: " << src_img->widthStep << endl;
/*图像数据大小(在交叉存储格式下imageSize =
image->height * image->widthStep),单位字节*/
cout << "Img's imageSize: " << src_img->imageSize << endl;
//输出图像一块区域像素对应的RGB值
for(int i=0; i<200; i=i+3)
{
cout << (int)(uchar)src_img->imageData[i] << " "//Blue
<< (int)(uchar)src_img->imageData[i+1] << " "//Green
<< (int)(uchar)src_img->imageData[i+2] << " "//Red
<< endl;
}
dst_img = cvCreateImage(cvSize(src_img->width, src_img->height),
src_img->depth, 3);
//dst_img是src_img的倒置图像
cvConvertImage(src_img, dst_img, CV_CVTIMG_FLIP);
cvNamedWindow("lena", CV_WINDOW_AUTOSIZE);
cvNamedWindow("lena_flip", CV_WINDOW_AUTOSIZE);
cvShowImage("lena", src_img);
cvShowImage("lena_flip", dst_img);
cvWaitKey(0);
cvReleaseImage(&src_img);//释放图像
cvReleaseImage(&dst_img);
}
4、 ROI的基本操作:
#include
#include
#include
void main()
{
IplImage *src_img = cvLoadImage("lena.bmp", -1);
IplImage *dst_img;//读入目标图像头
CvRect ROI_rect_src;//源图像ROI的位置以及大小
CvRect ROI_rect_dst;//目标图像的ROI
cvNamedWindow("src_img", CV_WINDOW_AUTOSIZE);
cvMoveWindow("src_img", 200, 200);//设置源图像输出的窗口位置
cvShowImage("src_img", src_img);//输出未设置ROI的原始图像
cvWaitKey(800);
//cvSetImageROI
函
关于工期滞后的函关于工程严重滞后的函关于工程进度滞后的回复函关于征求同志党风廉政意见的函关于征求廉洁自律情况的复函
数基于给定的矩形设置感兴趣区域
//cvShowImage函数将只会显示ROI指定区域
ROI_rect_src.x = 0;
ROI_rect_src.y = 0;
ROI_rect_src.width = 120;
ROI_rect_src.height = 100;
cvSetImageROI(src_img, ROI_rect_src);
cout << "输出源图像的ROI区域" << endl;
cout << (src_img->roi->xOffset) << " " << (src_img->roi->yOffset) << endl;
cout << (src_img->roi->width) << " " << (src_img->roi->height) << endl << endl;
cvShowImage("src_img", src_img);//输出设定ROI后的原始图像
/*函数cvCloneImage实现图像的完整复制包括头、ROI区域和数据*/
dst_img = cvCloneImage(src_img);
/*cvGetImageROI得到图像的ROI区域*/
ROI_rect_dst = cvGetImageROI(dst_img);
cout << "输出目标函数的ROI区域" << endl;
cout << ROI_rect_dst.x << " " << ROI_rect_dst.y << endl;
cout << ROI_rect_dst.width << " " << ROI_rect_dst.height << endl;
cvNamedWindow("dst_img", CV_WINDOW_AUTOSIZE);
cvMoveWindow("dst_img", 400, 200);//设置目标输出的窗口位置
cvShowImage("dst_img", dst_img);//显示目标图像
cvWaitKey(800);
cvResetImageROI(dst_img);//释放目标图像的ROI
cvShowImage("dst_img", dst_img);//显示已释放ROI的目标图像
cvWaitKey(0);
cvReleaseImage(&src_img);//释放图像
cvReleaseImage(&dst_img); }
5、矩阵的基本操作(1)
#include
#include
#include
void main()
{
CvMat *mat_01, *mat_02, *mat_03;//声明三个矩阵指针
mat_01 = cvCreateMat(3, 3, CV_64FC1);//指明矩阵头的类型
mat_02 = cvCreateMat(3, 3, CV_64FC1);
mat_03 = cvCreateMat(3, 3, CV_64FC1);
double a[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};//具体存放数据的数组
cvInitMatHeader(mat_01, 3, 3, CV_64FC1, a);//初始化矩阵头
mat_02 = cvCloneMat(mat_01);//mat_02复制mat_01
cvMatMulAdd(mat_01, mat_02, 0, mat_03);//矩阵相乘
//cvMatMulAdd(src1,src2,0,src3)就是实现src3=src1*src2+src3;
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
cout << CV_MAT_ELEM(*mat_01, double, i, j) << " ";
}
cout << endl;
}
/*
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
cout << CV_MAT_ELEM(*mat_03, double, i, j) << " ";
}
cout << endl;
}
*/
cvReleaseMat(&mat_01);
cvReleaseMat(&mat_02);
cvReleaseMat(&mat_03);
}
矩阵的基本操作(2)->添加矩阵元素:
#include
#include
#include
void main()
{
CvScalar value = cvRealScalar(1);
CvMat *mat_01, *mat_02, *mat_03, *mat_04;
mat_01 = cvCreateMat(3, 3, CV_32FC1);
mat_02 = cvCreateMat(3, 3, CV_32FC1);
mat_03 = cvCreateMat(3, 3, CV_32FC1);
mat_04 = cvCreateMat(3, 3, CV_32FC1);
//设置矩阵元素为指定值
cvSet(mat_01, value, NULL);
//矩阵元素清零
cvSetZero(mat_02);
//设置单位矩阵
cvSetIdentity(mat_03, value);
//用指定范围的数来填充矩阵
cvRange(mat_04, 3., 12.);
//这里只输出mat_04的结果(可以修改成mat_01或其他)
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
cout << CV_MAT_ELEM(*mat_04, float, i, j) << " ";
}
cout << endl;
}
cvReleaseMat(&mat_01);
cvReleaseMat(&mat_02);
cvReleaseMat(&mat_03);
cvReleaseMat(&mat_04); }
6、数组的基本操作:(1)得到子数组
#include
#include
#include
#include
void main()
{
int i, j;
CvRect mat_rect = cvRect(1, 1, 3, 3);//指定去的数组子集的范围
// typedef struct CvRect { int x; int y; int width; int height; } CvRect;
CvMat *mat = cvCreateMat(6, 6, CV_64FC1);//原数组
CvMat *submat = cvCreateMat(3, 3, CV_64FC1);//按mat_rect指定取得的数组子集
CvMat *mat_rows = cvCreateMat(2, 6, CV_64FC1);
//按一定跨度内的行取得的数组子集
//设置源数组的数据为1,2,3,4,5...
for(i=0; i<6; i++)
{
for(j=0; j<6; j++)
{
CV_MAT_ELEM(*mat, double, i, j) = i*6 + j;
}
}
//输出源数组的数据
for(i=0; i<6; i++)
{
for(j=0; j<6; j++)
{
cout << setw(3) << CV_MAT_ELEM(*mat, double, i, j);
}
cout << endl;
}
cout << endl;
//根据mat_rect指定的范围取得数组子集
cvGetSubRect(mat, submat, mat_rect);
//输出submat数组子集的数据
for(i=0; i<3; i++)
{
for(j=0; j<3; j++)
{
cout << setw(3) << CV_MAT_ELEM(*submat, double, i, j);
}
cout << endl;
}
cout << endl;
//按照一定跨度内的行取数组子集(这里取一、二行,注意到end_row = 3)
cvGetRows(mat, mat_rows, 1, 3, 1);
//上面的最后三个参数参数:start_row, end_row, delta_row
for(i=0; i<2; i++)
{
for(j=0; j<6; j++)
{
cout << setw(3) << CV_MAT_ELEM(*mat_rows, double, i, j);
}
cout << endl;
}
cout << endl;
cvReleaseMat(&mat);
cvReleaseMat(&submat);
}
数组的基本操作(2)->图像的转换
#include
#include
#include
void main()
{
IplImage *src_img = cvLoadImage("stuff.jpg", -1);
IplImage *repeat_img;
IplImage *dst_img_c1;//通道1图像
IplImage *dst_img_c2;//通道2图像
IplImage *dst_img_c3;//通道3图像
IplImage *dst_img;
//cvRepeat函数的使用
//创建的图像比目标图像大
repeat_img = cvCreateImage(cvSize(src_img->width*2,
(int)(src_img->height*1.5)), IPL_DEPTH_8U, src_img->nChannels);
//用原数组管道式填充输出数组(这里目标数组大于原数组)
cvRepeat(src_img, repeat_img);
cvNamedWindow("lena.bmp", CV_WINDOW_AUTOSIZE);
cvNamedWindow("lena_changed.bmp", CV_WINDOW_AUTOSIZE);
//显示cvRepeat函数使用后repeat_img图像
cvShowImage("lena_changed.bmp", repeat_img);
cvShowImage("lena.bmp", src_img);
//cvFlip函数的使用
cvWaitKey(2000);
//垂直翻转图像
cvFlip(src_img, NULL, -1);
//显示垂直翻转后的源图像
cvShowImage("lena.bmp", src_img);
//cvSplit函数和cvMerge函数的使用
//分离的三个通道
dst_img_c1 = cvCreateImage(cvSize(src_img->width, src_img->height), IPL_DEPTH_8U, 1);
dst_img_c2 = cvCreateImage(cvSize(src_img->width, src_img->height), IPL_DEPTH_8U, 1);
dst_img_c3 = cvCreateImage(cvSize(src_img->width, src_img->height), IPL_DEPTH_8U, 1);
dst_img = cvCreateImage(cvSize(src_img->width, src_img->height), IPL_DEPTH_8U, 3);
//把原彩色图像分离成三个通道
cvSplit(src_img, dst_img_c1, dst_img_c2, dst_img_c3, NULL);
//显示分离出来的一个单通道的灰度图
cvShowImage("lena_single.bmp", dst_img_c1);
cvWaitKey(1000);
//合并分离出来的三个通道,但是不是按照原来的顺序,合并后的图像的色调发生改变
cvMerge(dst_img_c2, dst_img_c1, dst_img_c3, NULL, dst_img);
//显示合并后的图像
cvShowImage("lena_after.bmp", dst_img);
cvWaitKey(1000);
//释放图像
cvReleaseImage(&src_img);
cvReleaseImage(&repeat_img);
cvReleaseImage(&dst_img_c1);
cvReleaseImage(&dst_img_c2);
cvReleaseImage(&dst_img_c3);
cvReleaseImage(&dst_img); }
数组的基本操作(3)->数组的最大最小值等
#include
#include
#include
void main()
{
int i;
int num_nonzero = 0;//数组中非零元素个数
double sum = 0;//数组中全部元素的和
CvScalar mean;//数组所有元素的平均值
CvScalar std_dev;//数组所有元素的
标准
excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载
差
double Max = 0;//数组所有元素中的最大值
double Min = 0;//数组所有元素中的最小值
CvRNG rng_state = cvRNG(0x507656);
//初始化随机数生成状态
CvMat *mat = cvCreateMat(100, 1, CV_64FC1);
//初始化100个元素的数组
//对数组mat赋以服从均匀分布的100个随机数
cvRandArr(&rng_state, mat, CV_RAND_UNI,
cvScalar(0.0, 0., 0.), cvScalar(100.0, 0., 0.));
//输出数组的100个元素的值
for(i=0; i<100; i++)
{
cout << cvGetReal1D(mat, i) << endl;
}
//cvCountNonZero函数计算非零数组元素
num_nonzero = cvCountNonZero(mat);
cout << "数组全部元素个数为:" << (mat->rows * mat->cols) << endl;
cout << "非零的数组元素个数为:" << num_nonzero << endl << endl;
//cvSum函数计算全部元素的和
sum = cvSum(mat).val[0];
cout << "数组全部元素的和为:" << sum << endl << endl;
//cvAvgSdv函数计算全部元素的平均值和标准差
cvAvgSdv(mat, &mean, &std_dev);
cout << "数组全部元素的平均值为:" << mean.val[0] << endl;
cout << "数组全部元素的标准差为:" << std_dev.val[0] << endl << endl;
//cvMinMaxLoc函数查找数组元素的最大值和最小值
cvMinMaxLoc(mat, &Min, &Max, NULL, NULL);
cout << "数组元素中最小值:" << Min << endl;
cout << "数组元素中最大值:" << Max << endl;
cvReleaseMat(&mat);//释放矩阵
}
7、CvSeq:利用点画轮廓
#include
#include
#include
#include
void main()
{
int i = 0;
int mode = CV_RETR_EXTERNAL;//提取轮廓的模式
int contours_num = 0;//图像中提取轮廓的数目
CvMemStorage *storage = cvCreateMemStorage(0);
//提取轮廓时需要的存储容器
CvSeq *contour = 0;//存储提取轮廓的序列指针
IplImage *bin_img = cvLoadImage("bin_img.jpg", 0);
//读取待检测轮廓的图像
cvThreshold(bin_img, bin_img, 128, 255, CV_THRESH_BINARY);
//二值化
IplImage *pContourImg = cvCreateImage(cvGetSize(bin_img), IPL_DEPTH_8U, 3);
cvNamedWindow("bin_img", 1);
cvShowImage("bin_img", bin_img);//显示二值图
//cvFindContours查找物体轮廓
mode = CV_RETR_EXTERNAL;//只提取最外层的轮廓
contours_num = cvFindContours(bin_img, storage,
&contour, sizeof(CvContour), mode, CV_CHAIN_APPROX_NONE);
cout << "检测出的轮廓数目:" << contours_num << " " << endl;
//逐点将轮廓画出
CvSeqReader reader;//读序列
int Count = 0;
if(contour != 0)//输出组成轮廓的点的数目
{
Count = contour->total;
cout << Count << endl;
}
cvStartReadSeq(contour, &reader, 0);
CvPoint pt1;
CvScalar color = CV_RGB(255, 255, 255);
cvNamedWindow("contour", 1);
cvShowImage("contour", pContourImg);
for(i=0; i #include #include
#define thickness 2//线条粗细
#define line_type CV_AA//CV_AA表示抗锯齿类型直线 void main()
{
//CV_RGB(255, 158, 97);三个分量是按R,G,B顺序排列的
CvScalar color = CV_RGB(255, 158, 97);
CvPoint pt1_Rect;//确定外围矩形画框的两个点(对角线上两个点)
CvPoint pt2_Rect;
CvPoint center;//图像中心即是笑脸的中心
int radius = 0;//小脸的半径
//眼睛有关的变量
CvPoint center_l_eye;//左眼的中心
CvPoint center_r_eye;
CvSize axes_eye;//左右眼的大小
double angle_l_eye = 15;//左眼的偏转角:正数表示逆时针转
double angle_r_eye = -15;
double start_angle_eye = 0;
double end_angle_eye = 360;
//嘴巴有关的变量
CvPoint pt1_l_mouth;//嘴角的点
CvPoint pt2_l_mouth;
CvPoint pt1_r_mouth;
CvPoint pt2_r_mouth;
CvSize axes_mouth;//嘴的大小
double angle_mouth = 0;//嘴的偏转角
double start_angle_mouth = 0;//画嘴的圆弧的起始角
double end_angle_mouth = 360;//画嘴的圆弧的终止角
//绘制笑脸的目的图像img的初始化
IplImage *img = cvCreateImage(cvSize(600, 600), IPL_DEPTH_8U, 3);
cvNamedWindow("image", CV_WINDOW_AUTOSIZE);
//外围矩形画框
pt1_Rect.x = 0;
pt1_Rect.y = 0;
pt2_Rect.x = 600;
pt2_Rect.y = 600;
color = CV_RGB(97, 158, 255);
//cvRectangle画矩形
cvRectangle(img, pt1_Rect, pt2_Rect, color, CV_FILLED, line_type, 0);
//笑脸的轮廓
color = CV_RGB(255, 158, 97);//颜色为黄色
center.x = 300;
center.y = 300;
radius = 200;//笑脸半径
//cvCircle画圆形即为笑脸的轮廓
cvCircle(img, center, radius, color, CV_FILLED, line_type, 0);
//画眼睛
color = CV_RGB(156, 25, 255);//眼睛颜色为紫色
center_l_eye.x = 240;
center_l_eye.y = 200;
center_r_eye.x = 360;
center_r_eye.y = 200;
axes_eye.width = 16;
axes_eye.height = 30;
angle_l_eye = 10;
angle_r_eye = -5;
start_angle_eye = 0;//绘制整个椭圆时起始角为0度,终止角为360度
end_angle_eye = 360;
//左眼
cvEllipse(img, center_l_eye, axes_eye, angle_l_eye,
start_angle_eye, end_angle_eye, color, CV_FILLED, line_type, 0);
//右眼
cvEllipse(img, center_r_eye, axes_eye, angle_r_eye,
start_angle_eye, end_angle_eye, color, CV_FILLED, line_type, 0);
//画嘴巴
color = CV_RGB(255, 255, 0);//嘴巴颜色为黄色
pt1_l_mouth.y = 300;
pt1_l_mouth.x = 150;
pt2_l_mouth.y = 270;
pt2_l_mouth.x = 180;
pt1_r_mouth.y = 270;
pt1_r_mouth.x = 400;
pt2_r_mouth.y = 300;
pt2_r_mouth.x = 430;
axes_mouth.width = 130;
axes_mouth.height = 100;
start_angle_mouth = 150;
end_angle_mouth = 347;
angle_mouth = 10;
//左边的嘴角的线段
cvLine(img, pt1_l_mouth, pt2_l_mouth, color, 4, line_type, 0);
//右边的嘴角的线段
cvLine(img, pt1_r_mouth, pt2_r_mouth, color, 4, line_type, 0);
//嘴巴的圆弧
cvEllipse(img, center, axes_mouth, angle_mouth, start_angle_mouth,
end_angle_mouth, color, 4, line_type, 0);
/**********************绘制文本***********************/
CvFont font;//字体结构
CvScalar font_color = CV_RGB(255, 157, 96);//字体颜色
char text[] = "@_@ smile:-)";//显示的字符串
CvPoint position = cvPoint(40, 80);//字符串显示的位置
//字体结构初始化
cvInitFont(&font,
CV_FONT_HERSHEY_SIMPLEX,//正常大小无衬线字体
2.f,//字体高度
2.f,//字体宽度
0.0,//字体倾斜度 0.0表示不倾斜,1表示倾斜约45度
CV_AA);
//在图像中绘制文本字符串
cvPutText(img,
text,//要绘制的文本字符串
position,//文字显示的位置字符左下角的坐标
&font,//字体
font_color);//文字的颜色
cvShowImage("image", img);
cvWaitKey(0);
cvReleaseImage(&img); }
数据交互:提取并显示图像轮廓
#include
#include
#include #include
void main()
{
int i = 0;
int mode = CV_RETR_CCOMP;//提取轮廓的模式
int contours_num = 0;//图像中提取的轮廓的数目
CvScalar external_color;//绘制轮廓线的颜色
CvScalar hole_color;
CvMemStorage *storage = cvCreateMemStorage(0);
//提取轮廓时需要的存储容器
CvSeq *contour = 0;//存储提取轮廓的序列指针
IplImage *pImg = NULL;
IplImage *pContourImg = NULL;//显示提取的轮廓图像
IplImage *src = cvLoadImage("11.bmp", -1);
pImg = cvCreateImage(cvGetSize(src), src->depth, 1);
pContourImg = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 3);
cvCvtColor(src, pImg, CV_BGR2GRAY);//将读取的图像转为灰度图
cvNamedWindow("src", 1);
cvNamedWindow("contour", 1);
cvShowImage("src", src);//显示原图
//转为二值图(cvFindContours需要)
cvThreshold(pImg, pImg, 180, 255, CV_THRESH_BINARY);
/****************cvFindContours查找物体轮廓*******************/
mode = CV_RETR_LIST;
contours_num = cvFindContours(pImg, storage,
&contour, sizeof(CvContour), mode, CV_CHAIN_APPROX_NONE);
cout << contours_num << " " << endl;//找到的轮廓数目
/******************将轮廓画出*********************************/
for(; contour!=0; contour = contour->h_next)
{
hole_color = CV_RGB(rand()&255, rand()&255, rand()&255);
external_color = CV_RGB(rand()&255, rand()&255, rand()&255);
cvDrawContours(pContourImg, contour,
external_color, hole_color, 1, 2, 8);
}
//显示提取的轮廓的图像
cvShowImage("contour", pContourImg);
cvWaitKey(0);
//释放图像
cvReleaseImage(&src);
cvReleaseImage(&pImg);
cvReleaseImage(&pContourImg);
cvReleaseMemStorage(&storage);
}
8、数据交互:文件存储
#include
#include
void main()
{
CvMat *mat = cvCreateMat(3, 3, CV_32SC1);
cvSetIdentity(mat);//生成单位矩阵
CvMemStorage *memstorage = cvCreateMemStorage(0);
//内存存储器(数据写入时需要)
//文件存储结构
CvFileStorage *fs_write_xml = cvOpenFileStorage("mat_xml.xml",
memstorage, CV_STORAGE_WRITE);
CvFileStorage *fs_write_yml = cvOpenFileStorage("mat_yml.yml",
memstorage, CV_STORAGE_WRITE);
//把mat写入xml文件
cvWriteComment(fs_write_xml, "mat_xml", 1);//注释
cvWrite(fs_write_xml, "CvMat", mat, cvAttrList(NULL, NULL));
//写入数据到xml文件
cvReleaseFileStorage(&fs_write_xml);//释放文件存储器
//把mat写入xml文件
cvWriteComment(fs_write_yml, "mat_yml", 1);//注释
cvWrite(fs_write_yml, "CvMat", mat, cvAttrList(NULL, NULL));
//写入数据到xml文件
cvReleaseFileStorage(&fs_write_yml);//释放文件存储器
//释放内存存储器
cvReleaseMemStorage(&memstorage);
cvReleaseMat(&mat);
}
8、数据交互:写入数据
#include
#include
void main()
{
int a = 1;//待写入的整型数据
float b = 2.;//待写入的浮点型数据
double c[] = {4.5, 6.7, 8.9};//待写入的数组
CvMat *mat = cvCreateMat(3, 3, CV_32SC1);
//待写入的矩阵数据类型
cvSetIdentity(mat);
//打开文件存储器,指定待写入的文件是当前目录下的test.xml文件
CvFileStorage *fs = cvOpenFileStorage("My_Data.xml", 0,
CV_STORAGE_WRITE);
//cvWriteComment写入注释语句
cvWriteComment(fs, "write_data", 1);
//注释最好用英文,中文虽然能写入但是读取的时候会出错
cvStartWriteStruct(fs, "My_Data", CV_NODE_MAP, 0, cvAttrList(0, 0));
//写入数组c,它的标记是"c"
cvStartWriteStruct(fs, "c", CV_NODE_SEQ, 0, cvAttrList(0, 0));
cvWriteRawData(fs, c, 3, "d");
cvEndWriteStruct(fs);
//写入CvMat *mat单位矩阵
cvWrite(fs, "Identity_Mat", mat, cvAttrList(NULL,NULL));
cvStartWriteStruct(fs, "CV_NODE_MAP", CV_NODE_MAP, 0, cvAttrList(0,0));
//写入整型数据a,它的标记是"a"
cvWriteInt(fs, "a", a);
//写入浮点型数据b,它的标记是"b"
cvWriteReal(fs, "b", b);//这个是不能放到startWriteStruct与endWriteStruct
//之间的,再次写入数组c,
cvStartWriteStruct(fs, "c", CV_NODE_SEQ, 0, cvAttrList(0,0));
cvWriteRawData(fs, c, 3, "d");
cvEndWriteStruct(fs);
cvEndWriteStruct(fs);
cvEndWriteStruct(fs);
cvReleaseFileStorage(&fs);
//释放文件存储器,不能缺少,否则数据写入不完整
cvReleaseMat(&mat);
}