本节主要介绍OpenCV的core模块基础部分:
1. Mat类的用法,及OpenCV中其他常用的数据类型
2. 基本绘图操作
本章节开始介绍OpenCV的core模块http://docs.opencv.org/3.1.0/d0/de1/group__core.html ,重点讲了些Basic structures中的一小部分内容http://docs.opencv.org/3.1.0/dc/d84/group__core__basic.html。可以多看看,例如cv::Algorithm, cv::Point以后都很有用。
mat数据内存中的存储方式,一张PPT解释。关于其读写,下面会给出一个例程。
常用构造函数:
个人比较喜欢的用法:
Mat A(1000, 800, CV_8UC3,Scalar(0, 0, 255));
Mat F=A.clone();
Mat G;
A.copyTo(G);
Mat imageROI;//创建一个感兴趣区域(ROI),只需要创建包含边界信息的信息头
imageROI = A(Rect(800, 350, 100, 100));
Mat imageROI(A, Rect(800, 350, 100, 100));
Mat E=Mat::zeros(100, 100, CV_8UC1);
M.create(4, 4, CV_8UC2);
Mat类深拷贝、浅拷贝。例如:clone()和copyTo()为深拷贝,而“=”和copy()即为浅拷贝(只创建信息头)
OpenCV 中还有一些其他常见的数据类:Point, Scalar, Size, Rect。书中讲的都很好。本P100页“其他常用的知识点”,很实用。
源码:
#include
#include
#include
using namespace cv;
using namespace std;
int main()
{
Mat I = Mat::eye(4, 4, CV_64F);
I.at<double>(1, 1) = CV_PI;
cout << "\nI = " << I << ";\n" << endl;
Mat r = Mat(10, 3, CV_8UC3);
randu(r, Scalar::all(0), Scalar::all(255));
cout << "r (OpenCV默认风格) = " << r << ";" << endl << endl;
cout << "r (Python风格) = " << format(r, Formatter::FMT_PYTHON) << ";" << endl << endl;
cout << "r (Numpy风格) = " << format(r, Formatter::FMT_NUMPY) << ";" << endl << endl;
cout << "r (逗号分隔风格) = " << format(r, Formatter::FMT_CSV) << ";" << endl << endl;
cout << "r (C语言风格) = " << format(r, Formatter::FMT_C) << ";" << endl << endl;
Point2f p(6, 2);
cout << " 【2维点】p = " << p << ";" << endl;
Point3f p3f(8, 2, 0);
cout << " 【3维点】p3f = " << p3f << ";" << endl;
vector<float> v;
v.push_back(3); v.push_back(5); v.push_back(7);
cout << "【基于Mat的vector】shortvec = " << Mat(v) << ";" << endl;
vector points(20);
for (size_t i = 0; i < points.size(); i++)
points[i] = Point2f((float)(i*5), (float)(i%7));
cout << "【二维点向量】points = " << points << ";";
waitKey(0);
return 0;
}
素材:
无
效果图:
无
提示:
无
源码:
#include
using namespace cv;
int writeGrayimByAt(Mat m);
int writeGrayimByIt(Mat m);
int writeColorimByAt(Mat m);
int writeColorimByIt(Mat m);
int main()
{
Mat grayim(128, 160, CV_8UC1, Scalar(0, 0, 255));
writeGrayimByAt(grayim);
writeGrayimByIt(grayim);
Mat colorim(128, 160, CV_8UC3, Scalar(0, 0, 255));
writeColorimByAt(colorim);
writeColorimByIt(colorim);
return 0;
}
int writeGrayimByAt(Mat m) {
for (int i = 0; i < m.rows; i++)
for (int j = 0; j < m.cols; j++)
m.at(i, j) = i;
return 0;
}
int writeGrayimByIt(Mat m) {
MatIterator_ grayit, grayend;
int i = 0;
for (grayit = m.begin(), grayend = m.end(); grayit != grayend; ++grayit, ++i)
*grayit = i / m.cols;
return 0;
}
int writeColorimByAt(Mat m) {
for (int i = 0; i < m.rows; i++)
for (int j = 0; j < m.cols; j++) {
Vec3b pixel;
pixel[0] = i;
pixel[1] = j;
pixel[2] = 255;
m.at(i, j) = pixel;
}
return 0;
}
int writeColorimByIt(Mat m) {
MatIterator_ colorit, colorend;
int i = 0;
for (colorit = m.begin(), colorend = m.end(); colorit != colorend; ++colorit, ++i) {
(*colorit)[0] = i / m.cols;
(*colorit)[1] = i % m.cols;
(*colorit)[2] = 255;
}
return 0;
}
素材:
无
效果图:
无
提示:
无
源码:
#include
#include
using namespace cv;
using namespace std;
#define WINDOW_NAME1 "【原子示例图】"
#define WINDOW_NAME2 "【组合图】"
#define WINDOW_WIDTH 600 //定义窗口大小的宏
vector rookPoints = { Point(1 * WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8),
Point(3 * WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8),
Point(3 * WINDOW_WIDTH / 4, 13 * WINDOW_WIDTH / 16),
Point(11 * WINDOW_WIDTH / 16, 13 * WINDOW_WIDTH / 16),
Point(19 * WINDOW_WIDTH / 32, 3 * WINDOW_WIDTH / 8),
Point(3 * WINDOW_WIDTH / 4, 3 * WINDOW_WIDTH / 8),
Point(3 * WINDOW_WIDTH / 4, 1 * WINDOW_WIDTH / 8),
Point(26 * WINDOW_WIDTH / 40, 1 * WINDOW_WIDTH / 8),
Point(26 * WINDOW_WIDTH / 40, 1 * WINDOW_WIDTH / 4),
Point(22 * WINDOW_WIDTH / 40, 1 * WINDOW_WIDTH / 4),
Point(22 * WINDOW_WIDTH / 40, 1 * WINDOW_WIDTH / 8),
Point(18 * WINDOW_WIDTH / 40, 1 * WINDOW_WIDTH / 8),
Point(18 * WINDOW_WIDTH / 40, 1 * WINDOW_WIDTH / 4),
Point(14 * WINDOW_WIDTH / 40, 1 * WINDOW_WIDTH / 4),
Point(14 * WINDOW_WIDTH / 40, 1 * WINDOW_WIDTH / 8),
Point(1 * WINDOW_WIDTH / 4, 1 * WINDOW_WIDTH / 8),
Point(1 * WINDOW_WIDTH / 4, 3 * WINDOW_WIDTH / 8),
Point(13 * WINDOW_WIDTH / 32, 3 * WINDOW_WIDTH / 8),
Point(5 * WINDOW_WIDTH / 16, 13 * WINDOW_WIDTH / 16),
Point(1 * WINDOW_WIDTH / 4, 13 * WINDOW_WIDTH / 16), };
int main() {
Mat atomImage = Mat::zeros(WINDOW_WIDTH, WINDOW_WIDTH, CV_8UC3);
Mat rookImage = Mat::zeros(WINDOW_WIDTH, WINDOW_WIDTH, CV_8UC3);
ellipse(atomImage,Point(WINDOW_WIDTH/2, WINDOW_WIDTH/2), Size(WINDOW_WIDTH/4, WINDOW_WIDTH/16), 90, 0, 360, Scalar(255, 129, 0), 2);
ellipse(atomImage, Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2), Size(WINDOW_WIDTH / 4, WINDOW_WIDTH / 16), 0, 0, 360, Scalar(255, 129, 0), 2);
ellipse(atomImage, Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2), Size(WINDOW_WIDTH / 4, WINDOW_WIDTH / 16), 45, 0, 360, Scalar(255, 129, 0), 2);
ellipse(atomImage, Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2), Size(WINDOW_WIDTH / 4, WINDOW_WIDTH / 16), -45, 0, 360, Scalar(255, 129, 0), 2);
circle(atomImage, Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2), WINDOW_WIDTH / 32, Scalar(0, 0, 255), -1);
vector<vector > rp = { rookPoints }; //注意,必须将其再加一层vector
fillPoly(rookImage, rp, Scalar(255, 255, 255));
rectangle(rookImage, Point(0, 7*WINDOW_WIDTH/8), Point(WINDOW_WIDTH, WINDOW_WIDTH), Scalar(0, 255, 255), -1);
line(rookImage, Point(0, 15*WINDOW_WIDTH/16), Point(WINDOW_WIDTH, 15*WINDOW_WIDTH/16), Scalar(0, 0, 0), 2);
line(rookImage, Point(1 * WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8), Point(WINDOW_WIDTH/4, WINDOW_WIDTH), Scalar(0, 0, 0), 2);
line(rookImage, Point(1 * WINDOW_WIDTH / 2, 7 * WINDOW_WIDTH / 8), Point(WINDOW_WIDTH/2, WINDOW_WIDTH), Scalar(0, 0, 0), 2);
line(rookImage, Point(3 * WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8), Point(3*WINDOW_WIDTH/4, WINDOW_WIDTH), Scalar(0, 0, 0), 2);
imshow(WINDOW_NAME1, atomImage);
moveWindow(WINDOW_NAME1, 0, 200);
imshow(WINDOW_NAME2, rookImage);
moveWindow(WINDOW_NAME2, WINDOW_WIDTH, 200);
waitKey(0);
return 0;
}
素材:
无
效果图:
略
提示:
无