python圖像處理入門:opencv圖像機器學習
本章介紹圖像的基本概念和基本操作。 我們將首先提供像素等圖像基礎知識的清晰定義。 接下來,我們將深入講解如何使用 OpenCV 庫讀取、顯示和保存圖像。 然后我們將繼續使用 OpenCV 在圖像上繪制形狀的實際任務,重點是矩形、圓形和其他基本形狀等主題。
1. 圖像和像素簡介
什么是圖像? 用非技術術語來說,圖像是指場景、物體或人的視覺表示,它使我們能夠更好地理解周圍的世界。在數字環境中,圖像是像素的多維陣列。
像素是圖像的構建塊。 像素是數字圖像的最小單位,包含有關其顏色和位置的信息。 當多個像素在二維網格中聚集在一起時,它們就形成了完整的圖像。 數字圖像中的像素以網格圖案排列以創建整體圖像。 每個像素都包含特定的顏色信息,它們一起形成完整的圖像。
像素通常用于表示灰度或彩色圖像。 灰度圖像通常表示為二維像素網格,而彩色圖像通常表示為多維矩陣。 在灰度圖像中,每個像素都分配有0 到 255 之間的值,表示該點圖像的強度。 值 0 表示沒有強度,導致黑色像素,而值255表示最大強度,導致純白色像素。
在彩色圖像中,每個像素由三個或四個值的組合表示,最常見的顏色空間是 RGB 顏色空間。 在此空間中,使用表示紅色、綠色和藍色通道強度的三個值來表示單個像素。 每個值的范圍從 0 到 255,表示像素中存在的每種顏色的數量。 典型的 RGB 像素可以用(紅、綠、藍)格式表示。
例如,具有 (0,0,0) 值的顏色表示黑色,因為所有顏色的強度均為 0,而 (255,255,255) 表示白色圖像,因為所有顏色都有最大值。
讓我們看幾個關于如何在 RGB 顏色空間中表示顏色的示例:
-
(255,0,0) 產生純紅色,因為紅色處于最大值,而綠色和藍色處于 0。
-
(0,255,0) 產生純綠色。
-
(0,0,255) 產生純藍色。
-
(255,255,0) 產生黃色,因為它是紅色和綠色的組合。
-
(128,128,128) 代表灰色。
PPI(即每英寸像素 Pixels per Inch)表示單英寸數字圖像中存在的像素數。 較高的 PPI 意味著每英寸有更多的像素,從而產生更平滑、更細致的圖像。 相反,較低的 PPI 意味著像素較大且每英寸的像素較少,從而導致圖像細節較少且清晰度較差。
分辨率是一個術語,用于描述構成圖像的像素總數。 分辨率越高,像素越多,從而產生更詳細和高質量的圖像。 分辨率通常以每英寸像素 (PPI) 或每英寸點數 (DPI) 來衡量。 當圖像的分辨率較低時,意味著像素較少,因此圖像的細節較少。
長寬比是指圖像的寬度和高度之間的比例關系,它決定了圖像的整體形狀。 它通常表示為用冒號分隔的兩個數字(例如 4:3 或 16:9),表示圖像或屏幕的寬度和高度。 例如,縱橫比為 4:3 的圖像的寬度為每3 個單位的高度對應 4 個單位的長度。 寬高比用于確保在不同設備上顯示圖像時圖像正確適合顯示尺寸。
數字圖像的像素數量一直在迅速增加。 第一臺商用數碼相機 Dycam Model 1 的分辨率僅為 0.01兆像素,而當今的高端相機可以捕獲分辨率為 100兆像素或更高的圖像。
2. 加載和顯示圖像
是時候開始處理圖像了! 在本書中,當我們引導您完成探索和操作圖像的過程時,您將獲得實踐經驗。 在我們繼續前進時,請務必自行實現代碼示例,因為這將有助于鞏固您對我們將要介紹的概念的理解。
2.1 Imread()
要開始使用OpenCV處理圖像,我們需要使用imread() 函數。通過該函數,我們可以將圖像加載到我們的程序中:
cv2.imread(path, flag=cv2.IMREAD_COLOR)
參數:
-
path: 字符串,表示要讀取圖像的路徑。
-
flag: 可選參數, 指定讀取圖像的方式。
cv2.IMREAD_COLOR (1): 以 BGR 格式加載圖像。這是該函數的默認格式。
cv2.IMREAD_GRAYSCALE (0):以灰度格式加載圖像: 以灰度格式加載圖像。
cv2.IMREAD_UNCHANGED (-1):以原始格式加載圖像: 以原始格式加載圖像,通常用于包含 alpha 通道。
cv2.imread(path, 0)
這將以灰度格式加載圖像。
2.2 imshow
cv2.imshow(winname, mat)
參數:
-
Winname:顯示圖像的窗口名稱。
-
Mat: 表示我們要顯示的圖像的 NumPy 數組。
2.3 imwrite
Imwrite 用于將圖像保存到系統中。
cv2.imwrite(filename, img, params=None)
參數:
-
Filename:表示要保存的圖像路徑的字符串
-
Img: 表示我們要寫入的圖像的NumPy數組。
-
Params: 可選參數,用于指定圖像文件的格式和壓縮參數。默認值為None。
示例代碼
在本練習中,我們將使用之前學習的代碼加載圖像并顯示圖像:
import cv2 # Using imread to read out image img = cv2.imread("../img/dog.jpg") # Print the shape of the image print(img.shape) # Displaying the image cv2.imshow("Dog Image", img) # Wait until a key is pressed cv2.waitKey(0) # Close all Windows cv2.destroyAllWindows()
2.4 WaitKey
WaitKey是OpenCV程序中的一個函數,用于讓用戶在特定時間內或按下某個鍵之前顯示一個窗口。如果沒有 waitKey,圖像或視頻會在用戶來得及觀看之前立即關閉。
它只接受一個整數參數,即窗口保持打開的毫秒數。如果給定的參數為0或根本沒有給定參數,函數將等待按鍵按下后再關閉窗口。
2.5 DestroyAllWindows
DestroyAllWindows是一條簡單的命令,用于關閉OpenCV在執行代碼期間打開的所有窗口。該命令不需要任何參數。
我們已經成功運行了第一段 OpenCV 代碼,現在可以讀取并顯示圖像了。
試試看 現在嘗試以不同的路徑將前面的圖像寫入光盤。
3 用像素操作圖像
圖像在 Python 中存儲為 NumPy 數組,這意味著圖像元素可以像 NumPy 數組一樣被索引。通過圖像索引,我們可以操作圖像中的單個像素或某個像素區域。
3.1 訪問單個像素
要訪問圖像中的某個像素,我們可以使用類似的 img[row, col] 索引。使用此方法訪問像素值將返回一個包含像素值的 NumPy 數組:
import cv2 # Load an image in grayscale mode img = cv2.imread('../img/dog.jpg') # Get the pixel value at x=75, y=25 pixel_value = img[25, 75] #Print this value print(pixel_value) #Manipulate value of this pixel img[25, 75] = 0 #Rechecking value print(pixel_value)
結果:
[120 165 222] [0 0 0]
對于RGB圖像,前面的代碼行將返回包含三個值的數組,而對于灰度圖像,它將只返回值,例如30。
我們還可以使用索引修改像素值。我們可以為某個像素賦值,如下所示:
img[5,7] = 255
如果img是灰度圖像,這將為像素賦值255。如果圖像img是BGR 格式,那么三個顏色通道的值都將設置為 255。
如果我們想在 RGB 圖像中設置特定值,可以使用該特定顏色的顏色代碼:
img[5,7] = [0,255,0]
這將把綠色通道值設置為 255,其他兩個通道設置為 0,從而得到純綠色像素。
3.2 訪問感興趣區域 (ROI Region of Interest)
現在,我們將討論如何通過使用索引定義感興趣區域 (ROI) 來操作圖像的整個區域。我們經常需要操作圖像的特定區域,而不是單個像素或整個圖像。
import cv2 # Load image img = cv2.imread('../img/dog.jpg') # Define index values x=50 y=60 w=75 h=75 # Extract ROI from the image roi = img[y:y+h,x:x+w] # Print shape of the extracted ROI print(roi.shape) # Assigning a colour to a different ROI img[100:150,150:200] = (255,255,0) cv2.imshow('Extracted ROI rectangle', roi) cv2.imshow('Image with ROI colour', img) cv2.waitKey(0) cv2.destroyAllWindows()
3.3 在OpenCV中繪圖
在本節中,我們將學習如何使用 OpenCV 繪制形狀。我們可以使用 OpenCV 設計各種形狀,包括線、圓、矩形和多邊形,還可以自定義它們的大小和顏色。使用 OpenCV 還可以在照片上添加文字。形狀有多種用途,包括注釋照片和強調照片的特定區域。
首先,我們將創建一張空白畫布,在上面繪制各種形狀。或者,也可以加載一張圖片,然后在上面繪制形狀。
為了創建繪制形狀的畫布,我們可以使用 NumPy 創建一個 NumPy 數組。然后,我們可以使用各種方法在 NumPy 畫布上繪圖:
canvas = np.zeros((600, 600, 3), dtype=np.uint8)
我們使用 np.zeros 函數創建畫布。這是一個 NumPy 函數,用于創建一個具有特定形狀和數據類型的 NumPy 數組。在本例中,我們創建了一個具有 "np.uint8 "數據類型的形狀數組(600,600,3)。該數據類型對應于 8 位無符號整數,取值范圍為 0 至 255。
3.4 線條(Line)
我們使用 cv2.line 命令在圖像上創建線條。該命令提供多個參數,讓我們可以自定義線條,以滿足我們的特定需求和要求。
參數:
-
Img: 繪制線條的圖像。
-
Pt1:線條的起始坐標: 線條的起始坐標。格式為 tuple (x,y)。
-
Pt2: 線條的終點坐標。格式為 tuple (x,y)。
-
Color:線條的顏色。采用元組(B、G、R)格式。
-
厚度(Thickness): 線條的厚度(像素)。這是一個可選參數,默認值為 1。
-
lineType(線條類型 線條的類型。我們將不使用此參數,可將其保留為默認值。
-
Shift(移位): 線條坐標中的小數位數。我們將不使用此參數,默認值為 0。
cv2.line(img, pt1, pt2, color, thickness=1, lineType = cv2.LINE_8, shift = 0)
實例:
import numpy as np import cv2 # Create a black canvas canvas = np.zeros((600, 500, 3), dtype=np.uint8) # Define the vertices of the triangle p1 = (250, 100) p2 = (100, 400) p3 = (400, 400) # Draw the lines using cv2.line() cv2.line(canvas, p1, p2, (0, 255, 0), 1) cv2.line(canvas, p3, p1, (255, 0, 0), 3) cv2.line(canvas, p2, p3, (255, 255, 255), 10) # Display the image cv2.imshow("Triangle", canvas) cv2.waitKey(0) cv2.destroyAllWindows()
參考資料
軟件測試精品書籍文檔下載持續更新 https://github.com/china-testing/python-testing-examples 請點贊,謝謝!
本文涉及的python測試開發庫 謝謝點贊! https://github.com/china-testing/python_cn_resouce
python精品書籍下載 https://github.com/china-testing/python_cn_resouce/blob/main/python_good_books.md
Linux精品書籍下載 https://www.cnblogs.com/testing-/p/17438558.html
3.5 矩形(rectangle)
在 OpenCV 中,繪制矩形與繪制直線類似。我們可以使用 cv2.rectangle 命令在 OpenCV 中創建矩形:
Cv2.rectangle(img, pt1, pt2, color, thickness=1, lineType=cv2.LINE_8, shift=0)
參數:
-
Img: 繪制的圖像。
-
Pt1:矩形的左上角點: 矩形的左上角點。格式為 tuple (x,y)。
-
Pt2: 矩形的右下角點: 矩形的右下角點。格式為 tuple (x,y)。
-
Color:矩形的顏色將采用元組(B、G、R)格式。
-
厚度(Thickness): 以像素為單位的矩形邊框厚度。這是一個可選參數,默認值為 1。如果矩形的厚度為負值,則會填充矩形。
-
lineType:線條類型: 線條的類型。我們將不使用此參數,因此可將其保留為默認值。
-
Shift(移位): 線條坐標中的小數位數。我們將不使用該參數,默認值為 0。
現在,根據前面的解釋,讓我們嘗試創建這幅圖像:
import numpy as np import cv2 # Create a black image img = np.zeros((600, 500, 3), dtype=np.uint8) # Draw the figure using rectangles and lines # Face cv2.rectangle(img, (150, 150), (350, 400), (242, 199, 155), thickness=-1) # Cap cv2.rectangle(img, (100, 50), (400, 150), (198, 131, 56), thickness=-1) # Mouth cv2.rectangle(img, (200, 310), (300, 330), (128, 0, 128), thickness=2) # Draw the eyes on the face as X shapes cv2.line(img, (195, 200), (212, 228), (0, 0, 0), thickness=2) cv2.line(img, (212, 200), (195, 228), (0, 0, 0), thickness=2) cv2.line(img, (288, 200), (305, 228), (0, 0, 0), thickness=2) cv2.line(img, (305, 200), (288, 228), (0, 0, 0), thickness=2) # Display the image cv2.imshow('Robo', img) cv2.waitKey(0) cv2.destroyAllWindows()
3.6 circle
cv2.circle() 函數用于在圖像上繪制圓形:
cv2.circle(img, center, radius, color, thickness=1, lineType = cv2.LINE_8, shift=0)
參數
-
Img: 繪制的圖像。
-
Center: 圓的中心點。格式為 tuple (x,y)。
-
Radius: 圓的半徑
-
Color:圓的顏色。格式為元組(B、G、R)。
-
Thickness: 圓邊框的厚度,以像素為單位: 圓邊框的厚度,單位為像素。這是一個可選參數,默認值為 1。如果矩形的厚度為負值,它將填充圓。
-
lineType:線條類型: 線條的類型。我們將不使用此參數,因此可將其保留為默認值。
-
Shift(移位): 線條坐標中的小數位數。我們將不使用此參數,默認值為 0。
讓我們嘗試自己創建幾個圓:
import numpy as np import cv2 # Create an empty canvas canvas = np.zeros((500, 500, 3), dtype=np.uint8) # Define the center point center = (250, 250) # Define the radii of the circles radius1 = 50 radius2 = 100 radius3 = 150 # Define the colors of the circles color1 = (0, 0, 255) color2 = (255, 0, 0) color3 = (0, 255, 0) # Define the thickness of the circles thickness1 = -1 thickness2 = 2 thickness3 = 10 # Draw the circles on the canvas cv2.circle(canvas, center, radius1, color1, thickness1) cv2.circle(canvas, center, radius2, color2, thickness2) cv2.circle(canvas, center, radius3, color3, thickness3) # Display the image cv2.imshow("Image", canvas) cv2.waitKey(0) cv2.destroyAllWindows()
3.7 文本(Text)
我們使用函數 cv2.putText() 為圖像添加文本:
cv2.putText(img, text, org, fontFace=’cv2.FONT_HERSHEY_SIMPLEX’, fontScale=0, color=(0,0,0), thickness=1, lineType=’cv2.LINE_AA’, bottomLeftOrigin=False)
參數:
-
Img: 繪制的圖像。
-
Text:文本: 要繪制的文本字符串。
-
org:文本左下角的坐標: 文本左下角的坐標。
-
fontFace:文本的字體類型。這是可選參數,默認值為 cv2.FONT_HERSHEY_SIMPLEX。
-
fontScale:字體縮放比例: 字體比例系數,乘以特定字體的基本尺寸。這是一個可選參數,默認值為 1。
-
Color(顏色):文本的顏色。將采用元組(B、G、R)格式。這是一個可選參數,默認值為 (0,0,0)。
-
厚度(Thickness): 文本中線條的粗細。這是一個可選參數,默認值為 1。如果粗細為負值,它將填充文本。
-
lineType:線條類型: 線條的類型。我們將不使用此參數,可將其保留為默認值。
-
bottomLeftOrigin: 這是一個標志,用于指示文本的位置。這是一個可選參數,默認值為 "False(假)",這將使文本位于左上角。默認值為 True 時,文本將位于左下角。
import numpy as np import cv2 # create a blank image img = np.zeros((600, 500, 3), dtype=np.uint8) # define the text to be displayed text = "Hello World!" # set the text color and position color = (255, 0, 0) pos = (50, 200) # display the text using cv2.putText() cv2.putText(img, text, pos, cv2.FONT_HERSHEY_SIMPLEX, 2, color, 3) cv2.imshow("Image with text", img) cv2.waitKey(0) cv2.destroyAllWindows()
4. 總結
本章扎實地介紹了圖像的基本概念和基本操作。我們定義了像素等關鍵概念,并講解了如何使用 OpenCV 庫讀取、顯示和保存圖像。此外,我們還探討了在圖像上繪制形狀的實際任務,重點是矩形和圓形等基本形狀。這一基礎對于將來構建更復雜的圖像處理應用程序非常寶貴。