基於C++ OpenCV制作電子相冊查看器
前言
本文將使用OpenCV C++ 制作電子相冊查看器。類似於win10系統的“照片”功能。接下來就具體來看看是如何一步步的實現吧。
一、圖片讀取
我們想要一張張的查看文件夾下的圖片,第一步就得讀取將該文件夾下的所有圖片。
如上圖所示,為我創建的文件夾,該文件夾下有14張圖片。接下來我們就編寫代碼讀取該文件夾下的所有圖片。將讀取到的圖片存儲在images容器。
//讀取文件夾下所有圖片 string filename = "images"; vector<string>imageList; glob(filename, imageList); vector<Mat>images; for (int i = 0; i < imageList.size(); i++) { Mat img = imread(imageList[i]); images.push_back(img); }
現在我們已經有瞭images容器,其實再使用一個for循環就能夠一張張讀取容器裡的圖片瞭。不過這樣隻能一張張往下讀取,直到讀取完最後一張圖片程序結束。本案例的需求是使用鍵盤按鍵“->”向後讀取,“<-”向前讀取。
二、圖片展示
我們需要一張白色的畫佈用來放置圖片。為瞭將所有圖片都居中在畫佈中顯示,令畫佈中心為(cx,cy),當前圖片寬width,高height。則該圖片相對於畫佈起點為(x,y)。如下圖所示。
//將每一張照片放置畫佈中心 int x = cx - (width / 2); int y = cy - (height / 2); //將照片摳圖到畫佈上,此時照片位於畫佈中心位置 images[index].copyTo(bg(Rect(x, y, width, height)));
在這裡,使用一個判斷語句,判斷當前圖片尺寸是否大於畫佈尺寸。如果當前圖片尺寸大於畫佈尺寸,則將圖片自適應剪切。否則的話,會造成內存溢出。
//如果圖片過大,則對其進行裁剪 if (width > canvas.cols || height > canvas.rows) { //進行自適應剪切,每次隻在原基礎上剪切百分之八十 while (true) { resize(images[index], images[index], Size(0, 0), 0.8, 0.8, INTER_LINEAR); if (images[index].cols < canvas.cols&&images[index].rows < canvas.rows) { break; } } width = images[index].cols; height = images[index].rows; }
三、鍵盤控制
根據上述代碼我們已經可以將圖片顯示在畫佈中心瞭,接下來就需要使用鍵盤響應事件控制圖片查看。
我們使用方向鍵“->”控制向下查看,“<-”控制向上查看。具體請看源碼註釋。
if (key == 2424832) { //如果按動鍵盤‘←'鍵,則向前查看相片 if (index > 0)//如果圖片不是圖庫中第一張,則允許向前查看 { cout << "←" << endl; index--; } } else if (key == 2555904) { //如果按動鍵盤‘→'鍵,則向後查看相片 if (index < size-1)//如果圖片不是圖庫中最後一張,則允許向後查看 { cout << "→" << endl; index++; } } //如果按動鍵盤‘ESC'鍵,則退出程序 else if (key == 27) { break; }
四、效果顯示
如上圖所示,至此我們已經完成瞭案例所想要的效果。請參考源碼,註釋也比較詳細瞭。
五、源碼
#include<iostream> #include<opencv2/opencv.hpp> using namespace std; using namespace cv; int main() { //讀取文件夾下所有圖片 string filename = "images"; vector<string>imageList; glob(filename, imageList); vector<Mat>images; for (int i = 0; i < imageList.size(); i++) { Mat img = imread(imageList[i]); images.push_back(img); } //創建畫佈,用於放置相片 Mat canvas = Mat(Size(1400, 900), CV_8UC3, Scalar::all(255)); //畫佈中心 int cx = canvas.cols / 2; int cy = canvas.rows / 2; int size = images.size();//圖庫中相片數量 int index = 0; //當前圖庫中相片索引 while (true) { //waitKey無法正常捕捉方向鍵(上下左右),故使用waitKeyEx int key = waitKeyEx(0); if (key == 2424832) { //如果按動鍵盤‘←'鍵,則向前查看相片 if (index > 0)//如果圖片不是圖庫中第一張,則允許向前查看 { cout << "←" << endl; index--; } } else if (key == 2555904) { //如果按動鍵盤‘→'鍵,則向後查看相片 if (index < size-1)//如果圖片不是圖庫中最後一張,則允許向後查看 { cout << "→" << endl; index++; } } //如果按動鍵盤‘ESC'鍵,則退出程序 else if (key == 27) { break; } //將畫佈拷貝一份,每經一次循環,更新一次圖片。 Mat bg = canvas.clone(); //計算每一張圖片的寬高 int width = images[index].cols; int height = images[index].rows; //如果圖片過大,則對其進行裁剪 if (width > canvas.cols || height > canvas.rows) { //進行自適應剪切,每次隻在原基礎上剪切百分之八十 while (true) { resize(images[index], images[index], Size(0, 0), 0.8, 0.8, INTER_LINEAR); if (images[index].cols < canvas.cols&&images[index].rows < canvas.rows) { break; } } width = images[index].cols; height = images[index].rows; } //將每一張照片放置畫佈中心 int x = cx - (width / 2); int y = cy - (height / 2); //將照片摳圖到畫佈上,此時照片位於畫佈中心位置 images[index].copyTo(bg(Rect(x, y, width, height))); imshow("Demo", bg); } destroyAllWindows(); system("pause"); return 0; }
總結
本文使用OpenCV C++ 制作電子相冊查看器,類似win10系統下的“照片”功能,關鍵步驟有以下幾點。
1、圖片在畫佈上居中顯示
2、使用鍵盤響應事件控制相片上下讀取
到此這篇關於基於C++ OpenCV制作電子相冊查看器的文章就介紹到這瞭,更多相關C++ OpenCV電子相冊查看器內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- C++ OpenCV生成蒙太奇圖像的示例詳解
- C++ OpenCV實現抖音"藍線挑戰"特效
- C++ OpenCV實戰之制作九宮格圖像
- C++ OpenCV制作哈哈鏡圖像效果
- OpenCV實現更改圖片顏色功能