這篇文章給大家介紹如何理解OpenCV及其工程應(yīng)用,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供岑溪網(wǎng)站建設(shè)、岑溪做網(wǎng)站、岑溪網(wǎng)站設(shè)計(jì)、岑溪網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、岑溪企業(yè)網(wǎng)站模板建站服務(wù),十余年岑溪做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
OpenCV是一個(gè)基于BSD許可(開源)發(fā)行的跨平臺的計(jì)算機(jī)視覺和機(jī)器學(xué)習(xí)軟件庫,可以運(yùn)行在Linux、Windows、Android和Mac OS操作系統(tǒng)上。它輕量級而且高效——由一系列 C 函數(shù)和少量 C++ 類構(gòu)成,同時(shí)提供了Python、Ruby、MATLAB等語言的接口,實(shí)現(xiàn)了圖像處理和計(jì)算機(jī)視覺方面的很多通用算法。
OpenCV在圖像分割、人臉識別、物體識別、動作跟蹤、動作分析、機(jī)器視覺等領(lǐng)域都有廣泛的應(yīng)用。
以下是OpenCV的基本操作及其應(yīng)用案例。
import cv2 image = cv2.imread("test.jpg") # 讀取操作 cv2.imshow("test", image) # 顯示操作 cv2.waitKey() # 等待按鍵 cv2.imwrite("save.jpg") # 保存操作
image = cv2.imread("test.jpg") hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # 轉(zhuǎn)換到HSV空間 hls = cv2.cvtColor(image, cv2.COLOR_BGR2HLS) # 轉(zhuǎn)換到HLS空間 lab = cv2.cvtColor(image, cv2.COLOR_BGR2Lab) # 轉(zhuǎn)換到Lab空間 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 轉(zhuǎn)換到GRAY空間(灰度圖)
HSV這個(gè)模型中顏色的參數(shù)分別是:色調(diào)(H),飽和度(S),明度(V),該模型常用來做綠幕分割。
在圖像檢測中,可以對樣本進(jìn)行色彩空間轉(zhuǎn)換實(shí)現(xiàn)數(shù)據(jù)增強(qiáng),如將訓(xùn)練數(shù)據(jù)直接轉(zhuǎn)換到HSV空間,或者調(diào)整V(明度)通道的大小,改變圖片的明暗,再轉(zhuǎn)到BGR格式。
image = cv2.imread("test.jpg") resize = cv2.resize(image, (), fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA) # 長寬縮小到0.5倍
在對圖像作平移操作時(shí),需創(chuàng)建2行3列變換矩陣,M矩陣表示水平方向上平移為x,豎直方向上的平移距離為y。
import cv2 import numpy as np image = cv2.imread("test.jpg") rows, cols, channels = image.shape M = np.float32([[1,0,100],[0,1,50]]) res = cv.warpAffine(image, M, (cols, rows))
旋轉(zhuǎn)所需的變換矩陣可以通過函數(shù)cv2.getRotationMatrix2D得到。
image = cv2.imread('test.jpg') rows, cols, channels = image.shape rotate = cv2.getRotationMatrix2D((rows*0.5, cols*0.5), 45, 1) # 第一個(gè)參數(shù):旋轉(zhuǎn)中心點(diǎn) 第二個(gè)參數(shù):旋轉(zhuǎn)角度 第三個(gè)參數(shù):縮放比例 res = cv2.warpAffine(image, rotate, (cols, rows))
模糊濾波操作去除圖像中的椒鹽噪聲、提高圖像的對比度、實(shí)現(xiàn)銳化處理、提高立體感等。
image = cv2.imread('test.jpg') blur = cv2.blur(image, (5, 5)) # 均值濾波 第二個(gè)參數(shù)是卷積核大小 median_blur = cv2.medianBlur(image, 5) # 中值濾波 gaussian_blur = cv2.GussianBlur(image, (5, 5)) # 高斯模糊
圖像形態(tài)學(xué)操作是基于形狀的一系列圖像處理操作的合集,主要是基于集合論基礎(chǔ)上的形態(tài)學(xué)數(shù)學(xué)。
形態(tài)學(xué)有四個(gè)基本操作:侵蝕、膨脹、開、閉
膨脹與腐蝕是圖像處理中最常用的形態(tài)學(xué)操作手段
膨脹就是圖像中的高亮部分進(jìn)行膨脹,“領(lǐng)域擴(kuò)張”,效果圖擁有比原圖更大的高亮區(qū)域。侵蝕就是原圖中的高亮部分被腐蝕,“領(lǐng)域被蠶食”,效果圖擁有比原圖更小的高亮區(qū)域
它們能實(shí)現(xiàn)多種多樣的功能,主要如下:
消除噪聲
分割出獨(dú)立的圖像元素,在圖像中連接相鄰的元素
尋找圖像中的明顯的極大值區(qū)域或極小值區(qū)域
求出圖像的梯度
image = cv2.imread("test.jpg") kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3)) # 獲取卷積核 eroded = cv2.erode(image, kernel) # 腐蝕圖像 dilated = cv2.dilate(image, kernel) # 膨脹圖像
開運(yùn)算:先腐蝕后膨脹,用于移除由圖像噪音形成的斑點(diǎn)
閉運(yùn)算:先膨脹后腐蝕,用來連接被誤分為許多小塊的對象
輪廓查找在圖像檢測領(lǐng)域有很廣泛的應(yīng)用,比如查找圖像中明顯的色塊、條紋、物體邊緣等等,查找輪廓前先要對圖像進(jìn)行二值化處理。
# opencv版本大于3 contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # 第一個(gè)參數(shù):查找的二值圖像 第二個(gè)參數(shù):輪廓檢索模式 第三個(gè)參數(shù):輪廓近似方法 # 返回值contours為查找到的輪廓列表,hierarhy為輪廓之間的層級關(guān)系
查找到輪廓后可以通過drawContours函數(shù)繪制出輪廓
cv2.drawContours(temp,contours,-1,(0,255,0),3) # 第一個(gè)參數(shù):畫布,可以是原圖 第二個(gè)參數(shù):查找到的輪廓 第三個(gè)參數(shù):-1表示全畫 第四個(gè)參數(shù):顏色 第五個(gè)參數(shù):輪廓寬度
游戲畫面因?yàn)槊佬g(shù)資源缺失、程序bug都會產(chǎn)生各種色塊,常見的有白色、紫色等,怎么通過程序篩選出這類異常畫面,加快測試過程呢?
通過觀察,我們發(fā)現(xiàn)色塊類的異常都是一些比較規(guī)則的矩形圖像,色彩差很明顯,基于這些特點(diǎn),我們可以很容易的篩選出色塊。
通過RGB通道的數(shù)值大小剔除掉其它的顏色,得到黑白二值圖
import cv2 import numpy as np image = cv2.imread("test.jpg") b, g, r = cv2.split(self.image) # 分離B、G、R通道 b = np.where(b >= 250, 1, 0) # 找到G通道符合要求的像素點(diǎn)置1,不符合置0 g = np.where(g >= 250, 1, 0) # 找到G通道符合要求的像素點(diǎn)置1,不符合置0 r = np.where(r >= 250, 1, 0) # 找到G通道符合要求的像素點(diǎn)置1,不符合置0 gray = b + g + r # 將三個(gè)通道疊加成一個(gè)通道 gray = np.where(gray==3, 255, 0).astype(np.uint8) # 像素點(diǎn)為3的即為滿足要求的點(diǎn)設(shè)置為白色,不符合設(shè)置為黑色
得到的黑白二值圖由于除了色塊外其它圖像位置也有接近色塊顏色的位置被保留了下來,需要剔除
通過查找二值圖輪廓的方法我們可以篩選出分離的小色塊
contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # 獲取輪廓及層級關(guān)系
通過輪廓周長和面積剔除掉小色塊,這些色塊很可能就是提取的正常區(qū)域顏色較相似的點(diǎn)。
def screen_contour(contour): contour_area = cv2.contourArea(contour) if contour_area > self.area_limit: return True return False pass_contours = [] for contour in contours: if screent_contour(contour): pass_contours.append(contour)
由于色塊更接近于矩形,我們可以通過輪廓計(jì)算出色塊的寬和高,色塊的面積可以估算出來,色塊面積與估算面積越接近,說明檢測到的色塊更接近矩形,通過這個(gè)方法,可以篩選出大部分不規(guī)則的色塊。
def screent_contour(contour): width = np.max(contour[:,:,0]) - np.min(contour[:,:,0]) height = np.max(contour[:,:,1]) - np.min(contour[:,:,1]) block_area = width * heigh contour_area = cv2.contourArea(contour) slimier = cv2.contourArea(contour) / block_area if slimier > self.simliar_rate: return True return False pass_contours = [] for contour in contours: if screent_contour(contour): pass_contours.append(contour)
OpenCV是如何完成以上這些操作的呢?
OpenCV在讀取圖像的時(shí)候是將圖像信息轉(zhuǎn)換成了矩陣,默認(rèn)矩陣為(height,width,channel),channel對應(yīng)的是B、G、R通道,每個(gè)像素點(diǎn)的顏色由三個(gè)通道一起決定,和三元色的關(guān)系是一樣的,B、G、R的大小代表的是色彩比例。
色彩空間的轉(zhuǎn)換是將圖像數(shù)據(jù)從一種表示關(guān)系變換到了另一種表示關(guān)系,比如BGR轉(zhuǎn)換到HSV顏色空間是將原本的三原色表示法轉(zhuǎn)換到了色調(diào)(H),飽和度(S),明度(V)表示法,每個(gè)channel所表示的含義發(fā)生了變化。
從信息的角度考慮,攝像機(jī)將光照信息采集后轉(zhuǎn)化成了數(shù)字的形式(圖像矩陣),顏色空間的轉(zhuǎn)換是將圖像數(shù)據(jù)從一種表示方法變換到另一種表示方法,信息的轉(zhuǎn)化也會引起信息的丟失或者引入噪聲,比如攝像機(jī)在采集光照信息的時(shí)候很容易采集到椒鹽噪聲,丟棄光照信息中的一些頻段,清晰度降低等等,在做色彩空間轉(zhuǎn)換的時(shí)候也可能發(fā)生信息丟失,比如從彩色圖片轉(zhuǎn)化到灰度圖。深度學(xué)習(xí)中的圖像檢測、人臉識別就是要從這些圖像信息中提取我們想要的信息。
在做圖像幾何變換的時(shí)候,我們需要提供變換矩陣,矩陣是怎么完成這些操作的呢?
我們知道矩陣代表的就是一種空間映射,nxm的矩陣(列向量線性無關(guān))代表的是n維空間到m維空間的映射,如上圖所示,第一個(gè)立方體所在的空間通過一個(gè)3x3的矩陣映射到了第二個(gè)立方體所在的空間,立方體的形狀發(fā)生了變化,再比如第一個(gè)立方體所在的空間通過一個(gè)3x2的矩陣映射到了它的影子所在的空間,立方體被壓縮成了一個(gè)平面。
立方體可以通過矩陣(實(shí)數(shù)范圍)映射成球體嗎?因?yàn)槠浯淼氖蔷€性變換,所以是不可以的。
我們在處理圖像問題的時(shí)候要將信息從一個(gè)空間映射到另一個(gè)空間,由于問題的復(fù)雜性所以線性映射是滿足不了要求的,這也就是為什么在深度學(xué)習(xí)中需要加入激活函數(shù)的原因。
從上一節(jié)的分析中我們發(fā)現(xiàn),圖像的處理過程就是從數(shù)據(jù)中找規(guī)律,將圖像信息從一種表示變換到另一種表示,這個(gè)工作正好是機(jī)器學(xué)習(xí)的強(qiáng)項(xiàng),再延申一下,不管是圖像數(shù)據(jù)、文本數(shù)據(jù)、音頻數(shù)據(jù),要從數(shù)據(jù)中找規(guī)律,都會用到機(jī)器學(xué)習(xí),從信息的角度考慮,這些問題本質(zhì)上是沒有區(qū)別的。
openCV已經(jīng)集成了很多機(jī)器學(xué)習(xí)算法、如K近鄰(KNN),支持向量機(jī)(SVM)、決策樹、隨機(jī)森林、Boost、邏輯回歸、ANN等。
下圖是摘自scikit-learn的一張圖片,很形象的展示了不同的機(jī)器學(xué)習(xí)算法是如何對數(shù)據(jù)進(jìn)行處理的,從宏觀角度來講就是如何將信息變換到不同的空間。
關(guān)于如何理解OpenCV及其工程應(yīng)用就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。