第一件事:OpenCV數(shù)據(jù)結(jié)構(gòu)
1. 基礎(chǔ)圖像容器 Mat 詳解
內(nèi)存:
(1)不必再手動(dòng)為其開(kāi)辟空間
(2)不必再不需要時(shí)立即釋放空間
(3)OpenCV 中使用了引用計(jì)數(shù)機(jī)制,每個(gè) Mat 類型都有自己的信息頭臼婆,但共享同一個(gè)矩陣抒痒。所以拷貝構(gòu)造函數(shù)則只復(fù)制信息頭和矩陣指針。
(4)盡量不進(jìn)行大圖像的矩陣復(fù)制颁褂,會(huì)極大地降低程序運(yùn)行速度故响。
(5)當(dāng)傳遞一個(gè)已經(jīng)存在的 Mat 對(duì)象時(shí),開(kāi)辟好的矩陣會(huì)被重用颁独。組成:
有兩個(gè)部分組成:矩陣頭(包含矩陣尺寸彩届、存儲(chǔ)方法、存儲(chǔ)地址等信息)和指向矩陣的指針誓酒。像素值的存儲(chǔ):
存儲(chǔ)像素值需要指定元素空間和數(shù)據(jù)類型樟蠕。顏色空間:表示存儲(chǔ)一個(gè)指定顏色所需要的顏色元素組合。最簡(jiǎn)單的顏色空間是灰度空間丰捷,在灰度空間中只需要處理黑色原色和白色元素即可坯墨。最常用的是 RGB顏色空間,這主要是因?yàn)?RGB 顏色空間與人眼內(nèi)部構(gòu)成顏色的方式一致病往。
顏色空間還有很多:HSV 和 HLS捣染、YCrCb、CIE Lab*等等停巷。每個(gè)基本元素都有其自己的定義域耍攘,定義域取決于其數(shù)據(jù)類型(也就是之前所說(shuō)的顏色深度),例如:char 類型(8 位)畔勤、float 類型(32 位)或 double 類型(64 位)等等蕾各。
創(chuàng)建Mat對(duì)象的幾種方法:
直接使用 Mat() 構(gòu)造函數(shù)
原型:
Mat(int rows, int cols, int type, const Scalar& s);
示例:
//類型格式:CV_[位數(shù)][帶符號(hào)與否][類型前綴]C[通道數(shù)]
//CV_8UC3,8位3通道
Mat M(2,2, CV_8UC3, Scalar(0,0,255));
- 在 C\C++ 中通過(guò)構(gòu)造函數(shù)進(jìn)行初始化
int sz[3] = {2,2,2};
//參數(shù):1.唯獨(dú)庆揪,2.每個(gè)維度的尺寸式曲,3.同上方法 4.顏色表示Scalar類(下面有介紹)
Mat L(3,sz,CV_8UC,Scalar::all(0));
- 為已存在的 IplImage 創(chuàng)建信息頭
IplImage* img = cvLoadImage("1.jpg", 1);
Mat mtx(img) ;
- 利用 Create() 函數(shù)
cvCreateMat(int rows, int cols, int type);
- 采用 Matlab 式的初始化方式
cv::Mat::eye(int rows, int cols, int type)
- 對(duì)小矩陣采用逗號(hào)分隔式初始化函數(shù)
Mat C = (Mat_<double> (3,3) << 1, -1, 2, -5, 5, 3, 1, 3, 1);
- 為已經(jīng)存在的對(duì)象創(chuàng)建新的信息頭
Mat RowClone = C.row(1).clone();
2. 顏色空間轉(zhuǎn)換:cvtColor 函數(shù)
cvtColor 函數(shù)可以實(shí)現(xiàn) RGB 顏色空間向 HSV、HSI 等顏色空間的轉(zhuǎn)換×咝撸可以在 imgproc.hpp 頭文件中找到兰伤,函數(shù)原型如下:
void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0);
- 第一個(gè)參數(shù):輸入圖像;
- 第二個(gè)參數(shù):輸出圖像钧排;
- 第三個(gè)參數(shù):顏色空間轉(zhuǎn)換標(biāo)識(shí)符敦腔,在 imgproc.hpp 頭文件的 519 行可以找到枚舉定義;
- 第四個(gè)參數(shù):目標(biāo)圖像通道數(shù)恨溜。
顏色空間轉(zhuǎn)換標(biāo)識(shí)符枚舉定義
/** the color conversion code
@see @ref imgproc_color_conversions
@ingroup imgproc_misc
*/
enum ColorConversionCodes {
COLOR_BGR2BGRA = 0, //!< add alpha channel to RGB or BGR image
COLOR_RGB2RGBA = COLOR_BGR2BGRA,
COLOR_BGRA2BGR = 1, //!< remove alpha channel from RGB or BGR image
COLOR_RGBA2RGB = COLOR_BGRA2BGR,
COLOR_BGR2RGBA = 2, //!< convert between RGB and BGR color spaces (with or without alpha channel)
COLOR_RGB2BGRA = COLOR_BGR2RGBA,
COLOR_RGBA2BGR = 3,
COLOR_BGRA2RGB = COLOR_RGBA2BGR,
COLOR_BGR2RGB = 4,
COLOR_RGB2BGR = COLOR_BGR2RGB,
COLOR_BGRA2RGBA = 5,
COLOR_RGBA2BGRA = COLOR_BGRA2RGBA,
COLOR_BGR2GRAY = 6, //!< convert between RGB/BGR and grayscale, @ref color_convert_rgb_gray "color conversions"
COLOR_RGB2GRAY = 7,
COLOR_GRAY2BGR = 8,
COLOR_GRAY2RGB = COLOR_GRAY2BGR,
COLOR_GRAY2BGRA = 9,
COLOR_GRAY2RGBA = COLOR_GRAY2BGRA,
COLOR_BGRA2GRAY = 10,
COLOR_RGBA2GRAY = 11,
COLOR_BGR2BGR565 = 12, //!< convert between RGB/BGR and BGR565 (16-bit images)
COLOR_RGB2BGR565 = 13,
COLOR_BGR5652BGR = 14,
COLOR_BGR5652RGB = 15,
COLOR_BGRA2BGR565 = 16,
COLOR_RGBA2BGR565 = 17,
COLOR_BGR5652BGRA = 18,
COLOR_BGR5652RGBA = 19,
COLOR_GRAY2BGR565 = 20, //!< convert between grayscale to BGR565 (16-bit images)
COLOR_BGR5652GRAY = 21,
COLOR_BGR2BGR555 = 22, //!< convert between RGB/BGR and BGR555 (16-bit images)
COLOR_RGB2BGR555 = 23,
COLOR_BGR5552BGR = 24,
COLOR_BGR5552RGB = 25,
COLOR_BGRA2BGR555 = 26,
COLOR_RGBA2BGR555 = 27,
COLOR_BGR5552BGRA = 28,
COLOR_BGR5552RGBA = 29,
COLOR_GRAY2BGR555 = 30, //!< convert between grayscale and BGR555 (16-bit images)
COLOR_BGR5552GRAY = 31,
COLOR_BGR2XYZ = 32, //!< convert RGB/BGR to CIE XYZ, @ref color_convert_rgb_xyz "color conversions"
COLOR_RGB2XYZ = 33,
COLOR_XYZ2BGR = 34,
COLOR_XYZ2RGB = 35,
COLOR_BGR2YCrCb = 36, //!< convert RGB/BGR to luma-chroma (aka YCC), @ref color_convert_rgb_ycrcb "color conversions"
COLOR_RGB2YCrCb = 37,
COLOR_YCrCb2BGR = 38,
COLOR_YCrCb2RGB = 39,
COLOR_BGR2HSV = 40, //!< convert RGB/BGR to HSV (hue saturation value), @ref color_convert_rgb_hsv "color conversions"
COLOR_RGB2HSV = 41,
COLOR_BGR2Lab = 44, //!< convert RGB/BGR to CIE Lab, @ref color_convert_rgb_lab "color conversions"
COLOR_RGB2Lab = 45,
COLOR_BGR2Luv = 50, //!< convert RGB/BGR to CIE Luv, @ref color_convert_rgb_luv "color conversions"
COLOR_RGB2Luv = 51,
COLOR_BGR2HLS = 52, //!< convert RGB/BGR to HLS (hue lightness saturation), @ref color_convert_rgb_hls "color conversions"
COLOR_RGB2HLS = 53,
COLOR_HSV2BGR = 54, //!< backward conversions to RGB/BGR
COLOR_HSV2RGB = 55,
COLOR_Lab2BGR = 56,
COLOR_Lab2RGB = 57,
COLOR_Luv2BGR = 58,
COLOR_Luv2RGB = 59,
COLOR_HLS2BGR = 60,
COLOR_HLS2RGB = 61,
COLOR_BGR2HSV_FULL = 66, //!<
COLOR_RGB2HSV_FULL = 67,
COLOR_BGR2HLS_FULL = 68,
COLOR_RGB2HLS_FULL = 69,
COLOR_HSV2BGR_FULL = 70,
COLOR_HSV2RGB_FULL = 71,
COLOR_HLS2BGR_FULL = 72,
COLOR_HLS2RGB_FULL = 73,
COLOR_LBGR2Lab = 74,
COLOR_LRGB2Lab = 75,
COLOR_LBGR2Luv = 76,
COLOR_LRGB2Luv = 77,
COLOR_Lab2LBGR = 78,
COLOR_Lab2LRGB = 79,
COLOR_Luv2LBGR = 80,
COLOR_Luv2LRGB = 81,
COLOR_BGR2YUV = 82, //!< convert between RGB/BGR and YUV
COLOR_RGB2YUV = 83,
COLOR_YUV2BGR = 84,
COLOR_YUV2RGB = 85,
//! YUV 4:2:0 family to RGB
COLOR_YUV2RGB_NV12 = 90,
COLOR_YUV2BGR_NV12 = 91,
COLOR_YUV2RGB_NV21 = 92,
COLOR_YUV2BGR_NV21 = 93,
COLOR_YUV420sp2RGB = COLOR_YUV2RGB_NV21,
COLOR_YUV420sp2BGR = COLOR_YUV2BGR_NV21,
COLOR_YUV2RGBA_NV12 = 94,
COLOR_YUV2BGRA_NV12 = 95,
COLOR_YUV2RGBA_NV21 = 96,
COLOR_YUV2BGRA_NV21 = 97,
COLOR_YUV420sp2RGBA = COLOR_YUV2RGBA_NV21,
COLOR_YUV420sp2BGRA = COLOR_YUV2BGRA_NV21,
COLOR_YUV2RGB_YV12 = 98,
COLOR_YUV2BGR_YV12 = 99,
COLOR_YUV2RGB_IYUV = 100,
COLOR_YUV2BGR_IYUV = 101,
COLOR_YUV2RGB_I420 = COLOR_YUV2RGB_IYUV,
COLOR_YUV2BGR_I420 = COLOR_YUV2BGR_IYUV,
COLOR_YUV420p2RGB = COLOR_YUV2RGB_YV12,
COLOR_YUV420p2BGR = COLOR_YUV2BGR_YV12,
COLOR_YUV2RGBA_YV12 = 102,
COLOR_YUV2BGRA_YV12 = 103,
COLOR_YUV2RGBA_IYUV = 104,
COLOR_YUV2BGRA_IYUV = 105,
COLOR_YUV2RGBA_I420 = COLOR_YUV2RGBA_IYUV,
COLOR_YUV2BGRA_I420 = COLOR_YUV2BGRA_IYUV,
COLOR_YUV420p2RGBA = COLOR_YUV2RGBA_YV12,
COLOR_YUV420p2BGRA = COLOR_YUV2BGRA_YV12,
COLOR_YUV2GRAY_420 = 106,
COLOR_YUV2GRAY_NV21 = COLOR_YUV2GRAY_420,
COLOR_YUV2GRAY_NV12 = COLOR_YUV2GRAY_420,
COLOR_YUV2GRAY_YV12 = COLOR_YUV2GRAY_420,
COLOR_YUV2GRAY_IYUV = COLOR_YUV2GRAY_420,
COLOR_YUV2GRAY_I420 = COLOR_YUV2GRAY_420,
COLOR_YUV420sp2GRAY = COLOR_YUV2GRAY_420,
COLOR_YUV420p2GRAY = COLOR_YUV2GRAY_420,
//! YUV 4:2:2 family to RGB
COLOR_YUV2RGB_UYVY = 107,
COLOR_YUV2BGR_UYVY = 108,
//COLOR_YUV2RGB_VYUY = 109,
//COLOR_YUV2BGR_VYUY = 110,
COLOR_YUV2RGB_Y422 = COLOR_YUV2RGB_UYVY,
COLOR_YUV2BGR_Y422 = COLOR_YUV2BGR_UYVY,
COLOR_YUV2RGB_UYNV = COLOR_YUV2RGB_UYVY,
COLOR_YUV2BGR_UYNV = COLOR_YUV2BGR_UYVY,
COLOR_YUV2RGBA_UYVY = 111,
COLOR_YUV2BGRA_UYVY = 112,
//COLOR_YUV2RGBA_VYUY = 113,
//COLOR_YUV2BGRA_VYUY = 114,
COLOR_YUV2RGBA_Y422 = COLOR_YUV2RGBA_UYVY,
COLOR_YUV2BGRA_Y422 = COLOR_YUV2BGRA_UYVY,
COLOR_YUV2RGBA_UYNV = COLOR_YUV2RGBA_UYVY,
COLOR_YUV2BGRA_UYNV = COLOR_YUV2BGRA_UYVY,
COLOR_YUV2RGB_YUY2 = 115,
COLOR_YUV2BGR_YUY2 = 116,
COLOR_YUV2RGB_YVYU = 117,
COLOR_YUV2BGR_YVYU = 118,
COLOR_YUV2RGB_YUYV = COLOR_YUV2RGB_YUY2,
COLOR_YUV2BGR_YUYV = COLOR_YUV2BGR_YUY2,
COLOR_YUV2RGB_YUNV = COLOR_YUV2RGB_YUY2,
COLOR_YUV2BGR_YUNV = COLOR_YUV2BGR_YUY2,
COLOR_YUV2RGBA_YUY2 = 119,
COLOR_YUV2BGRA_YUY2 = 120,
COLOR_YUV2RGBA_YVYU = 121,
COLOR_YUV2BGRA_YVYU = 122,
COLOR_YUV2RGBA_YUYV = COLOR_YUV2RGBA_YUY2,
COLOR_YUV2BGRA_YUYV = COLOR_YUV2BGRA_YUY2,
COLOR_YUV2RGBA_YUNV = COLOR_YUV2RGBA_YUY2,
COLOR_YUV2BGRA_YUNV = COLOR_YUV2BGRA_YUY2,
COLOR_YUV2GRAY_UYVY = 123,
COLOR_YUV2GRAY_YUY2 = 124,
//CV_YUV2GRAY_VYUY = CV_YUV2GRAY_UYVY,
COLOR_YUV2GRAY_Y422 = COLOR_YUV2GRAY_UYVY,
COLOR_YUV2GRAY_UYNV = COLOR_YUV2GRAY_UYVY,
COLOR_YUV2GRAY_YVYU = COLOR_YUV2GRAY_YUY2,
COLOR_YUV2GRAY_YUYV = COLOR_YUV2GRAY_YUY2,
COLOR_YUV2GRAY_YUNV = COLOR_YUV2GRAY_YUY2,
//! alpha premultiplication
COLOR_RGBA2mRGBA = 125,
COLOR_mRGBA2RGBA = 126,
//! RGB to YUV 4:2:0 family
COLOR_RGB2YUV_I420 = 127,
COLOR_BGR2YUV_I420 = 128,
COLOR_RGB2YUV_IYUV = COLOR_RGB2YUV_I420,
COLOR_BGR2YUV_IYUV = COLOR_BGR2YUV_I420,
COLOR_RGBA2YUV_I420 = 129,
COLOR_BGRA2YUV_I420 = 130,
COLOR_RGBA2YUV_IYUV = COLOR_RGBA2YUV_I420,
COLOR_BGRA2YUV_IYUV = COLOR_BGRA2YUV_I420,
COLOR_RGB2YUV_YV12 = 131,
COLOR_BGR2YUV_YV12 = 132,
COLOR_RGBA2YUV_YV12 = 133,
COLOR_BGRA2YUV_YV12 = 134,
//! Demosaicing
COLOR_BayerBG2BGR = 46,
COLOR_BayerGB2BGR = 47,
COLOR_BayerRG2BGR = 48,
COLOR_BayerGR2BGR = 49,
COLOR_BayerBG2RGB = COLOR_BayerRG2BGR,
COLOR_BayerGB2RGB = COLOR_BayerGR2BGR,
COLOR_BayerRG2RGB = COLOR_BayerBG2BGR,
COLOR_BayerGR2RGB = COLOR_BayerGB2BGR,
COLOR_BayerBG2GRAY = 86,
COLOR_BayerGB2GRAY = 87,
COLOR_BayerRG2GRAY = 88,
COLOR_BayerGR2GRAY = 89,
//! Demosaicing using Variable Number of Gradients
COLOR_BayerBG2BGR_VNG = 62,
COLOR_BayerGB2BGR_VNG = 63,
COLOR_BayerRG2BGR_VNG = 64,
COLOR_BayerGR2BGR_VNG = 65,
COLOR_BayerBG2RGB_VNG = COLOR_BayerRG2BGR_VNG,
COLOR_BayerGB2RGB_VNG = COLOR_BayerGR2BGR_VNG,
COLOR_BayerRG2RGB_VNG = COLOR_BayerBG2BGR_VNG,
COLOR_BayerGR2RGB_VNG = COLOR_BayerGB2BGR_VNG,
//! Edge-Aware Demosaicing
COLOR_BayerBG2BGR_EA = 135,
COLOR_BayerGB2BGR_EA = 136,
COLOR_BayerRG2BGR_EA = 137,
COLOR_BayerGR2BGR_EA = 138,
COLOR_BayerBG2RGB_EA = COLOR_BayerRG2BGR_EA,
COLOR_BayerGB2RGB_EA = COLOR_BayerGR2BGR_EA,
COLOR_BayerRG2RGB_EA = COLOR_BayerBG2BGR_EA,
COLOR_BayerGR2RGB_EA = COLOR_BayerGB2BGR_EA,
COLOR_COLORCVT_MAX = 139
};
對(duì)源碼中顏色空間宏的整理:
顏色空間 | 對(duì)應(yīng)宏 |
---|---|
RGB | RGB |
RGBA | RGBA符衔,A代表Alpha通道 |
BGR | BGR |
BGRA | BGRA,A代表Alpha通道 |
5x5 | BGR565糟袁、BGR555,每個(gè)數(shù)字代表每個(gè)顏色通道占幾BPP (位/像素) |
GRAY | GRAY |
CIE XYZ | XYZ |
luma-chroma (YCC) | YCrCb |
HSV (hue saturation value) | HSV |
CIE Lab | Lab |
CIE Luv | Luv |
HLS (hue lightness saturation) | HLS |
YUV | YUV |
Bayer | Bayer |
3. 點(diǎn)的表示:Point 類
Point 類數(shù)據(jù)結(jié)構(gòu)表示了二位坐標(biāo)系下的點(diǎn)判族。
types.hpp 文件中的定義:
template<typename _Tp> class Point_
{
public:
typedef _Tp value_type;
// various constructors
Point_();
Point_(_Tp _x, _Tp _y);
Point_(const Point_& pt);
Point_(const Size_<_Tp>& sz);
Point_(const Vec<_Tp, 2>& v);
Point_& operator = (const Point_& pt);
//! conversion to another data type
template<typename _Tp2> operator Point_<_Tp2>() const;
//! conversion to the old-style C structures
operator Vec<_Tp, 2>() const;
//! dot product
_Tp dot(const Point_& pt) const;
//! dot product computed in double-precision arithmetics
double ddot(const Point_& pt) const;
//! cross-product
double cross(const Point_& pt) const;
//! checks whether the point is inside the specified rectangle
bool inside(const Rect_<_Tp>& r) const;
_Tp x, y; //< the point coordinates
};
typedef Point_<int> Point2i;
typedef Point_<int64> Point2l;
typedef Point_<float> Point2f;
typedef Point_<double> Point2d;
typedef Point2i Point;
發(fā)現(xiàn)常用的 Point 是 Point_ 模板類的 int 類型 Point_<int>。
創(chuàng)建:
Point point;
point.x = 100;
point.y = 200;
或者
Point point = Point(100,200);
方便的運(yùn)算符重載的使用:
pt1 = pt2 + pt3;
pt1 = pt2 - pt3;
pt1 = pt2 * a;
pt1 = a * pt2;
pt1 = pt2 / a;
pt1 += pt2;
pt1 -= pt2;
pt1 *= a;
pt1 /= a;
pt1 == pt2;
pt1 != pt2;
4. 顏色表示:Scalar 類
在 types.hpp 中的定義:
typedef Scalar_<double> Scalar;
template<typename _Tp> class DataType< Scalar_<_Tp> >
{
public:
typedef Scalar_<_Tp> value_type;
typedef Scalar_<typename DataType<_Tp>::work_type> work_type;
typedef _Tp channel_type;
enum { generic_type = 0,
depth = DataType<channel_type>::depth,
channels = 4,
fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
type = CV_MAKETYPE(depth, channels)
};
typedef Vec<channel_type, channels> vec_type;
};
發(fā)現(xiàn)常用的 Scalar 是 Scalar_ 模板類的 double 類型 Scalar_<double>系吭,Scalar 包括四個(gè)顏色元素五嫂。如果用不到第四個(gè)元素可以不用寫出來(lái)。
Scalar( a, b, c );
5. 尺寸表示:Size 類
在 types.hpp 頭文件中的定義:
template<typename _Tp> class Size_
{
public:
typedef _Tp value_type;
//! various constructors
Size_();
Size_(_Tp _width, _Tp _height);
Size_(const Size_& sz);
Size_(const Point_<_Tp>& pt);
Size_& operator = (const Size_& sz);
//! the area (width*height)
_Tp area() const;
//! conversion of another data type.
template<typename _Tp2> operator Size_<_Tp2>() const;
_Tp width, height; // the width and the height
};
typedef Size_<int> Size2i;
typedef Size_<int64> Size2l;
typedef Size_<float> Size2f;
typedef Size_<double> Size2d;
typedef Size2i Size;
發(fā)現(xiàn)常用的 Size 是 Size_ 模板類的 int 類型 Size_<int>肯尺,
Size 類主要是描述寬和高的沃缘。構(gòu)造方法如下:
Size(5, 5);
6. 矩形表示:Rect 類
在 types.hpp 頭文件中的定義:
template<typename _Tp> class Rect_
{
public:
typedef _Tp value_type;
//! various constructors
Rect_();
Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
Rect_(const Rect_& r);
Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz);
Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2);
Rect_& operator = ( const Rect_& r );
//! the top-left corner
Point_<_Tp> tl() const;
//! the bottom-right corner
Point_<_Tp> br() const;
//! size (width, height) of the rectangle
Size_<_Tp> size() const;
//! area (width*height) of the rectangle
_Tp area() const;
//! conversion to another data type
template<typename _Tp2> operator Rect_<_Tp2>() const;
//! checks whether the rectangle contains the point
bool contains(const Point_<_Tp>& pt) const;
_Tp x, y, width, height; //< the top-left corner, as well as width and height of the rectangle
};
typedef Rect_<int> Rect2i;
typedef Rect_<float> Rect2f;
typedef Rect_<double> Rect2d;
typedef Rect2i Rect;
發(fā)現(xiàn)常用的 Rect 是 Rect_ 模板類的 int 類型 Size_<int>,
Rect 類的成員變量有 x则吟、y槐臀、width、height氓仲,分別為左上角點(diǎn)的坐標(biāo)和矩形的寬和高水慨,可以看做 point 和 size 的組合。
Rect常用運(yùn)算:
兩個(gè)矩形的交集敬扛、并集
Rect rect = rect1 & rect2;//交集
Rect rect = rect1 | rect2;//并集
矩陣平移晰洒、縮放
Rect rectShift = rect + point;//平移
Rect rectScale = rect + size;//縮放