学习OpenCV时做的笔记

本文介绍使用OpenCV进行图像处理的方法,包括文件操作、基本数据结构的声明与初始化、图像信息获取、ROI区域操作、矩阵与数组的基本操作等。通过示例代码详细讲解了如何实现图像的加载、显示、保存、矩阵运算、图像变换等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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<highgui.h>
#include<cv.h>

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<highgui.h>
#include<cv.h>
#include<iostream.h>

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<highgui.h>
#include<cv.h>
#include<iostream.h>

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<highgui.h>
#include<cv.h>
#include<iostream.h>

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<highgui.h>
#include<cv.h>
#include<iostream.h>

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<highgui.h>
#include<cv.h>
#include<iostream.h>
#include<iomanip.h>

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<highgui.h>
#include<cv.h>
#include<iostream.h>

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<highgui.h>
#include<cv.h>
#include<iostream.h>

void main()
{
 int i;
 int num_nonzero = 0;//数组中非零元素个数
 double sum = 0;//数组中全部元素的和
 CvScalar mean;//数组所有元素的平均值
 CvScalar std_dev;//数组所有元素的标准差
 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<cv.h>
#include<cxcore.h>
#include<highgui.h>
#include<iostream.h>

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<Count; i++)
 {
  CV_READ_SEQ_ELEM(pt1, reader);
  cvCircle(pContourImg, pt1, 1, color);
  cvShowImage("contour", pContourImg);
  cvWaitKey(5);
 }
 cvWaitKey(0);
 //释放
 cvReleaseImage(&bin_img);
 cvReleaseImage(&pContourImg);
 cvReleaseMemStorage(&storage);
}

 

8、数据交互:基本绘图操作:

#include<highgui.h>
#include<cv.h>
#include<iostream.h>

#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<cv.h>
#include<cxcore.h>
#include<highgui.h>
#include<iostream.h>

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<cxcore.h>
#include<iostream.h>

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<cxcore.h>
#include<iostream.h>

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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值