1. Mat操作
//初始化
Mat A = (Mat_<double>(3, 3) << 1, 2, 3, 0, 1, 4, 5, 6, 0);
Mat E = Mat::eye(3, 4, CV_64F);//单位矩阵
Mat P = Mat::zeros(3, 4, CV_64F);//全0
Mat.at<float>(i, j) = x;
Mat N; 或Mat N = Mat();//这样的声明,输出为“[]”
Mat M(2, 3, CV_32F);//这样的声明,输出为全0
//运算
Mat.inv();//逆
Mat.t();//转置
norm(Mat);//模长
determinant(A);//行列式
//访问
Mat.ptr<float>(i)[j];//i行j列
Mat.row(i).clone();//i行行向量
Mat.col(i).clone();//i列列向量
//操作
MatA.push_back(MatB);//MatA和MatB列数要相等。在MatA的底部加入MatB,MatA的行数增加
Mat.reshape(0, x);//通道数不变,行数变为x
Mat.resize(x);//截取前x行,x大于行数会填0
2. 视频的读取与保存
string video_name = "1.mp4";
VideoCapture cap;
cap.open(video_name);
int w = cap.get(CV_CAP_PROP_FRAME_WIDTH);
int h = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
int count = cap.get(CV_CAP_PROP_FRAME_COUNT);
int fps = cap.get(CV_CAP_PROP_FPS);
VideoWriter wri;
wri.open("res.avi", CV_FOURCC('D', 'I', 'V', 'X'), fps, Size(w, h));
Mat img;
while (true) {
cap >> img;
if (img.empty())
break;
wri << img;
}
cap.release();
wri.release();
3. 访问像素
Mat img = Mat(5, 5, CV_8UC3, Scalar(0, 0, 0));
//分成3个通道,在每个通道上访问像素
vector<Mat> channels;
split(img, channels);
Mat c0 = channels.at(0); //b
Mat c1 = channels.at(1); //g
Mat c2 = channels.at(2); //r
c0 = 50;
c1 = 100;
c2 = 150;
//在三通道图像上访问一个像素的rgb值
Mat res;
merge(channels, res);
for (int i = 0; i < res.rows; i++)
for (int j = 0; j < res.cols; j++) {
res.at<cv::Vec3b>(i, j)[0] = 0;
res.at<cv::Vec3b>(i, j)[1] = 255;
res.at<cv::Vec3b>(i, j)[2] = 0;
}
imwrite("res.jpg", res);
4. 图像切片
把图像img切成 m × n m \times n m×n个小块。
void slice(Mat img, int m, int n) {
int h = img.rows / m, w = img.cols / n;
Mat cell;
int i, j;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++) {
stringstream ss;
ss << "./result/" << i + 1 << j + 1 << ".png";
Rect rect(j * w, i * h, w, h);
img(rect).copyTo(cell);
imwrite(ss.str().c_str(), cell);
waitKey(1);
}
}
5. 直线检测算法LSD
int main(int argc, char** argv) {
if (argc != 3) { std::cout << "./exe 填充图 原图" << std::endl; exit(0); }
Mat image = imread(argv[1], IMREAD_GRAYSCALE);//读入填充图
Mat image2 = imread(argv[2], IMREAD_COLOR);//读入原图
Ptr<LineSegmentDetector> ls = createLineSegmentDetector(LSD_REFINE_STD);//LSD_REFINE_NONE
vector<Vec4f> lines_std;
ls->detect(image, lines_std);//在填充图上检测直线
Mat drawnLines(image2);
ls->drawSegments(drawnLines, lines_std);//在原图上画直线
imwrite("./r.jpg", drawnLines);
}
6. 读取摄像头
int main(int argc, char* argv[]) {
VideoCapture capture(1);//如果是笔记本,0打开的是自带的摄像头,1 打开外接的相机
VideoWriter writer(argv[1], CV_FOURCC('X', 'V', 'I', 'D'), capture.get(CV_CAP_PROP_FPS), cvSize(640, 480));
Mat frame;
while (capture.isOpened()) {
capture >> frame;
writer << frame;
imshow("video", frame);
if (waitKey(1) == 27)//27是键盘摁下esc时,计算机接收到的ascii码值
break;
}
}