在实验室里听一点记一点,到时候再总结整理吧。先记下来再说。
一定要记住的page:http://wiki.opencv.org.cn/index.php/%E9%A6%96%E9%A1%B5
#include <highgui.h>
int main()
{
IplImage * test=NULL;
test = cvLoadImage ("D:\\demo.jpg");
cvNamedWindow("test_demo",1);
cvMoveWindow("test_demo",800,10);
cvShowImage("test_demo",test);
cvWaitKey(0);
cvDestroyWindow("test_demo");
cvReleaseImage(&test);
return 0;
}
已知函数:
1.IplImage *p=NULL;定义图像指针
IplImage是一个类,它包含以下结构:
typedef struct _IplImage
{
int nSize; /* IplImage大小,=sizeof(IplImage)*/
int ID; /* 版本 (=0)*/
int nChannels; /* 大多数OPENCV函数支持1,2,3 或 4 个通道 */
int alphaChannel; /* 被OpenCV忽略 */
int depth; /* 像素的位深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,
IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F 可支持 */
char colorModel[4]; /* 被OpenCV忽略 */
char channelSeq[4]; /* 被OpenCV忽略 */
int dataOrder; /* 0 - 交叉存取颜色通道,对三通道RGB图像,像素存储顺序为BGR BGR BGR ... BGR;
1 - 分开的颜色通道,对三通道RGB图像,像素存储顺序为RRR...R GGG...G BBB...B。
cvCreateImage只能创建交叉存取图像 */
int origin; /* 0 - 顶—左结构,
1 - 底—左结构 (Windows bitmaps 风格) */
int align; /* 图像行排列 (4 or 8). OpenCV 忽略它,使用 widthStep 代替 */
int width; /* 图像宽像素数 */
int height; /* 图像高像素数*/
struct _IplROI *roi;/* 图像感兴趣区域. 当该值非空只对该区域进行处理 */
struct _IplImage *maskROI; /* 在 OpenCV中必须置NULL */
void *imageId; /* 同上*/
struct _IplTileInfo *tileInfo; /*同上*/
int imageSize; /* 图像数据大小(在交叉存取格式下imageSize=image->height*image->widthStep),单位字节*/
char *imageData; /* 指向排列的图像数据 */
int widthStep; /* 排列的图像行大小,以字节为单位 */
int BorderMode[4]; /* 边际结束模式, 被OpenCV忽略 */
int BorderConst[4]; /* 同上 */
char *imageDataOrigin; /* 指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的 */
}
IplImage;
每定义一个IplImage指针,就定义了一个矩形,矩形的每一行依次为nsize,ID……等等。如图:
2.cvLoadImage()
cvLoadImage( filename, -1 ); 默认读取图像的原通道数,filename为图像路径
cvLoadImage( filename, 0 ); 强制转化读取图像为灰度图
cvLoadImage( filename, 1 ); 读取彩色图
3.cvNameWindow("Image",1);命名图像空间
int cvNamedWindow( const char* name, int flags=CV_WINDOW_AUTOSIZE );
函数cvNamedWindow创建一个可以放置图像的窗口.
被创建的窗口可以通过它们的名字被引用.
如果已经存在这个名字的窗口,这个函数将不做任何事情.
若为0表示以固定尺寸显示,此时可以用cvResizeWindow控制窗口大小,这时图像根据窗口大小进行调整,且全铺在窗口上。可以用鼠标拉伸。
若为1,窗口以图像大小进行调整(即使先前设置过窗口大小),也会根据图像大小进行调整,且不可拉伸。
***使用了这个函数后,即使没有图像指针,在编译完成后也会生成一个窗口(灰色)。
关于cvResizeWindow(需要注意,这个函数是用来改变窗口大小的,而非改变图像大小。之所以看似图像大小也改变了,实际上是因为在NamedWindow参数里,设置为图像根据窗口进行调整。换句话说,它的原理是通过改变窗口大小——让图像跟着窗口变化——进而改变图像大小,而非直接改变图像大小。)
void cvResizeWindow( const char* name, int width, int height );
-
name
- 将被设置窗口的名字。 width
- 新的窗口宽度。 height
- 新的窗口高度。
函数cvResizeWindow改变窗口的大小。
如果想要直接改变图像大小,需要resize函数或者图像金字塔pyrDown,pyrUp(不改变长宽比,一次面积放大4倍或者缩小4分之一)
以下为转载:
*************************************
OpenCV改变图像大小的操作有两类:resize与图像金字塔,但是这两类操作差别还是比较大的。
一、resize
函数原型
void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR )
各个参数的意义比较直观,但是需要注意的是dsize与fx和fy必须不能同时为零,也就是说要么dsize不为零而fx与fy同时可以为0,要么dsize为0而fx与fy不同时为0;resize函数的目标大小可以是任意的大小,可以不保持长宽比率,删除的像素或者新增的像素值通过interpolation(内插)控制;
二、图像金字塔
pyrDown与pyrUp分别表示向下降采样与向上升采样,但是二者并不是互为逆操作;
void pyrDown(InputArray src, OutputArray dst, const Size& dstsize=Size(), int border-
Type=BORDER_DEFAULT )
void pyrUp(InputArray src, OutputArray dst, const Size& dstsize=Size(), int border-
Type=BORDER_DEFAULT )
这两个操作实现图像金字塔的经典操作,他们仅仅是分别代表一次采样操作,也就是说,向下(或者向上)进行相邻层次的金字塔采样,调用一次pyrDown函数只能降低到原图像尺寸的1/2;反之,调用pyrUp目标图像则为原图像尺寸的2倍。因为它们内部都给定了一次采样尺寸的约束。也就是说采样之后,长宽比基本是不变的。
void ResizeDemo()
{
Mat img1=imread("person_org.jpg");
Mat img2;
//将原图像变为32*32,长宽比被改变了
resize(img1,img2,Size(32,32),0,0,CV_INTER_LINEAR);
namedWindow("WindowOrg");
namedWindow("WindowNew");
imshow("WindowOrg",img1);
imshow("WindowNew",img2);
waitKey(10000);
}
#include <stdafx.h>
#include <highgui.h>
#include <cv.h>
int main()
{
IplImage *Image;
IplImage *NewImage;
Image = cvLoadImage("D:\\1234.jpg",1);
CvSize sz;
sz = cvGetSize(Image);
sz.height /= 2;
sz.width /= 2;
//if pyrup,
//sz.height*=2;
//sz.width*=2;
//setting height and width.
NewImage = cvCreateImage(sz,IPL_DEPTH_8U, 3);
//Create Image
cvPyrDown(Image, NewImage, 7);
//cvPryup(Image,NewImage,7);
//若使用这个函数,需要事先建立好一个尺寸为原图一半的图并用IplImage指针指向它.7相当于CV_GAUSSIAN_5x5.
cvNamedWindow("graph1", 1);
cvNamedWindow("graph2", 1);
cvShowImage("graph1", Image);
cvShowImage("graph2", NewImage);
cvWaitKey(0);
cvDestroyAllWindows();
return 0;
}
总结:resize可以一次性将原图像变为任意不为0的尺寸,适合用来做归一化图像操作;而pyrDown与pyrUp适合做长宽比率不变得操作,且调用一次只能长和宽只能变为原来的1/2或者2倍,也即是说面积变为原来的1/4或者4倍。
转载自http://blog.sina.com.cn/s/blog_4b0020f30101cgok.html
**********************************************
4.void cvShowImage( const char* name, const CvArr* image );
Example:
cvShowImage("Image",p);
函数cvShowImage 在指定窗口中显示图像.如果窗口创建的时候被设定标志CV_WINDOW_AUTOSIZE,
那么图像将以原始尺寸显示;否则,图像将被伸缩以适合窗口大小.
一条语句只显示一次图像,若后面的语句没有cvWaitKey(0)的话,图像一闪而过。
5.cvWaitKey(delay)
Example:
cvWaitKey(0);
函数的功能是不断刷新图像,频率时间为delay,单位为ms。
delay为<=0时,无限制等待按键。按键后(在显示出的图片里进行按键),才执行WaitKey之后的语句。另外注意WaitKey单位为毫秒!它的功能可以理解为延时X毫秒后,执行接下来的语句。
函数cvWaitKey无限制的等待按键事件(delay<=0时);或者延迟"delay"毫秒。返回值为被按键的值,如果超过指定时间则返回-1。
6.void cvDestroyWindow( const char* name );
Example;
cvDestroyWindow("Image");
销毁指定窗口
7.cvReleaseImage(&p);//销毁指针
cvReleaseImage函数只是将IplImage*型的变量值赋为NULL,而这个变量本身还是存在的并且在内存中的存储位置不变
8.void cvMoveWindow( const char* name, int x, int y );
设定窗口的位置。
name 将被设置的窗口的名字。
x 窗口左上角的x坐标。
y 窗口左上角的y坐标。
函数cvMoveWindow改变窗口的位置。
cvActionTargetMod()
Example:
cv Get 2D
cv Create Image
cv Name Window
CV_bitdepth()
S=符号整型
U=无符号整型
F=浮点型
CV_8(位数)U(类型)G(矩阵)1(通道) 一个8位无符号整形单通道矩阵
CV_32FG2 32位浮点型双通道矩阵
图像数据类型:
IPL_DEPTH_<bit_depth>(S|U|F)
IPL_DEPTH_8U 8位无符号整型
头文件:
<cv.h>
<cvaux.h>
<highgui.h>
<ml.h>
<cxcore.h>
基础结构:
- 1 CvPoint
- 2 CvPoint2D32f
- 3 CvPoint3D32f
- 4 CvSize
- 5 CvSize2D32f
- 6 CvRect
- 7 CvScalar
- 8 CvTermCriteria
- 9 CvMat
- 10 CvMatND
- 11 CvSparseMat
- 12 IplImage
- 13 CvArr
其中,CvPoint为二维坐标点整型,2D32F为2维浮点型,以此类推。
CyScalar是一个颜色结构体类,有四个数组元素,分别代表R,G,B,第四个元素通常用来表示透明色.
typedef struct CvScalar
{
double val[4]
}
CvScalar;
扩展——
其中Cvpoint
inline CvPoint cvPoint( int x, int y );
inline CvPoint cvPointFrom32f( CvPoint2D32f point )
分别作用为:返回一个cvPoint值,
将一个2D32f值转换为cvPoint值并返回。
函数原型:
void cvLine( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8, int shift=0 );
-
img 图像。
-
pt1 线段的第一个端点。
-
pt2 线段的第二个端点。
-
color 线段的颜色。
-
thickness 线段的粗细程度。
-
line_type 线段的类型。8 (or 0) - 8-connected line(8邻接)连接 线。4 - 4-connected line(4邻接)连接线。CV_AA - antialiased 线条。
// qwsds.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "highgui.h"
#include "stdio.h"
int main()
{
CvPoint pt1;
pt1=cvPoint(100,200);
printf("x:%d,y:%d\n",pt1.x,pt1.y);
CvPoint pt2;
pt2=cvPoint(200,320);
printf("x:%d,y:%d\n",pt2.x,pt2.y);
CvScalar color;
color=cvScalar(100,0,200);//蓝 绿 红。RGB
printf("v1:%f v2:%f v3:%f\n",color.val[0],color.val[1],color.val[2]);
IplImage *img=0;
img=cvLoadImage("D:\\Blue hills.jpg");
cvLine(img,pt1,pt2,color,2);
cvNamedWindow("draw");
cvShowImage("draw",img);
cvWaitKey();
return 0;
}
</pre><pre code_snippet_id="421021" snippet_file_name="blog_20140707_14_8402014" name="code" class="cpp"><strong><span style="color:#ff0000;">CvLine</span></strong>
void cvLine( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color,
int thickness=1, int line_type=8, int shift=0 );
-
img
- 图像。 pt1
- 线段的第一个端点。 pt2
- 线段的第二个端点。 color
- 线段的颜色。 thickness
- 线段的粗细程度。 line_type
-
线段的类型。
- 8 (or 0) - 8-connected line(8邻接)连接 线。
- 4 - 4-connected line(4邻接)连接线。
- CV_AA - antialiased 线条。
-
shift
- 坐标点的小数点位数。
函数cvLine 在图像中的点1和点2之间画一条线段。线段被图像或感兴趣的矩形(ROI rectangle)所裁剪。对于具有整数坐标的non-antialiasing 线条,使用8-连接或者4-连接Bresenham 算法。画粗线条时结尾是圆形的。画 antialiased 线条使用高斯滤波。要指定线段颜色,用户可以使用使用宏CV_RGB( r, g, b )。
CvSize sz;
sz=cvSize(640,480);
printf("width:%d,height:%d\n",sz.width,sz.height);
将这个矩形作为Image显示出来:
IplImage *p;
p=cvCreateImage(sz,IPL_DEPTH_8U,3);//sz矩形的宽,高(将结构体传进去),深度,颜色通道数)
cvNamedWindow("Image");
cvShowImage("Image",p);
cvWaitKey(0);
其中cvCreateImage创建了一个矩形!
typedef struct CvRect
{
int x; /* 方形的最左角的x-坐标 */
int y; /* 方形的最上或者最下角的y-坐标 */
int width; /* 宽 */
int height; /* 高 */
}
CvRect;
应用:(利用了CvRectangle)
void cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color,
int thickness=1, int line_type=8, int shift=0 );
-
img
- 图像. pt1
- 矩形的一个顶点。 pt2
- 矩形对角线上的另一个顶点 color
- 线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)。 thickness
- 组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形。 line_type
- 线条的类型。见cvLine的描述 shift
- 坐标点的小数点位数。
函数 cvRectangle 通过对角线上的两个顶点绘制矩形。
#include "highgui.h"
#include "stdio.h"
int main(int argc, char* argv[])
{
CvSize sz;//CvSize 数据类型 C大写,定义。
sz=cvSize(640,480);//给sz赋值。
printf("width:%d,height:%d\n",sz.width,sz.height);
IplImage *img=0;
img=cvCreateImage(sz,IPL_DEPTH_8U,3);//创建而不是载入。
CvRect rect;
rect=cvRect(50,30,100,150);//左上坐标,长度,宽度。
CvPoint pt1=cvPoint(rect.x,rect.y);
CvPoint pt2=cvPoint(rect.x+rect.width,rect.y+rect.height);
cvRectangle(img,pt1,pt2,cvScalar(0,0,255),2);
cvNamedWindow("create");
cvShowImage("create",img);
cvWaitKey();
return 0;
}
只有在创建了一个矩形(或者指针已经指向了一张图才可以用cvRectangle函数在图里画矩形(画线也一样))。
IplImage *mp1=cvCloneImage(img);//把图像img复制给mp1.
</pre></div><div class="para" style="margin:15px 0px 5px; text-indent:2em; line-height:24px; font-family:arial,宋体,sans-serif; font-size:14px"><pre code_snippet_id="421021" snippet_file_name="blog_20140707_20_810661" name="code" class="cpp" style="color: rgb(51, 51, 51);"> cvNamedWindow("create");
cvShowImage("create",img);//img需要事先指向图像
IplImage *p2=cvCloneImage(img);
cvNamedWindow("clone");
cvShowImage("clone",p2);
cvWaitKey();
保存图像到文件
int cvSaveImage( const char* filename, const CvArr* image );
-
filename
- 文件名,如果对应的文件已经存在,则将被复盖。 image
- 要保存的图像。
函数cvSaveImage保存图像到指定文件。图像格式的的选择依赖于filename的扩展名,请参考cvLoadImage。只有8位单通道或者3通道(通道顺序为'BGR' )可以使用这个函数保存。如果格式,深度或者通道不符合要求,请先用cvCvtScale 和cvCvtColor转换;或者使用通用的cvSave保存图像为XML或者YAML格式。
#include <highgui.h>
int main()
{
IplImage * test=NULL;
test = cvLoadImage ("D:\\demo.jpg");
cvNamedWindow("test_demo",1);
cvMoveWindow("test_demo",800,10);
cvShowImage("test_demo",test);
cvSaveImage("D:\\123.jpg",test);
cvWaitKey(0);
cvDestroyWindow("test_demo");
cvReleaseImage(&test);
return 0;
}
其中cvSaveImage在指定目录建立一个新文件(图像)。
OpenCV里有两个单词,Image,Window,它们各自代表的是载入的图像(用IplImage指针表示),放置图像的窗口。
1.在存在Window的前提下,即cvNamedWindow("窗口名",是否根据Image进行调整的指标.),
2.让IplImage指针指向Image,即cvLoadImage("Image",指针名).除去载入的方法外,也可以创建:
(1).定义一个CvSize类型的矩形sz.
(2).赋予其宽,高.sz=CvSize(640,480)
(3).p=cvCreateImage(sz,IPL_DEPTH_8U,3).第二个参数为深度,例为8位无符号整型,3通道.
3.再将Image导入Window,才能让Image显示出来,即cvShowImage(Window,image的指针).
1.FILE *fopen(char *filename, *type)
如果要打开一个CCDOS子目录中, 文件名为CLIB的二进制文件, 可写成:
fopen("c:\\ccdos\\clib", "rb");
如果成功的打开一个文件, fopen()函数返回文件指针,否则返回空指针(NULL)。由此可判断文件打开是否成功。
表 文件操作类型
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
字符 含义
────────────────────────────
"r" 打开文字文件只读
"w" 创建文字文件只写
"a" 增补, 如果文件不存在则创建一个
"r+" 打开一个文字文件读/写
"w+" 创建一个文字文件读/写
"a+" 打开或创建一个文件增补
"b" 二进制文件(可以和上面每一项合用)
"t" 文这文件(默认项)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
fopen()函数中第一个形式参数表示文件名, 可以包含路径和文件名两部分。 如: "B:TEST.DAT"
"C:\\TC\\TEST.DAT"
如果将路径写成"C:\TC\TEST.DAT"是不正确的, 这一点要特别注意。
2. fclose()函数
fclose()函数用来关闭一个由fopen()函数打开的文件 , 其调用格式为:
int fclose(FILE *stream);
#iclude<stdio.h>
main()
{
FILE *fp; /*定义一个文件指针*/
int i;
fp=fopen("CLIB", "rb"); /*打开当前目录名为CLIB的文件只读*/
if(fp==NULL) /*判断文件是否打开成功*/
puts("File open error");/*提示打开不成功*/
i=fclose(fp); /*关闭打开的文件*/
if(i==0) /*判断文件是否关闭成功*/
printf("O.K"); /*提示关闭成功*/
else
puts("File close error");/*提示关闭不成功*/
}
3.文件的顺序写函数
fprintf()、fputs()和fputc()函数均为文件的顺序写操作函数,其调用格式如下:
int fputs(char *string, FILE *steam);
int fputc(intch, FILE *steam);
fprintf() 函数的返回值为实际写入文件中的字符个数(字节数)。如果写错误, 则返回一个负数; fputs()函数返回0时表明将string指针所指的字符串写入文件中的操作成功, 返回非0时,表明写操作失败。 fputc()函数返回一个向文件所写字符的值, 此时写操作成功,否则返回EOF(文件结束结束其值为-1, 在stdio.h中定义)表示写操作错误。 fprintf( ) 函数中格式化的规定与printf( ) 函数相同,所不同的只是fprintf()函数是向文件中写入。而printf()是向屏幕输出。
4.文件的顺序读操作函数
fscanf()、fgets()和fgetc()函数
函数fscanf()、fgets()和fgetc()均为文件的顺序读操作函数, 其调用格式 如下:
char fgets(char *string, int n, FILE *steam);
int fgetc(FILE *steam);
fscanf()函数的用法与scanf()函数相似,只是它是从文件中读到信息。 fscanf()函数的返回值为EOF(即-1), 表明读错误, 否则读数据成功。 fgets()函数从文件中读取至多n-1个字符(n用来指定字符数), 并把它们放入string指向的字符串中, 在读入之后自动向字符串未尾加一个空字符, 读成功返回string指针, 失败返回一个空指针。 fgetc()函数返回文件当前位置的一个字符,读错误时返回EOF。