重磅干貨,第一時間送達
圖像處理
圖像處理始于計算機識別數(shù)據(jù)。首先,為圖像格式的數(shù)據(jù)創(chuàng)建一個矩陣。圖像中的每個像素值都被處理到此矩陣中。例如,為尺寸為200x200的圖片創(chuàng)建尺寸為200x200的矩陣。如果此圖像是彩色的,則此尺寸變?yōu)?00x200x3(RGB)。實際上,圖像處理中的每個操作都是矩陣運算。假設(shè)需要對圖像進行模糊操作。特定的過濾器會在整個矩陣上移動,從而對所有矩陣元素或部分矩陣元素進行更改。作為該過程的結(jié)果,圖像的所需部分或全部變得模糊。
在許多情況下都需要對圖像進行處理[1]。通常,這些操作應(yīng)用于將在深度學(xué)習(xí)模型中使用。例如,使用彩色圖像進行訓(xùn)練會導(dǎo)致性能下降。卷積神經(jīng)網(wǎng)絡(luò)是圖像處理最廣泛使用的深度學(xué)習(xí)結(jié)構(gòu)之一。該網(wǎng)絡(luò)確定圖像上卷積層訓(xùn)練所需的屬性。在這一點上,僅圖像中將用于訓(xùn)練的某些部分可能需要處理。圖片中更圓的線條而不是清晰的線條突出有時可以提高訓(xùn)練的成功率。
除上述情況外,相同的邏輯還基于日常生活中使用的圖像優(yōu)化程序的操作。圖像處理中有許多過程,例如提高圖像質(zhì)量,對圖像進行還原,消除噪聲,直方圖均衡化。
OpenCV
OpenCV是用于圖像處理的最流行的庫之一[2]。有許多使用OpenCV的公司,例如Microsoft,Intel,Google,Yahoo。OpenCV支持多種編程語言,例如Java,C ++,Python和Matlab。本工作中的所有示例都是使用Python編碼的。
import cv2
from matplotlib import pyplot as plt
import numpy as np
首先,導(dǎo)入庫。OpenCV中的某些功能在每個版本中均無法穩(wěn)定運行。這些功能之一是“ imshow”。此功能使我們可以查看由于操作導(dǎo)致的圖像變化。對于有此類問題的人,matplotlib庫將用作這項工作的替代解決方案。
圖1.標(biāo)準(zhǔn)圖像
要執(zhí)行的過程將應(yīng)用于上面顯示的圖像(圖1)。最初會讀取圖像,以便對其進行處理。
img_path = "/Users/..../opencv/road.jpeg"
img = cv2.imread(img_path)
print(img.shape)
>>>(960, 1280, 3)
圖2中圖像的尺寸為960 x 1280像素。當(dāng)我們要在讀取過程后打印尺寸時,我們看到960x1280x3的結(jié)果。因此,根據(jù)圖像的尺寸創(chuàng)建了一個矩陣,并為該矩陣分配了圖像每個像素的值。RGB有3個維度,因為圖像是彩色的。
如果我們想將圖像轉(zhuǎn)換為黑白圖像,則使用cvtColor函數(shù)。
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
如果要查看由于該函數(shù)而發(fā)生的更改,可以使用matplotlib中的imshow函數(shù)。
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
plt.imshow(gray_image)
plt.show()
print(gray_image.shape)
>>>(960, 1280)
圖2.黑白圖像
如圖2所示,我們已將圖像轉(zhuǎn)換為黑白圖像。當(dāng)我們檢查其尺寸時,不再有3個尺寸。
當(dāng)查看圖像的矩陣值時,我們看到它由0到255之間的值組成。在某些情況下,我們可能希望此矩陣僅由0到255的值組成[3]。在這種情況下使用閾值功能。
(thresh, blackAndWhiteImage) = cv2.threshold(gray_image, 20, 255, cv2.THRESH_BINARY)
(thresh, blackAndWhiteImage) = cv2.threshold(gray_image, 80, 255, cv2.THRESH_BINARY)
(thresh, blackAndWhiteImage) = cv2.threshold(gray_image, 160, 255, cv2.THRESH_BINARY)
(thresh, blackAndWhiteImage) = cv2.threshold(gray_image, 200, 255, cv2.THRESH_BINARY)
plt.imshow(blackAndWhiteImage)
plt.show()
圖3.應(yīng)用了閾值功能的圖像
OpenCV中閾值功能所需的第一個參數(shù)是要處理的圖像。以下參數(shù)是閾值。第三個參數(shù)是我們要分配超出閾值的矩陣元素的值??梢栽趫D3中看到四個不同閾值的影響。在第一張圖像(圖像1)中,該閾值確定為20.將20之上的所有值分配給255.其余值為設(shè)置為0。這僅允許黑色或非常深的顏色為黑色,而所有其他陰影直接為白色。圖像2和圖像3的閾值分別為80和160.最后,在圖像4中將閾值確定為200.與圖像1不同,白色和非常淺的顏色被指定為255,而所有在圖4中將剩余值設(shè)置為0。
圖像處理中使用的另一種方法是模糊。這可以通過多個功能來實現(xiàn)。
output2 = cv2.blur(gray_image, (10, 10))
plt.imshow(output2)
plt.show()
圖4具有模糊功能的模糊圖像
output2 = cv2.GaussianBlur(gray_image, (9, 9), 5)
plt.imshow(output2)
plt.show()
圖5.具有高斯模糊函數(shù)的模糊圖像
如圖4和圖5所示,黑白圖像使用指定的模糊濾鏡和模糊度模糊。此過程通常用于消除圖像中的噪點。此外,在某些情況下,由于圖像中的線條清晰,訓(xùn)練也會受到嚴(yán)重影響。出于此原因使用它的情況下可用。
在某些情況下,可能需要旋轉(zhuǎn)數(shù)據(jù)以進行擴充,或者用作數(shù)據(jù)的圖像可能會偏斜。在這種情況下,可以使用以下功能。
(h, w) = img.shape[:2]
center = (w / 2, h / 2)
M = cv2.getRotationMatrix2D(center, 13, scale =1.1)
rotated = cv2.warpAffine(gray_image, M, (w, h))
plt.imshow(rotated)
plt.show()
圖6.具有g(shù)etRotationMatrix2D函數(shù)的旋轉(zhuǎn)圖像
首先,確定圖像的中心,并以此中心進行旋轉(zhuǎn)。getRotationMatrix2D函數(shù)的第一個參數(shù)是計算出的中心值。第二個參數(shù)是角度值。最后,第三個參數(shù)是旋轉(zhuǎn)后要應(yīng)用的縮放比例值。如果將此值設(shè)置為1,它將僅根據(jù)給定的角度旋轉(zhuǎn)同一圖像,而不會進行任何縮放。
實驗1
上述方法通常在項目中一起使用。讓我們制作一個示例項目,以更好地了解這些結(jié)構(gòu)和過程。
假設(shè)我們要訓(xùn)練車輛的自動駕駛飛行員[4]。當(dāng)檢查圖1中的圖像以解決此問題時,我們的自動駕駛儀應(yīng)該能夠理解路徑和車道。我們可以使用OpenCV解決此問題。由于顏色在此問題中無關(guān)緊要,因此圖像將轉(zhuǎn)換為黑白。矩陣元素通過確定的閾值設(shè)置值0和255。如上面在閾值功能的解釋中提到的,閾值的選擇對于該功能至關(guān)重要。該問題的閾值設(shè)置為200。我們可以清除其他詳細信息,因為這足以專注于路邊和車道。為了消除噪聲,使用高斯模糊函數(shù)執(zhí)行模糊處理??梢詮膱D1到5詳細檢查到此為止的部分。
這些過程之后,將應(yīng)用Canny邊緣檢測。
img = cv2.imread(img_path)
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
(thresh, output2) = cv2.threshold(gray_image, 200, 255, cv2.THRESH_BINARY)
output2 = cv2.GaussianBlur(output2, (5, 5), 3)
output2 = cv2.Canny(output2, 180, 255)
plt.imshow(output2)
plt.show()
圖7. Canny函數(shù)結(jié)果圖像
Canny函數(shù)采用的第一個參數(shù)是將對其執(zhí)行操作的圖像。第二參數(shù)是低閾值,第三參數(shù)是高閾值。逐像素掃描圖像以進行邊緣檢測。一旦存在低于下閾值的值,則檢測到邊緣的第一側(cè)。當(dāng)找到一個比較高閾值高的值時,確定另一側(cè)并創(chuàng)建邊緣。因此,為每個圖像和每個問題確定閾值參數(shù)值。為了更好地觀察高斯模糊效果,讓我們做同樣的動作而又不模糊這次。
img = cv2.imread(img_path)
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
(thresh, output2) = cv2.threshold(gray_image, 200, 255, cv2.THRESH_BINARY)
output2 = cv2.Canny(output2, 180, 255)
plt.imshow(output2)
plt.show()
圖8.非模糊圖像
如果未實現(xiàn)GaussianBlur函數(shù),則噪聲在圖8中清晰可見。這些噪聲對于我們的項目可能不是問題,但它們將對不同項目和情況下的培訓(xùn)成功產(chǎn)生重大影響。在該階段之后,基于確定的邊緣在真實(標(biāo)準(zhǔn))圖像上執(zhí)行處理。為此使用HoughLinesP和line函數(shù)。
lines = cv2.HoughLinesP(output2, 1, np.pi/180,30)
for line in lines:
x1,y1,x2,y2 = line[0]
cv2.line(img,(x1,y1),(x2,y2),(0,255,0),4)
plt.imshow(img)
圖9.應(yīng)用了HoughLinesP函數(shù)的圖像
如圖9所示,可以很好地實現(xiàn)道路邊界和車道。但是,當(dāng)仔細檢查圖9時,會發(fā)現(xiàn)一些問題。盡管確定車道和道路邊界沒有問題,但云也被視為道路邊界。應(yīng)該使用掩蔽方法來防止這些問題[5]。
def mask_of_image(image):
height = image.shape[0]
polygons = np.array([[(0,height),(2200,height),(250,100)]])
mask = np.zeros_like(image)
cv2.fillPoly(mask,polygons,255)
masked_image = cv2.bitwise_and(image,mask)
return masked_image
我們可以使用mask_of_image函數(shù)進行屏蔽過程。首先,將要掩蓋的區(qū)域確定為多邊形。參數(shù)值完全是特定于數(shù)據(jù)的值。
圖10.確定的遮罩區(qū)域
蒙版(圖10)將應(yīng)用于真實圖片。對與真實圖像中黑色區(qū)域相對應(yīng)的區(qū)域不進行任何處理。但是,上述所有過程都應(yīng)用于與白色區(qū)域相對應(yīng)的區(qū)域。
圖11.遮罩應(yīng)用的圖像
如圖11所示,通過屏蔽過程,我們解決了在云中看到的問題。
實驗2
我們使用HougLinesP解決了車道識別問題。讓我們假設(shè)這個問題適用于圓形[6]。
圖12.硬幣圖像[8]
讓我們創(chuàng)建一個識別圖12中硬幣的圖像處理。在這種情況下,這里還將使用車道識別項目中使用的方法。
img = cv2.imread("/Users/.../coin.png")
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
(thresh, output2) = cv2.threshold(gray_image, 120, 255, cv2.THRESH_BINARY)
output2 = cv2.GaussianBlur(output2, (5, 5), 1)
output2 = cv2.Canny(output2, 180, 255)
plt.imshow(output2, cmap = plt.get_cmap("gray"))circles = cv2.HoughCircles(output2,cv2.HOUGH_GRADIENT,1,10, param1=180,param2=27,minRadius=20,maxRadius=60)
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
# draw the outer circle
cv2.circle(img,(i[0],i[1]),i[2],(0,255,0),2)
# draw the center of the circle
cv2.circle(img,(i[0],i[1]),2,(0,0,255),3)
plt.imshow(img)
圖13.最終硬幣圖片
作為圖像處理的結(jié)果,可以在圖13中找到i。圖像被轉(zhuǎn)換為黑白圖像。然后應(yīng)用閾值函數(shù)。使用了高斯模糊和Canny邊緣檢測功能。最后,使用HoughCircles函數(shù)繪制圓。
圖像處理也適用于圖像格式的文本。
圖14.圖像格式的文本
假設(shè)我們要使用圖14中所示的文本來訓(xùn)練我們的系統(tǒng),我們希望通過訓(xùn)練,我們的模型可以識別所有單詞或某些特定單詞。我們可能需要向系統(tǒng)傳授單詞的位置信息。OpenCV也用于此類問題。首先,圖像(在圖14中)被轉(zhuǎn)換為文本。為此,使用了一種稱為Tesseract的光學(xué)字符識別引擎[7]。
data = pytesseract.image_to_data(img, output_type=Output.DICT, config = "--psm 6")
n_boxes = len(data['text'])
for i in range(n_boxes):
(x, y, w, h) = (data['left'][i], data['top'][i], data['width'][i], data['height'][i])
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
plt.imshow(img)
plt.show()
圖15.單詞位置信息的處理
通過將在Tesseract的幫助下獲得的信息與OpenCV相結(jié)合,可以實現(xiàn)圖15所示的圖像。每個單詞和每個單詞塊都用圓括起來。通過操縱來自Tesseract的信息,也可以只操縱框架中的某些單詞。另外,可以應(yīng)用圖像處理以從噪聲中清除文本。但是,如果將其他示例中使用的GaussianBlur函數(shù)應(yīng)用于文本,則會對文本的質(zhì)量和易讀性產(chǎn)生不利影響,因此將使用midBlur函數(shù)代替GaussianBlur函數(shù)。
img = cv2.imread(img_path)
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
output2 = cv2.medianBlur(gray_image, ksize=5)
plt.imshow(output2)
plt.show()
圖16. meanBlur函數(shù)應(yīng)用的圖像
在圖14中檢查圖像時,虛線在某些單詞下方清晰可見。在這種情況下,光學(xué)字符識別引擎可能會誤讀某些單詞。圖16中位數(shù)模糊處理的結(jié)果是,這些虛線消失了。
注意:必須檢查黑白圖像矩陣的尺寸。大多數(shù)情況下,即使是黑白,也有RGB尺寸。這可能會導(dǎo)致在OpenCV的某些函數(shù)中出現(xiàn)尺寸錯誤。
侵蝕和膨脹功能也可以用來消除圖像格式文本的干擾。
kernel = np.ones((3,3),np.uint8)
output2 = cv2.dilate(gray_image,kernel,iterations = 3)
plt.imshow(output2)
plt.show()
圖17.膨脹函數(shù)產(chǎn)生的圖像
當(dāng)查看圖14中的文本時,將看到存在一些點形噪聲。可以看出,使用圖17中的膨脹函數(shù)可以大大消除這些噪聲??梢酝ㄟ^更改創(chuàng)建的濾波器和迭代參數(shù)值來更改制品的稀疏率。必須正確確定這些值,以保持文本的可讀性。與擴張功能相反,侵蝕功能使文本變粗。
kernel = np.ones((3,3),np.uint8)
output2 = cv2.erode(gray_image,kernel,iterations = 3)
plt.imshow(output2)
plt.show()
圖18.侵蝕功能產(chǎn)生的圖像
如圖18所示,使用Erode功能可以增加字體的粗細。這是一種通常用來提高用精細字體書寫的文章質(zhì)量的方法。這里要注意的另一點是,我們的文章為黑色,背景為白色。如果背景為黑色,文本為白色,則將取代這些功能的過程。
OpenCV用于提高某些圖像的質(zhì)量。例如對比度差的圖像的直方圖值分布在狹窄的區(qū)域。
為了提高該圖像的對比度,有必要將直方圖值分布在很大的區(qū)域上。equalizeHist函數(shù)用于這些操作。讓我們對圖19中的圖像進行直方圖均衡。
圖19.直方圖值未修改的圖像(原始圖像)
圖20.原始圖像的直方圖分布
原始圖像的直方圖(圖19)可以在圖20中看到。
圖像中對象的可見性很低。
equ = cv2.equalizeHist(gray_image)
plt.imshow(equ)
圖21.直方圖均衡圖像
圖22.直方圖均衡圖像的直方圖分布
直方圖由equalizeHist函數(shù)均衡的圖像如圖21所示。圖像的質(zhì)量和清晰度得到了提高。此外,在圖22中完成了直方圖均衡化的圖像的直方圖圖形可以看出,在直方圖均衡化之后,圖20中一個區(qū)域中收集的值分布在更大的區(qū)域上。可以為每個圖像檢查這些直方圖值。必要時可以通過使直方圖相等來提高圖像質(zhì)量。
參考文獻
[1]P.Erbao, Z.Guotong, “Image Processing Technology Research of On-Line Thread Processing”, 2012 International Conference on Future Electrical Power and Energy System, April 2012.
[2]H.Singh, Practical Machine Learning and Image Processing, pp.63–88, January 2019.
[3]R.H.Moss, S.E.Watkins, T.Jones, D.Apel, “Image thresholding in the high resolution target movement monitor”, Proceedings of SPIE — The International Society for Optical Engineering, March 2009.
[4]Y.Xu, L.Zhang, “Research on Lane Detection Technology Based on OPENCV”, Conference: 2015 3rd International Conference on Mechanical Engineering and Intelligent Systems, January 2015.
交流群
聯(lián)系客服