opencv3.0版本以上都是用C++实现的. 常用的一些函数及类型集中在cv命名空间里.
cv::Mat类型用于表示一个图像.
构造函数除了空的构造函数外,还有很多个:
Mat(int rows, int cols, int type); //创建指定行,列数的图像对象
Mat(Size size, int type);
type参数用于指定每个像素点的大小,如CV_8UC1.
bool empty() const;//此函数成员用于判断Mat图像数据是否为空.
Mat imread( const String& filename, int flags = IMREAD_COLOR ); //函数用于加载一个图像文件并生成Mat对象
filename参数用于指定图像文件的路径及文件名.
flags加载图像时的处理:
IMREAD_COLOR 转成BGR的图像数据
IMREAD_GRAYSCALE 转成灰度图
void imshow(const String& winname, InputArray mat); //用一个窗口显示Mat图像
winname参数指定窗口名
mat参数指定Mat对象, InputArray类构造函数支持Mat对象
int waitKey(int delay = 0); //暂停执行多久
delay参数指定等待多少毫秒. 0表示一直等到有任意键按下止.
cv::VideoCapture类型用于表示操作摄像头或读视频文件的一个操作对象
此类的构造函数共有两个:
VideoCapture(const String& filename, int apiPreference = CAP_ANY); //可用于指定要读取的视频文件
VideoCapture(int index, int apiPreference = CAP_ANY); //可用于指定要打开第几个摄像头
apiPreference参数用于指定打开方式处理: CAP_ANY表示自动尝试。即如打开视频文件失败,会尝试打开摄像头
CAP_V4L2表示指定使用Linux-V4L2接口打开摄像头
CAP_DSHOW 在windows上使用
CAP_FFMPEG 表示通过调用ffmpeg库来打开视频文件
bool isOpened() const; //函数成员用于判断是否成功打开.
bool read(OutputArray image) ; //此函数成员用于从VideoCapture对象读出一个图像数据. OutputArray类构造函数可支持Mat对象.
cv::VideoWriter类型用于保存视频文件的操作.
构造函数:
VideoWriter(const String& filename, int fourcc, double fps,
Size frameSize, bool isColor = true);
filename指定输出的视频文件名
fourcc指定视频编码格式. VideoWriter::fourcc('H','2','6','4')
fps参数指定多少帧图像每秒
frameSize参数指定图像的分辨率.
isColor指定要编码的图像是彩色图还是灰度图.
void write(InputArray image); //此函数成员用于往视频文件写入一帧图像.
/
从摄像头获取图像数据显示并录制的例程:
#include <opencv4/opencv2/opencv.hpp>
#include <opencv4/opencv2/highgui.hpp>
#include <opencv4/opencv2/videoio.hpp>
using namespace cv;
int main(void)
{
VideoCapture *cap = new VideoCapture(0, CAP_V4L2);
if (!cap->isOpened())
return 3;
Mat m;
cap->read(m);
// mpeg mjpg
VideoWriter *wt = new VideoWriter("/my.avi", VideoWriter::fourcc('H','2','6','4'), 10,
m.size());
for (int i = 0; i < 100; i++)
{
cap->read(m);
wt->write(m);
imshow("pic", m);
waitKey(100);
}
delete wt;
delete cap;
return 0;
}
在图像上增加文字的函数:
void cv::putText( InputOutputArray img, const String& text, Point org,
int fontFace, double fontScale, Scalar color,
int thickness = 1, int lineType = LINE_8,
bool bottomLeftOrigin = false );
img参数指定图像对象,可用Mat对象
text指定要增加的文字内容.
org参数指定从图像的像素坐标开始画出字. 如从100,100坐标开始: Point pos(100, 100);
fontFace参数指定字体的大小及字体, 可用的有:
enum HersheyFonts {
FONT_HERSHEY_SIMPLEX = 0, //!< normal size sans-serif font
FONT_HERSHEY_PLAIN = 1, //!< small size sans-serif font
FONT_HERSHEY_DUPLEX = 2, //!< normal size sans-serif font (more complex than FONT_HERSHEY_SIMPLEX)
FONT_HERSHEY_COMPLEX = 3, //!< normal size serif font
FONT_HERSHEY_TRIPLEX = 4, //!< normal size serif font (more complex than FONT_HERSHEY_COMPLEX)
FONT_HERSHEY_COMPLEX_SMALL = 5, //!< smaller version of FONT_HERSHEY_COMPLEX
FONT_HERSHEY_SCRIPT_SIMPLEX = 6, //!< hand-writing style font
FONT_HERSHEY_SCRIPT_COMPLEX = 7, //!< more complex variant of FONT_HERSHEY_SCRIPT_SIMPLEX
FONT_ITALIC = 16 //!< flag for italic font
};
fontScale参数指定字体的放大倍数.
color参数指定字体的颜色. 如指定蓝色: Scalar s(255, 0, 0) //BGR;
thickness参数指定线条的粗细度.值越大则越粗.
lineType参数指定线条风格,可选择的有:
enum LineTypes {
FILLED = -1,
LINE_4 = 4, //!< 4-connected line
LINE_8 = 8, //!< 8-connected line
LINE_AA = 16 //!< antialiased line
};
bottomLeftOrigin参数, false指定正常画出字,true表示字体是倒着的.
///
在上面例程上加上时间标签:
#include <opencv4/opencv2/opencv.hpp>
#include <opencv4/opencv2/highgui.hpp>
#include <opencv4/opencv2/videoio.hpp>
#include <time.h>
using namespace cv;
int main(void)
{
VideoCapture *cap = new VideoCapture(0, CAP_V4L2);
if (!cap->isOpened())
return 3;
Mat m;
cap->read(m);
// mpeg mjpg
VideoWriter *wt = new VideoWriter("/my.avi", VideoWriter::fourcc('H','2','6','4'), 10,
m.size());
Point pos(100, 100);
Scalar s(255, 0, 0);
char str[20];
struct tm *tm;
time_t now;
for (int i = 0; i < 100; i++)
{
cap->read(m);
now = time(nullptr);
tm = localtime(&now);
sprintf(str, "%d-%02d-%02d %02d:%02d:%02d", tm->tm_year+1900,
tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
putText(m, str, pos, FONT_HERSHEY_DUPLEX, 1.0, s, 1);
wt->write(m);
imshow("pic", m);
waitKey(100);
}
delete wt;
delete cap;
return 0;
}
两Mat图像比较的方法步骤:
1. 把Mat图像转换成灰度图
cvtColor(srcMat, dstMat, BGRA2GRAY);
2. 高斯滤波处理灰度图
GaussianBlur(srcMat, dstMat, new Size(21, 21), 0);
//new Size(21, 21)指定高斯核大小,值越大则图像越模糊
//0指定sigmaX – X方向上的高斯核标准偏差
3. 比较已按上面步骤处理的两个Mat图像
dstMat = Absdiff(srcMat1, srcMat2);
4. 把两个Mat图像比较生成的灰度图转换成黑白图
dstMat = Threshold(srcMat,80, 255, THRESH_BINARY);
//指定每个像素的灰度值是在80~255范围则转换成白色,其它值范围的像素则转成黑色
5. 统计黑白图里白色的像素个数
int ret = CountNonZero(Mat);
//结果数值越大则表示两个图像的差异就越大