IplImage的参数:
Width---------------------int,保存图像的宽度(像素)
Height--------------------int,保存图像的高度(像素)
ImageData--------------指向字符数组的指针,每个字符表示一个实际的像素或颜色值。
nChannels--------------int,表示每个像素的颜色数,即通道
depth---------------------int,表示每个像素的bit数
origin----------------------int,表示坐标原点,0--左上,1左下
widthStep---------------int,表示图像一行所占字节数
imageSize---------------int,表示图像所占总字节数
imageDataOrigin---------指向图像原始数据的指针
roi-------------------------指向定义正在处理图像中的兴趣区的结构体的指针
获取像素点(i,j)的值: p = cvGet2D(img, i, j)
改变像素点(i,j)的值: cvSet(img, i, j, p)
cvLoadImage:从文件中读入一个图像,结构体默认强制为3通道RGB形式。
eg: img = cvLoadImage(filename,f)
返回一个表示IplImage*值,如果文件读取失败返回0;第二个参数表示返回图像类型,f>0,3通道,f=0,1通道,f<0,实际图像类型。
cvSaveImage:将图像写入文件:
eg:k = cvSaveImage(filename, img)
filename----------要保存文件的文件名,若为file.jpg,则文件格式为JPEG
img----------------要写入文件的图像
文件无法写入,就返回0.
opencv的用户界面函数封装在highgui的库中,通过cvNamedWindow函数创建一个窗口,这个函数给窗口指定了一个名称。所有的窗口都是通过窗口名称而不是指针访问的。在创建窗口的时候可以指定autosize属性,也可以不指定。用cvShowImage函数在已有窗口中显示图像。对于制定了autoSize属性的窗口,窗口可以更改大小以适应图像大小,否则图像会缩放以适应窗口的大小,即图像大小随窗口大小而变化。
不论何时调用cvShowImage,通过参数传入的图像都显示在指定窗口中。通过这种方式,可以显示一个图像连续处理的过程,因而可以创建并显示简单的动画。窗口创建之后,可通过cvMoveWindow(name, x, y)移动窗口,或用鼠标移动。
#include <stdio.h>
#include "opencv2\highgui\highgui.hpp"
#include "opencv2\opencv.hpp"
#include <math.h>
#include <iostream>
using namespace std;
int main()
{
IplImage *image = 0;
int i, j, k;
int mean = 0, count = 0;
char c;
image = cvLoadImage("timg.jpg");
if (image)
{
cout << "Height " << image->height << " X with " << image->width << endl;
cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);
cvShowImage("mainwin", image);
cout << "Display of image is done." << endl;
cvWaitKey(0);
for (i = 0; i < image->height; i++)
for (j = 0; j < image->width; j++)
{
k = ((image->imageData + i*image->widthStep)[j*image->nChannels + 0]
+ (image->imageData + i*image->widthStep)[j*image->nChannels + 1]
+ (image->imageData + i*image->widthStep)[j*image->nChannels + 2]) / 3;
for (int m = 0; m < 3; m++)
{
(image->imageData + i*image->widthStep)[j*image->nChannels + m] = (uchar)k;
}
mean += k;
count++;
}
cvNamedWindow("grey", CV_WINDOW_AUTOSIZE);
cvShowImage("grey", image);
cvWaitKey(0);
mean /= count;
for (int i = 0; i < image->height; i++)
for (int j = 0; j < image->width; j++)
{
k = (image->imageData + i*image->widthStep)[j*image->nChannels + 0];
if (k < mean)
k = 0;
else
{
k = 255;
}
for (int m = 0; m < 3; m++)
(image->imageData + i*image->widthStep)[j*image->nChannels + m] = (uchar)k;
}
cvNamedWindow("thresh");
cvShowImage("thresh", image);
cvSaveImage("thresholded.jpg", image);
cvWaitKey(0);
cvDestroyAllWindows();
}
else
cout << stderr << "Error reading image" << endl;
return 0;
}
我们可以通过代码了解到转化的灰度图像其实依然是3通道。
图像捕捉
在图像捕捉中,opencv首先声明并初始化一个摄像头,然后使用系统创建的句柄,然后可以通过句柄获得图像 。
CvCapture *camera = 0;
camera = CvCaptureFromCAM(CV_CAP_ANY);
if(!camera)...
CvCapture是内部类型,表示捕捉图像的句柄。CvCaptureFromCam函数初始化从摄像头捕捉视频。其中参数CV_CAP_ANY允许使用任何连接到系统的摄像头,但系统会自动选择用哪一个。若返回0,表示没有找到摄像头。
cvQueryFrame函数可以捕捉到一帧(图像):
IplImage *frame = 0;
frame = cvQueryFrame(camera);
当程序完成运行时,最后释放所有分配的资源。
eg:释放摄像头 cvReleaseCapture(&camera);
使用Opencv时需要了解的关键细节就在于是图像数据结构是如何实现的。因此,要把Opencv库和AIPCV连接起来的主要工作就在于提供一种在两种系统之间转换图像数据结构的方法。
AIPCV库中的基本图像数据结构是由两个数据结构组成:1。表示头信息,2,表示图像。图像数据结构的名称为image,由两个指针组成,一个指向头信息,一个指向存储像素数据的数组:
struct image
{
struct header *info;
unsigned char **data;
};
在单通道存储数据中,两个库都是按行寻址的字节。像素数据设置为二维数组检索的方式,因此像素数据为指向行数据的指针的数组。变量data[0]是指向整个数组起始位置的指针,类似IplImage.imageData.
头信息:
struct header
{
int nr,nc;
int oi,oj;
};
nr--------------------图像的行数==height
nc--------------------图像的列数==width
oi,oj------------------指定图像的原点(只在极少数情况下使用,如还原)