1. 矩阵和图像操作
Learning OpenCV中描述的都是OpenCV1.1的特征,已经远远落后于如今的2.4.9版本,这期间OpenCV有了很多新特性,比如说Mat.
矩阵和图像操作这一部分详细的介绍了一些适用于CvMat,图像处理中的基本操作,例如对角化,矩阵变换,以及更复杂的诸如计算图像的统计操作。但是鉴于新的OpenCV中已经有了Mat结构,可以方便的进行内存管理,不用主动释放内存,方便写更大的程序,所以我就不列举书中所介绍的各种CvMat的基本操作,不过推荐阅读OpenCV的Documentation,里面对于基本数据结构以及相应函数的介绍很全面,也推荐阅读这篇文章的介绍。
绘图
下面介绍OpenCV的一些基本绘图函数,详情请参考官方文档
<span style="font-size:14px;">//绘制直线(画布,端点1,端点2,颜色(BGRA),线条粗细,反走样模式
void line(CV_IN_OUT Mat& img, Point pt1, Point pt2,
const Scalar& color,int thickness=1,
int lineType=8, int shift=0);
void rectangle(CV_IN_OUT Mat& img, Point pt1, Point pt2,
const Scalar& color, int thickness=1,
int lineType=8, int shift=0);
void circle(CV_IN_OUT Mat& img, Point center, int radius,
const Scalar& color, int thickness=1,
int lineType=8, int shift=0);
void ellipse(CV_IN_OUT Mat& img, Point center, Size axes,
double angle, double startAngle, double endAngle,
const Scalar& color, int thickness=1,
int lineType=8, int shift=0);
void ellipse(CV_IN_OUT Mat& img, const RotatedRect& box, const Scalar& color,
int thickness=1, int lineType=8);
void fillConvexPoly(Mat& img, const Point* pts, int npts,
const Scalar& color, int lineType=8,
int shift=0);
void fillConvexPoly(InputOutputArray img, InputArray points,
const Scalar& color, int lineType=8,
int shift=0);
void fillPoly(Mat& img, const Point** pts,
const int* npts, int ncontours,
const Scalar& color, int lineType=8, int shift=0,
Point offset=Point() );
void fillPoly(InputOutputArray img, InputArrayOfArrays pts,
const Scalar& color, int lineType=8, int shift=0,
Point offset=Point() );
void polylines(Mat& img, const Point** pts, const int* npts,
int ncontours, bool isClosed, const Scalar& color,
int thickness=1, int lineType=8, int shift=0 );
void polylines(InputOutputArray img, InputArrayOfArrays pts,
bool isClosed, const Scalar& color,
int thickness=1, int lineType=8, int shift=0 );
void putText( Mat& img, const string& text, Point org,
int fontFace, double fontScale, Scalar color,
int thickness=1, int lineType=8,
bool bottomLeftOrigin=false );
Size getTextSize(const string& text, int fontFace,
double fontScale, int thickness,
CV_OUT int* baseLine);
</span>
不妨看一个有趣的官方示例代码
<span style="font-size:14px;">#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdio.h>
using namespace cv;
static void help()
{
printf("\nThis program demonstrates OpenCV drawing and text output functions.\n");
}
static Scalar randomColor(RNG& rng)
{
int icolor = (unsigned)rng;
//随机返回颜色
return Scalar(icolor&255, (icolor>>8)&255, (icolor>>16)&255);
}
int main()
{
help();
char wndname[] = "Drawing Demo";
const int NUMBER = 100;
const int DELAY = 5;
//反走样模式,CV_AA最高,其次还有lineType = 8 或 lineType = 4
int lineType = CV_AA;
int i, width = 1000, height = 700;
int x1 = -width/2, x2 = width*3/2, y1 = -height/2, y2 = height*3/2;
//随机数生成器
RNG rng(0xFFFFFFFF);
Mat image = Mat::zeros(height, width, CV_8UC3);
imshow(wndname, image);
waitKey(DELAY);
for (i = 0; i < NUMBER; i++)
{
Point pt1, pt2;
pt1.x = rng.uniform(x1, x2);
pt1.y = rng.uniform(y1, y2);
pt2.x = rng.uniform(x1, x2);
pt2.y = rng.uniform(y1, y2);
//绘制直线
line( image, pt1, pt2, randomColor(rng), rng.uniform(1,10), lineType );
imshow(wndname, image);
if(waitKey(DELAY) >= 0)
return 0;
}
for (i = 0; i < NUMBER; i++)
{
Point pt1, pt2;
pt1.x = rng.uniform(x1, x2);
pt1.y = rng.uniform(y1, y2);
pt2.x = rng.uniform(x1, x2);
pt2.y = rng.uniform(y1, y2);
int thickness = rng.uniform(-3, 10);
//绘制矩形
rectangle( image, pt1, pt2, randomColor(rng), MAX(thickness, -1), lineType );
imshow(wndname, image);
if(waitKey(DELAY) >= 0)
return 0;
}
for (i = 0; i < NUMBER; i++)
{
Point center;
center.x = rng.uniform(x1, x2);
center.y = rng.uniform(y1, y2);
Size axes;
axes.width = rng.uniform(0, 200);
axes.height = rng.uniform(0, 200);
double angle = rng.uniform(0, 180);
//绘制椭圆
ellipse( image, center, axes, angle, angle - 100, angle + 200,
randomColor(rng), rng.uniform(-1,9), lineType );
imshow(wndname, image);
if(waitKey(DELAY) >= 0)
return 0;
}
for (i = 0; i< NUMBER; i++)
{
Point pt[2][3];
pt[0][0].x = rng.uniform(x1, x2);
pt[0][0].y = rng.uniform(y1, y2);
pt[0][1].x = rng.uniform(x1, x2);
pt[0][1].y = rng.uniform(y1, y2);
pt[0][2].x = rng.uniform(x1, x2);
pt[0][2].y = rng.uniform(y1, y2);
pt[1][0].x = rng.uniform(x1, x2);
pt[1][0].y = rng.uniform(y1, y2);
pt[1][1].x = rng.uniform(x1, x2);
pt[1][1].y = rng.uniform(y1, y2);
pt[1][2].x = rng.uniform(x1, x2);
pt[1][2].y = rng.uniform(y1, y2);
const Point* ppt[2] = {pt[0], pt[1]};
int npt[] = {3, 3};
//绘制多条多边形曲线(这里是两条)
polylines(image, ppt, npt, 2, true, randomColor(rng), rng.uniform(1,10), lineType);
imshow(wndname, image);
if(waitKey(DELAY) >= 0)
return 0;
}
for (i = 0; i< NUMBER; i++)
{
Point pt[2][3];
pt[0][0].x = rng.uniform(x1, x2);
pt[0][0].y = rng.uniform(y1, y2);
pt[0][1].x = rng.uniform(x1, x2);
pt[0][1].y = rng.uniform(y1, y2);
pt[0][2].x = rng.uniform(x1, x2);
pt[0][2].y = rng.uniform(y1, y2);
pt[1][0].x = rng.uniform(x1, x2);
pt[1][0].y = rng.uniform(y1, y2);
pt[1][1].x = rng.uniform(x1, x2);
pt[1][1].y = rng.uniform(y1, y2);
pt[1][2].x = rng.uniform(x1, x2);
pt[1][2].y = rng.uniform(y1, y2);
const Point* ppt[2] = {pt[0], pt[1]};
int npt[] = {3, 3};
//同时绘制多个多边形,这里是两个
fillPoly(image, ppt, npt, 2, randomColor(rng), lineType);
imshow(wndname, image);
if(waitKey(DELAY) >= 0)
return 0;
}
for (i = 0; i < NUMBER; i++)
{
Point center;
center.x = rng.uniform(x1, x2);
center.y = rng.uniform(y1, y2);
//绘制圆
circle(image, center, rng.uniform(0, 300), randomColor(rng),
rng.uniform(-1, 9), lineType);
imshow(wndname, image);
if(waitKey(DELAY) >= 0)
return 0;
}
for (i = 1; i < NUMBER; i++)
{
Point org;
org.x = rng.uniform(x1, x2);
org.y = rng.uniform(y1, y2);
//显示文字
putText(image, "Testing text rendering", org, rng.uniform(0,8),
rng.uniform(0,100)*0.05+0.1, randomColor(rng), rng.uniform(1, 10), lineType);
imshow(wndname, image);
if(waitKey(DELAY) >= 0)
return 0;
}
//获取字符串的尺寸
Size textsize = getTextSize("OpenCV forever!", FONT_HERSHEY_COMPLEX, 3, 5, 0);
Point org((width - textsize.width)/2, (height - textsize.height)/2);
Mat image2;
for( i = 0; i < 255; i += 2 )
{
image2 = image - Scalar::all(i);
putText(image2, "OpenCV forever!", org, FONT_HERSHEY_COMPLEX, 3,
Scalar(i, i, 255), 5, lineType);
imshow(wndname, image2);
if(waitKey(DELAY) >= 0)
return 0;
}
waitKey();
return 0;
}
#ifdef _EiC
main(1,"drawing.c");
#endif
</span>