OpenCV(一)
OpenCV
官方連結為:https://www.opencv.org/
官方文件連結為:https://docs.opencv.org/
OpenCV下載及安裝
下載:
https://www.opencv.org/releases.html
點選該地址,win下安裝點選下圖方框,不同環境下載不同型別
win下安裝:
win下版本下載完成後直接一個可執行程式(其實是一個自解壓的zip檔案),雙擊後直接選擇安裝的路徑即可
選擇安裝路徑:
OpenCV3.4.1在VS2017中的配置
首先了解對應關係:Visual Studio 2017對應vc15
- 第一步:高階系統設定 -- 系統屬性 -- 環境變數 -- 使用者的變數 -- Path 加入:
D:\opencv-3.4.1\build\x64\vc15\bin
- 第二步:專案右鍵屬性
VC++目錄--》包含目錄
C/C++ ----- Additional Include Directories:
D:\opencv-3.4.1\build\include
D:\opencv-3.4.1\build\include\opencv
D:\opencv-3.4.1\build\include\opencv2
VC++目錄--》庫目錄
Linker ----- Additional Library Directories:
D:\opencv-3.4.1\build\x64\vc15\lib
- 第三步:連結器--》輸入--》附加依賴項
Linker ----- Additional Dependencies:
(Debug)
opencv_world341d.lib
(release, 可不填)
opencv_world300.lib
配置完成後在專案中編輯如下程式碼執行進行測試,如果成功即說明配置無誤:
// OpenCVTest1.cpp: 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() { Mat src = imread("D:/視訊跟蹤學習/images and videos/lena.png"); //圖片路徑自行修改 if (src.empty()) { printf("could not load image...\n"); return -1; } namedWindow("test opencv", CV_WINDOW_AUTOSIZE); imshow("test opencv", src); waitKey(0); cout << "1244124" << endl; system("pause"); return 0; }
能夠彈出圖片證明配置成功,可以進行下步學習。
載入影象(cv::imread)
imread的功能是載入影象檔案成為一個Mat物件,其中第一個引數表示影象檔名稱,第二個引數表示影象時什麼型別,第二個引數全體如下
IMREAD_UNCHANGED = -1, //!< If set, return the loaded image as is (with alpha channel, otherwise it gets cropped). IMREAD_GRAYSCALE = 0, //!< If set, always convert image to the single channel grayscale image. IMREAD_COLOR = 1, //!< If set, always convert image to the 3 channel BGR color image. IMREAD_ANYDEPTH = 2, //!< If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit. IMREAD_ANYCOLOR = 4, //!< If set, the image is read in any possible color format. IMREAD_LOAD_GDAL = 8, //!< If set, use the gdal driver for loading the image. IMREAD_REDUCED_GRAYSCALE_2 = 16, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/2. IMREAD_REDUCED_COLOR_2 = 17, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/2. IMREAD_REDUCED_GRAYSCALE_4 = 32, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/4. IMREAD_REDUCED_COLOR_4 = 33, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/4. IMREAD_REDUCED_GRAYSCALE_8 = 64, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/8. IMREAD_REDUCED_COLOR_8 = 65, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8. IMREAD_IGNORE_ORIENTATION = 128 //!< If set, do not rotate the image according to EXIF's orientation flag.
如果不設定,預設引數為IMREAD_ANYCOLOR
常用引數如下:
IMREAD_UNCHANGED:載入原圖,什麼都不做
IMREAD_COLOR :表示吧原作作為BGR模式載入進來
IMREAD_GRAYSCALE : 表示吧原圖作為灰度影象載入進來
注意:OpenCV支援JPG,PNG,TIFF等常見格式影象檔案載入
顯示影象(cv::namedWindow與cv::imshow)
- namedWindoW的功能是建立一個OpenCV視窗,它是有OpenCV自動建立與釋放的,你無須去銷燬他
- 常見的用法namedWindow("Window Title", WINDOW_AUTOSIZE)
- WINDOW_AUTOSIZE會自動根據影象大小,顯示視窗大小,不能人為的改變視窗大小
- WINFOW_NORMAL跟QT整合的時候會使用,允許修改視窗大小
- imshow根據視窗名稱顯示影象到指定的視窗上去,第一個引數是視窗名稱,第二個引數是Mat物件
修改影象(cv::cvtColor)
- cvtColor的功能是把影象從一個彩色空間轉換到另外一個色彩空間,有三個引數,第一個引數表示源影象、第二引數表示色彩空間轉換之後的影象、第三個引數表示源和目標色彩空間如:COLOR_BGR2HLS、COLOR BGR2GRAY等
cvtColor(image,gray_image,COLOR_BGR2GRAY);
儲存影象(cv:imwrite)
- 儲存影象檔案到指定目錄路徑,只有8位、16位的PNG、JPG、Tiff檔案格式而且是單通道或者三通道的BGR的影象才可以通過這種方式儲存
- 儲存PNG格式的時候可以儲存透明通道的圖片
- 可以指定壓縮引數
案例:讀取圖片,然後修改圖片,顯示出兩個圖片,最後把修改後的圖片儲存
// OpenCVTest1.cpp: 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() { Mat src = imread("D:/視訊跟蹤學習/images and videos/lena.png"); if (src.empty()) { printf("could not load image...\n"); return -1; } namedWindow("test opencv", CV_WINDOW_AUTOSIZE); imshow("test opencv", src); Mat out_image; //cvtColor(src, out_image, CV_BGR2HLS); //這種轉變方式也可以 cvtColor(src, out_image, COLOR_BGR2GRAY); namedWindow("change window", CV_WINDOW_AUTOSIZE); imshow("change window", out_image); imwrite("D:/change.png", out_image); waitKey(0); system("pause"); return 0; }
矩陣的掩膜操作
獲取影象畫素指標
- CV_Assert(mylmage.depth() == CV_8U);
- Mat.ptr<uchar>(int i=0)獲取畫素矩陣的指標,索引 i 表示第幾行,從0開始計行數。
- 獲得當前行指標const uchar* current=mylmage.ptr<uchar>(row);
- ·獲取當前畫素點P(row,col)的畫素值p(row,col)=curent[col]
畫素範圍處理saturate_cast<uchar>
將不再範圍內的畫素點歸併到範圍內,確保RGB值得範圍在0~255之間 :- saturate_cast<uchar>(-100),返回0。
- saturate_cast<uchar>(288),返回255
- saturate_cast<uchar>(100),返回100
掩膜操作實現影象對比度調整
如上圖,紅色是中心畫素,對每一個點通過周圍的四個點,做銳化處理後,得到的圖片既是調高對比度後的圖片(Mat物件)
公式為I(i,j) = 5 * I(i,j) - [I(i+1,j)+I(i-1,j)+I(i,j-1)+I(i,j+1)]
實現程式碼如下:
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() //圖片掩膜操作 { Mat src, dst; src = imread("D:/視訊跟蹤學習/images and videos/lena.png"); if (src.empty()) { printf("could not load image...\n"); return -1; } namedWindow("test opencv", CV_WINDOW_AUTOSIZE); imshow("test opencv", src); int cols = (src.cols - 1) * src.channels(); //channels是通道,算出來為列,長度 int offsetx = src.channels(); //通道數 int rows = src.rows; //行數,高度 dst = Mat::zeros(src.size(), src.type()); for (int row = 1; row < (rows - 1); row++) //從(1,1)開始,行數外層迴圈 { const uchar* previous = src.ptr<uchar>(row - 1); //獲取當前行的指標 const uchar* current = src.ptr<uchar>(row); //獲取上一行的指標 const uchar* next = src.ptr<uchar>(row + 1); //獲取下一行指標 uchar* output = dst.ptr<uchar>(row ); //按舊圖行數獲取新圖當前行指標 for (int col = offsetx; col < cols; col++) //列數內層迴圈 { output[col] = saturate_cast<uchar>(5 * current[col] - (current[col - offsetx] + current[col + offsetx] + previous[col] + next[col])); } } namedWindow("changed opencv", CV_WINDOW_AUTOSIZE); imshow("changed opencv", dst); waitKey(0); return 0; }
左圖為銳化處理後的圖片
函式呼叫filter2D功能直接進行銳化處理 OpenCV有專門的函式可直接實現如上的效果,如下Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, - 1, 0); //定義掩膜 filter2D(src, dst, src.depth(), kernel); //其中src與dst是Mat型別變數、src.depth表示點陣圖深度,有32、24、8等。
計算執行素的程式碼如下:
double t = getTickCount(); 。。。。。。。。。。。。。。。 。。。。。。。。。。。。。。。 double timeconsume = (getTickCount() - t) / getTickFrequency(); printf("time consume %.2f", timeconsume);
上面簡化後的程式碼:
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() //圖片掩膜操作 { Mat src, dst; src = imread("D:/視訊跟蹤學習/images and videos/lena.png"); if (src.empty()) { printf("could not load image...\n"); return -1; } namedWindow("test opencv", CV_WINDOW_AUTOSIZE); imshow("test opencv", src); double t = getTickCount(); Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, - 1, 0); //定義掩膜 filter2D(src, dst, src.depth(), kernel); //其中src與dst是Mat型別變數、src.depth表示點陣圖深度,有32、24、8等。 double timeconsume = (getTickCount() - t) / getTickFrequency(); printf("time consume %.2f", timeconsume); namedWindow("changed opencv", CV_WINDOW_AUTOSIZE); imshow("changed opencv", dst); waitKey(0); return 0; }
效果和上面相同