前言:本系列从入门角度去学习计算机视觉相关知识,再从算法设计角度去解析计算机视觉中的一些基础算法以及技巧
不知不觉就开了计算机视觉的坑 入门虽然没什么难度 但是opencv每个版本更新 都像是两个不同团队写的东西 真实被恶心到了 所以本系列文章都基于opencv3.0&VS2015与其他的版本差异或许在讲解过程中会提到。
需要注意的是:本文默认你有一定的c++/c基础
first:
1.系统变量里面新建变量,名为 【OPENCV】 ,值为解压后opencv文件夹里build文件夹的路径,如 C:\opencv\build
2.系统变量里面编辑【 Path】 变量,在末尾添加 【;%OPENCV%\x86\vc12\bin】
3.去这里下载opencv的配置文件选择【视图】->【其它窗口】->【属性管理器】,然后在【属性管理器】中右键单击项目名,选择【添加现有属性表】,然后将opencv300.props添加进去
第一步首先是认识opencv中的几种存储图像的类型
IplImage
typedef struct _IplImage
{
int nSize; /* 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 和IPL_DEPTH_64F */
char colorModel[4]; /* 被OpenCV忽略 */
char channelSeq[4]; /* 同上 */
int dataOrder; /* 0 - 交叉存取颜色通道, 1 - 分开的颜色通道. 只有cvCreateImage可以创建交叉存取图像 */
int origin; /*图像原点位置: 0表示顶-左结构,1表示底-左结构 */
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;
mat
class CV_EXPORTS Mat
{
public:
//! default constructor
Mat();
//! constructs 2D matrix of the specified size and type
// (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
Mat(int _rows, int _cols, int _type);
Mat(Size _size, int _type);
//! constucts 2D matrix and fills it with the specified value _s.
Mat(int _rows, int _cols, int _type, const Scalar& _s);
Mat(Size _size, int _type, const Scalar& _s);
//! constructs n-dimensional matrix
Mat(int _ndims, const int* _sizes, int _type);
Mat(int _ndims, const int* _sizes, int _type, const Scalar& _s);
//! copy constructor
Mat(const Mat& m);
//! constructor for matrix headers pointing to user-allocated data
Mat(int _rows, int _cols, int _type, void* _data, size_t _step=AUTO_STEP);
Mat(Size _size, int _type, void* _data, size_t _step=AUTO_STEP);
Mat(int _ndims, const int* _sizes, int _type, void* _data, const size_t* _steps=0);
//! creates a matrix header for a part of the bigger matrix
Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all());
Mat(const Mat& m, const Rect& roi);
Mat(const Mat& m, const Range* ranges);
//! converts old-style CvMat to the new matrix; the data is not copied by default
Mat(const CvMat* m, bool copyData=false);
//! converts old-style CvMatND to the new matrix; the data is not copied by default
Mat(const CvMatND* m, bool copyData=false);
//! converts old-style IplImage to the new matrix; the data is not copied by default
Mat(const IplImage* img, bool copyData=false);
......
}
cvmat
typedef struct CvMat
{
int type; //标示元素类型和标记
int step; //以字节为单位的行数据长度
/* for internal use only */
int* refcount;
int hdr_refcount;
union
{
uchar* ptr;
short* s;
int* i;
float* fl;
double* db;
} data; //数据指针
#ifdef __cplusplus
union
{
int rows;
int height;
};
union
{
int cols;
int width;
};
#else
int rows; //行数(用于保存图像数据时可以理解为图像高度)
int cols; //列数(用于保存图像数据时可以理解为图像宽度)
#endif
}
是不是感觉一阵
刚一上来就是这么多的数据结构 但是这些基本不用细看 因为你看了也记不住 我贴上来完全是为了让大家对这些图像类型有一个直观的认识
Mat,cvMat和IplImage,这三种类型都可以代表和显示图像,但是,Mat类型侧重于图形图像的计算,数学性较高,openCV对Mat类型的计算也进行了优化,所以你会看到mat类型和其他两个画风明显不一样。而CvMat和IplImage类型更侧重于“图像”,opencv对其中的图像操作(缩放、单通道提取、图像阈值操作等)进行了优化。
在opencv2.0之前,opencv是完全用C实现的,但是,IplImage类型与CvMat类型的关系类似于面向对象中的继承关系。实际上,CvMat之上还有一个更抽象的基类—-CvArr,这在源代码中会常见。
先来看看如何获取和显示一幅图像
#include "stdafx.h"
#include <opencv\cv.hpp>
#include <opencv\highgui.h>
#include <iostream>//c++流不用说了吧
#include <fstream>//文件
#include <cmath>
//头文件这里需要说明下 不同的 配置可能会有所差异但核心的就是cv.hpp/higui.h(hpp)/
using namespace std;
using namespace cv;
//命名空间最好也包括std
int _tmain(int argc, _TCHAR* argv[])
{
IplImage* img = cvLoadImage("图片名.图片类型", 0);
//定义ipiimage 与调取工程文件夹下的一张图片
//cvload后面的参数为0即加载黑白图像 1则加载彩色图像
cvNamedWindow("显示框名", 1);//这英语该认识吧命名窗口
cvShowImage("显示框名", img);//显示图片
cvWaitKey(-1);
return 0;
}
以下为演示效果
辣么 既然都是存储图像的数据结构 那么肯定是可以互相转换的咯 当然能 我们下节就将讲解 ipiimage/ mat/cvMat 这三种结构怎么互相转化
ok 本节的讲解就到这里 下节将重点更新:
1.转化方法。
2.基础图形处理算法