OpenCv VS C++ 影象處理(上)
VS OpenCv配置:
首先是VS的OpenCv配置,外部庫目錄指定和外部包含檔案的指定。
- 指定建立的工程為空白工程:
- 建立完工程之後,我們選中解決方案欄中的Resource Files目錄(即原始碼目錄),然後新建一個C++原始碼檔案:
- 設定原始碼的檔名,例如:Main,然後建立此原始碼檔案到工程中:
- 在VS中有個叫做“屬性管理器”的工具,用於進行VS整體引數的配置,配置一次之後,以後所有新建專案都能應用改配置,不用再一一進行配置操作,使用起來也非常方便。點選工具欄中的:View—>Other Windows—>Property Manger開啟屬性管理器:
- 在新出現的屬性管理器欄中,展開目錄,選中Debug|Win64中的Microsoft.Cpp.x64.user,並右鍵點選屬性(Properties)進入屬性介面:
1)配置包含目錄:
在通用屬性(Common Properties)—>VC ++目錄—>包含目錄,然後點選右側三角標誌選中Edit進入編輯:
向其中新增下面三個路徑:
E:\OpenCV\opencv\build\include
E:\OpenCV\opencv\build\include\opencv
E:\OpenCV\opencv\build\include\opencv2
2)配置庫檔案目錄:
完成上面的包含目錄配置之後,我們還需要進行庫檔案的配置:回到屬性介面,選擇包含目錄下面的Library Directories(庫檔案目錄):
向庫檔案目錄下新增OpenCV的庫檔案目錄:E:\OpenCV\opencv\build\x64\vc14\lib,這個目錄根據每個人自己在第一步安裝OpenCV中選擇的目錄進行選定:
3)配置動態連結庫:
我們可以檢視步驟2)中新增的庫檔案目錄下面.lib檔案列表,發現在3.1.0版本的OpenCV中,僅剩下兩個庫檔案,分別是:opencv_world310.lib和opencv_world310d.lib,這裡兩個庫檔案的區別就是:opencv_world310.lib是Release模式版本,而opencv_world310d.lib是Debug模式版本:
跟上述兩個步驟相似,在屬性介面中開啟Linker(連結庫)—>Input(輸入)—>Additional Dependencies(新增依賴):
將我們剛剛在OpenCV庫檔案目錄下看到的兩個庫檔案其中一個新增到這裡(根據模式需求Release模式或Debug模式):
上面部分為新建工程時VS的Opencv的配置,配置好了之後可以引入標頭檔案,使用Opencv了。
OpenCv影象處理:
(1).首先講解OpenCv改變影象大小,這裡以呼叫攝像頭舉例。
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\opencv.hpp>
using namespace cv;
int main()
{
//【1】從攝像頭讀入視訊
VideoCapture capture(0);
while (1)
{
Mat frame; //定義一個Mat變數,用於儲存每一幀的影象
capture >> frame; //讀取當前幀
resize(frame,frame,Size(360,240)); //改變影象大小
imshow("aa", frame);
waitKey(30); //延時30ms
}
return 0;
}
resize函式可以改變影象大小。
對於傳遞矩陣opencv矩陣賦值函式copyTo、clone、過載元算賦‘=’之間實現的功能相似均是給不同的矩陣賦值功能。copyTo和clone函式基本相同,被賦值的矩陣和賦值矩陣之間空間獨立,不共享同一空間。但是過載元算賦‘=’,被賦值的矩陣和賦值矩陣之間空間共享,改變任一個矩陣的值,會同時影響到另一個矩陣。
(2).然後講解OpenCv改變影象編碼格式
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\opencv.hpp>
using namespace cv;
int main()
{
//【1】從攝像頭讀入視訊
VideoCapture capture(0);
while (1)
{
Mat frame; //定義一個Mat變數,用於儲存每一幀的影象
capture >> frame; //讀取當前幀
cvtColor(frame,frame,CV_RGB2GRAY); //轉為灰度圖
imshow("aa", frame);
waitKey(30); //延時30ms
}
return 0;
}
cvtColor改變編碼格式,常用的是COLOR_RGB2GRAY(CV_RGB2GRAY)
還有接近人的直觀感覺的COLOR_RGB2HSV(CV_RGB2HSV),顏色資訊(H)、飽和度(S)、亮度(V)。
轉化後顏色改變,因為imshow命令裡面接受的引數是RGB空間的矩陣,把HSV空間的矩陣給imshow,會把它解釋為RGB空間的矩陣,顯示出的效果就不是源影象了.
HSV範圍(根據實際情況改)
這裡給出一個獲取HSV的程式碼。
#include<opencv2\opencv.hpp>
#include <ctype.h>
#include "iostream"
using namespace std;
using namespace cv;
void on_mouse(int EVENT, int x, int y, int flags, void* userdata);
int main(int argc, char** argv)
{
Mat src, hsv;
//此處更改圖片地址
src = imread("C:\\Users\\ttp\\Pictures\\Camera Roll\\WIN_20180714_14_18_10_Pro.jpg");
namedWindow("【display】");
setMouseCallback("【display】", on_mouse, &src);
while (1)
{
imshow("【display】", src);
waitKey(40);
}
}
void on_mouse(int EVENT, int x, int y, int flags, void* userdata)
{
Mat rgb, hsv;
rgb = *(Mat*)userdata;
Mat temp;
cvtColor(*(Mat*)userdata, hsv, CV_RGB2HSV);
Point p(x, y);
switch (EVENT)
{
case EVENT_LBUTTONDOWN:
{
printf("b=%d\t", rgb.at<Vec3b>(p)[0]);
printf("g=%d\t", rgb.at<Vec3b>(p)[1]);
printf("r=%d\n", rgb.at<Vec3b>(p)[2]);
printf("H=%d\t", hsv.at<Vec3b>(p)[0]);
printf("S=%d\t", hsv.at<Vec3b>(p)[1]);
printf("V=%d\n", hsv.at<Vec3b>(p)[2]);
circle(rgb, p, 2, Scalar(255), 3);
}
break;
}
}
(3).然後再講解OpenCv影象的顏色識別
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\opencv.hpp>
using namespace cv;
int alpha_slider1, alpha_slider2;
void on_trackbar(int, void*) {}
int main()
{
VideoCapture capture(0); //【1】從攝像頭讀入視訊
namedWindow("[總]");
createTrackbar("Hmin", "[總]", &alpha_slider1, 180, on_trackbar);
createTrackbar("Hmax", "[總]", &alpha_slider2, 180, on_trackbar);
while (1)
{
Mat frame; //定義一個Mat變數,用於儲存每一幀的影象
Mat HSV;
Mat mask; //儲存inRange後的值
capture >> frame; //讀取當前幀
cvtColor(frame, HSV, COLOR_RGB2HSV); //轉化為HSV
inRange(HSV, Scalar(alpha_slider1, 43, 46), Scalar(alpha_slider2, 255, 255), mask);
imshow("儲存", mask);
imshow("[總]", frame);
waitKey(30); //延時30ms
}
return 0;
}
z
這個程式會建立一個滑動條來改變H的值,從而識別顏色
函式原型(C++):
void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst)dst(I) = lowerb(I)0 ≤ src(I)0 < upperb(I)0 ∧ lowerb(I)1 ≤ src(I)1 < upperb(I)1 ∧lowerb(I)2 ≤ src(I)2 < upperb(I)2
即,每個通道的畫素值都必須在規定的閾值範圍內!
這篇文章先講到這。