一、基本的存儲類型
Mat:矩陣類,用來存儲圖像。
Mat(size, type);
//type類型:前兩位表示數據類型,C表示通道數
CV_8UC1
...
CV_32FC2
CV_32FC3
...
Vec:一個主要用於存儲數值向量的模板類。我們可以定義向量的類型和組件的數量:
typedef Vec<uchar, 2> Vec2b;
typedef Vec<uchar, 3> Vec3b;
...
typedef Vec<short, 2> Vec2s;
...
typedef Vec<float, 2> Vec2f;
...
typedef Vec<double, 3> Vec3d;
支持的操作:
v1 = v2 + v3, v1 = v2 - v3, v1 = v2 * scale, v1 = scale * v2, v1 = -v2, v1 += v2, (v1 == v2), (v1 != v2), norm(v1)
Scalar:Vec的派生模板類,有四個元素。Scalar類型在OpenCV中廣泛用於傳遞和讀取像素值。要訪問Vec和Scalar值,可以使用[]運算符。
Scalar s0(0);
Scalar color(0, 255, 0);
Point:該類定義一個由其座標x和y指定的2D點。
typedef Point_<int> Point2i;
typedef Point2i Point;
typedef Point_<float> Point2f;
typedef Point_<double> Point2d;
支持操作:pt1 = pt2 + pt3, pt1 = pt2 - pt3, pt1 = pt2 * a, pt1 = pt2 / a, pt1 += pt2, pt1 -= pt2, pt1 *= a, pt1 /= a, norm(pt), pt1 == pt2
Size:用於指定圖像或者矩形大小的模板類,有兩個成員變量 width 和 height,以及函數 area() 。
Size s(100, 100);
Mat img = Mat::zeros(s, CV_8UC1); //8U:unchar, C1:channel 1
s.width = 200;
int area = s.area(); // 20000
Rect(矩形):用於使用:1、坐上叫座標 2、矩形的寬度與高度 定義2D矩形;Rect可用於定義ROI。
Mat img = imread("test.jpg");
Rect rect_roi(0,0,100,100);
Mat img_roi = img(rect_roi);
RotateRect(旋轉矩形):該類表示一個旋轉矩形,該矩形由,中心點、矩形的寬度、高度以及以單位爲度的旋轉角度指定。
二、特殊矩陣的矩陣與運算
Mat m1 = Mat::eye(5, 5, CV_32F); //對角陣
Mat m2 = Mat::ones(5, 5, CV_32F); //由全是1組成的 5x5 矩陣
Mat m3 = Mat::zeros(5, 5, CV_32F); //由全是0組成的 5x5 矩陣
int a = 3;
a * m1; //標量*矩陣
m1 + a; //矩陣中得元素分別 +a
m1 * m2; //矩陣乘法
m1.mul(m2); //矩陣與矩陣對應元素相乘
三、基本的數據存儲
1、FileStorage
OpenCV要把一些數據寫入文件,可以使用FileStorage類,同時要是用流運算符操作STL流:
FileStorage fs("test.yml", FileStorage::WRITE);
int fps;
fs << "fps" << fps; //保存數據
Mat m1 = Mat::eye(2, 3, CV_32F);
Mat m2 = Mat::ones(3, 2, CV_32F);
Mat m3 = (m1+1)*(m2+1);
fs << "Result" << m3; //保存數據
fs.release();
FileSotrage fs2("test.yml", FileStorage::READ);
Mat r;
fs2["Result"] >> r; //讀取數據
cout << r << endl;
2、讀/寫圖像
Mat img = imread(path, IMREAD_GRAYSCALE);
imwrite(path, img);
imshow("window name", img);
3、讀取視頻或攝像頭 videoio
VideoCapture cap;
cap.open(filepath); // 讀取視頻文件
cap.open(index); //讀取攝像頭 如果有一個攝像頭則 輸入 0;
cap.isOpend(); //判斷是否成功讀取了數據
cap.release();
while(true){
Mat frame;
cap >> frame; //獲取視頻每一幀的圖像
imshow("video", frame);
if (waitKey(40) >= 0) break;
}
我們訪問攝像頭等待下一幀所需的時間要根據攝像頭的速度和我們花費的算法時間來計算,既當攝像頭將一幀數據寫入緩存後我們才應該去讀取,否則將無法獲取到數據或者取得的數據不完整。如果攝像頭的幀率是 20fps(50秒寫入1幀數據),我們的算法耗費10毫秒(讀取數據並將圖像顯示出來)。則我們顯示每一幀圖像的延遲等待時間至少爲 50 - 10 = 40毫秒。
四、常用操作函數
圖形界面模塊:highgui
#include "opencv2/highgui.hpp"
namedWindow("Test", WINDOW_NORMAL); //創建窗口
moveWindow("Test", 10, 10); //移動窗口
resizeWindow("Test", 512, 512); //調整窗口大小
destoryWindow("Test"); //刪除窗口
destoryAllWindows(); //刪除全部窗口
滑塊和鼠標事件:
int blurAmount = 15;
static void onChange(int pos, void *userInput) {
if (pos <= 0) return;
Mat imgBlur;
Mat *imgTmp = (Mat *)userInput;
blur(*imgTmp, imgBlur, Size(pos, pos));
imshow("Image", imgBlur);
}
static void onMouse(int event, int x, int y, int, void* userInput) {
if (event != EVENT_LBUTTONDOWN) {
return;
}
Mat* img = static_cast<Mat *>(userInput);
circle(*img, Point(x, y), 10, Scalar(0, 255, 0), 3);
onChange(blurAmount, img);
}
string path("D:/Project/C++_learning/OpenCVsolution/image/image_girl.jpg");
Mat img = imread(path, IMREAD_GRAYSCALE);
createTrackbar("ImageBar", "Image", &blurAmount, 30, onChange, &img); //創建滑塊
setMouseCallback("Image", onMouse, &img); //創建鼠標事件
createButton("Gray", grayCallback, NULL, QT_CHECKBOX, 0); //創建按鈕(需要QT)
五、常用濾波器(濾波器與圖像的運算就是卷積)
卷積運算過程
sobel濾波器:通常用於邊緣檢測。
Sobel(src, dst, CV_32F, 0, 2, 3);
其他邊緣檢測常用核:
均值濾波器(均值濾波器):用於圖像平滑處理。去噪
blur(src, dst, Size(pos, pos));
中值濾波器:使用卷積模板的中值來代替像素值,適用於處理椒鹽噪聲。
medianBlur(src, dst, kernel_size);
高斯濾波器:
GaussianBlur( InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT );