1. 程式人生 > >OpenCV(一)

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;
}

  效果和上面相同