一、計算機眼中的圖像
像素
????????像素是圖像的基本單元,每個像素存儲著圖像的顏色、亮度和其他特征。一系列像素組合到一起就形成 了完整的圖像,在計算機中,圖像以像素的形式存在并采用二進制格式進行存儲。根據圖像的顏色不 同,每個像素可以用不同的二進制數表示。
????????日常生活中常見的圖像是RGB三原色圖。RGB圖上的每個點都是由紅(R)、綠(G)、藍(B)三個顏 色按照一定比例混合而成的,幾乎所有顏色都可以通過這三種顏色按照不同比例調配而成。在計算機 中,RGB三種顏色被稱為RGB三通道,根據這三個通道存儲的像素值,來對應不同的顏色。例如,在使 用“畫圖”軟件進行自定義調色時,其數值單位就是像素。
二、RGB顏色
三、計算機中圖像的存儲
????????在計算機中,圖像都是以數組的形式存在的。一個RGB圖像放到內存中就是一個 三維數組,其中第一維表示圖像的寬度,第二維表示圖像的高度,第三維則是圖 像中每一個像素點的RGB三個像素值,但是在OpenCV中像素值的存儲順序是 BGR而不是RGB。
計算機處理圖像本質上就是對三維數組中的像素值進行操作。
四、opencv安裝
pip install opencv-python
官方網址
OpenCV - Open Computer Vision Library
五、圖形繪畫
????????主要功能是生成一個700x700的圖像,其上繪制了網格線和交叉的紅色方塊,并分別提取了該圖像的RGB通道。最后,使用Matplotlib庫顯示了整個圖像和各個分離的通道。
5.1、導入模塊
import cv2 # 導入OpenCV庫,用于圖像處理
import numpy as np # 導入NumPy庫,用于數組和矩陣操作
from matplotlib import pyplot as plt # 導入Matplotlib庫,用于繪圖
5.2、創建圖像
創建一個空白的 700x700 彩色圖像
# 創建一個700x700的黑色圖像,包含三個顏色通道(RGB)
image = np.zeros((700, 700, 3), dtype=np.uint8)
5.3、為圖像添加色彩
# 使用雙層循環在圖像上繪制網格和交叉的紅色方塊
for i in range(0, 700, 100): # 外層循環,步長為100,從0到600 for j in range(0, 700, 100): # 內層循環,同樣步長為100 # 繪制水平網格線 image[i, :, :] = (255, 255, 255) # 將第i行的所有像素設為白色 # 繪制垂直網格線 image[:, j, :] = (255, 255, 255) # 將第j列的所有像素設為白色 # 繪制交叉的紅色方塊 if i != 0 and j != 0 and i != 600 and j != 600 and (i == j or i + j == 600): image[i:i+100, j:j+100, :] = (0, 0, 255) # 將指定區域設為紅色
?另一種方式
for i in range(0, 700, 100):for j in range(0, 700, 100):top_left=(j,i)botton_right=(j+99,i+99)if i!=0 and i!=600 and (i==j or i+j==600):cv2.rectangle(image,top_left,botton_right,(0,0,255),-1)else:cv2.rectangle(image,top_left,botton_right,(255,255,255),1)
5.4、將BGR轉化為RGB
# 將BGR格式的圖像轉換為RGB格式,以便正確顯示
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
5.5、分割RGB通道
# 分離圖像的紅、綠、藍通道
r, g, b = cv2.split(image_rgb)
5.6、對三通道進行操作
# 創建三個單獨的通道圖像,初始為全零(黑色)
blue_channel = np.zeros((700, 700, 3), dtype=np.uint8) # 藍色通道
green_channel = np.zeros((700, 700, 3), dtype=np.uint8) # 綠色通道
red_channel = np.zeros((700, 700, 3), dtype=np.uint8) # 紅色通道 # 將分離出的通道放入對應的通道圖像中
blue_channel[:, :, 0] = b # 將藍色通道的值放入藍色通道圖像的第一個通道
green_channel[:, :, 1] = g # 將綠色通道的值放入綠色通道圖像的第二個通道
red_channel[:, :, 2] = r # 將紅色通道的值放入紅色通道圖像的第三個通道 # 將單獨的通道圖像轉換為RGB格式
blue_channel_rgb = cv2.cvtColor(blue_channel, cv2.COLOR_BGR2RGB)
green_channel_rgb = cv2.cvtColor(green_channel, cv2.COLOR_BGR2RGB)
red_channel_rgb = cv2.cvtColor(red_channel, cv2.COLOR_BGR2RGB)
5.7、通過matplotlib顯示圖像
plt.subplot(232) # 在2行3列的網格中,放置第2個子圖(1-indexed)
plt.imshow(image_rgb) # 顯示原始的RGB圖像
plt.axis('off') # 關閉坐標軸 plt.subplot(234) # 在2行3列的網格中,放置第4個子圖
plt.imshow(blue_channel_rgb) # 顯示藍色通道圖像
plt.axis('off') # 關閉坐標軸 plt.subplot(235) # 在2行3列的網格中,放置第5個子圖
plt.imshow(green_channel_rgb) # 顯示綠色通道圖像
plt.axis('off') # 關閉坐標軸 plt.subplot(236) # 在2行3列的網格中,放置第6個子圖
plt.imshow(red_channel_rgb) # 顯示紅色通道圖像
plt.axis('off') # 關閉坐標軸 plt.tight_layout() # 自動調整子圖參數,以便給子圖留出更合適的空間
plt.show() # 顯示所有繪制的圖像
5.8、通過cv顯示圖像
cv2.imshow('image_rgb', image) cv2.waitKey(0) # 等待用戶按鍵
5.9、完整代碼?
import cv2 # 導入OpenCV庫,用于圖像處理
import numpy as np # 導入NumPy庫,用于數組和矩陣操作
from matplotlib import pyplot as plt # 導入Matplotlib庫,用于繪圖 # 創建一個700x700的黑色圖像,包含三個顏色通道(RGB)
image = np.zeros((700, 700, 3), dtype=np.uint8) # 使用雙層循環在圖像上繪制網格和交叉的紅色方塊
for i in range(0, 700, 100): # 外層循環,步長為100,從0到600 for j in range(0, 700, 100): # 內層循環,同樣步長為100 # 繪制水平網格線 image[i, :, :] = (255, 255, 255) # 將第i行的所有像素設為白色 # 繪制垂直網格線 image[:, j, :] = (255, 255, 255) # 將第j列的所有像素設為白色 # 繪制交叉的紅色方塊 if i != 0 and j != 0 and i != 600 and j != 600 and (i == j or i + j == 600): image[i:i+100, j:j+100, :] = (0, 0, 255) # 將指定區域設為紅色 # 將BGR格式的圖像轉換為RGB格式,以便正確顯示
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 分離圖像的紅、綠、藍通道
r, g, b = cv2.split(image_rgb) # 創建三個單獨的通道圖像,初始為全零(黑色)
blue_channel = np.zeros((700, 700, 3), dtype=np.uint8) # 藍色通道
green_channel = np.zeros((700, 700, 3), dtype=np.uint8) # 綠色通道
red_channel = np.zeros((700, 700, 3), dtype=np.uint8) # 紅色通道 # 將分離出的通道放入對應的通道圖像中
blue_channel[:, :, 0] = b # 將藍色通道的值放入藍色通道圖像的第一個通道
green_channel[:, :, 1] = g # 將綠色通道的值放入綠色通道圖像的第二個通道
red_channel[:, :, 2] = r # 將紅色通道的值放入紅色通道圖像的第三個通道 # 將單獨的通道圖像轉換為RGB格式
blue_channel_rgb = cv2.cvtColor(blue_channel, cv2.COLOR_BGR2RGB)
green_channel_rgb = cv2.cvtColor(green_channel, cv2.COLOR_BGR2RGB)
red_channel_rgb = cv2.cvtColor(red_channel, cv2.COLOR_BGR2RGB) # 使用Matplotlib繪制圖像
plt.subplot(232) # 在2行3列的網格中,放置第2個子圖(1-indexed)
plt.imshow(image_rgb) # 顯示原始的RGB圖像
plt.axis('off') # 關閉坐標軸 plt.subplot(234) # 在2行3列的網格中,放置第4個子圖
plt.imshow(blue_channel_rgb) # 顯示藍色通道圖像
plt.axis('off') # 關閉坐標軸 plt.subplot(235) # 在2行3列的網格中,放置第5個子圖
plt.imshow(green_channel_rgb) # 顯示綠色通道圖像
plt.axis('off') # 關閉坐標軸 plt.subplot(236) # 在2行3列的網格中,放置第6個子圖
plt.imshow(red_channel_rgb) # 顯示紅色通道圖像
plt.axis('off') # 關閉坐標軸 plt.tight_layout() # 自動調整子圖參數,以便給子圖留出更合適的空間
plt.show() # 顯示所有繪制的圖像 # 使用OpenCV顯示原始圖像(BGR格式)
cv2.imshow('image_rgb', image) cv2.waitKey(0) # 等待用戶按鍵
六、庫函數
6.1、cvtColor()
????????將圖像從一個色彩空間轉換為另一個色彩空間。
????????該函數將輸入圖像從一個色彩空間轉換為另一個色彩空間。在從 RGB 色彩空間轉換的情況下,應明確指定通道的順序(RGB 或 BGR)。請注意,OpenCV 中的默認顏色格式通常稱為 RGB,但實際上是 BGR(字節是相反的)。因此,標準 (24 位) 彩色圖像中的第一個字節將是 8 位藍色分量,第二個字節將是綠色,第三個字節將是紅色。然后,第 4 個、第 5 個和第 6 個字節將是第二個像素(藍色、綠色、紅色),依此類推。
R、G 和 B 通道值的常規范圍為:
- 0 到 255 表示CV_8U圖像
- 0 到 65535(CV_16U圖像
- 0 到 1 表示CV_32F圖像
cv.cvtColor( src, code[, dst[, dstCn[, hint]]] ) -> dst
函數 | 描述 |
---|---|
src | 輸入圖像:8 位無符號、16 位無符號 ( CV_16UC... ) 或單精度浮點。 |
dst | 輸出圖像的大小和深度與 src 相同。 |
code | 色彩空間轉換代碼 |
dstCn | 目標圖像中的通道數;如果參數為 0,則 Channels 的數量會自動從 src 和 code 中得出。 |
hint | 實現修改標志 |
6.2、?拆分和合并圖像通道
????????有時,您需要單獨處理圖像的 B、G、R 通道。在這種情況下,您需要將 BGR 圖像拆分為單個通道。在其他情況下,您可能需要加入這些單獨的通道以創建 BGR 圖像。您可以簡單地通過以下方式執行此作:
>>> b,g,r = cv.split(img)
>>> img = cv.merge((b,g,r))
假設您要將所有紅色像素設置為零 - 您無需先拆分通道。Numpy 索引更快:
>>> img[:,:,2] = 0
?6.3、imshow()
????????在指定窗口中顯示圖像。
????????函數 imshow 在指定窗口中顯示圖像。如果窗口是使用?cv::WINDOW_AUTOSIZE?標志創建的,則圖像將以其原始大小顯示,但它仍受屏幕分辨率的限制。否則,將縮放圖像以適合窗口。
cv.imshow( winname, mat ) -> None
函數 | 描述 |
---|---|
winname | 窗口的名稱 |
mat | 要顯示的圖像。 |
注意
此函數后應調用?cv::waitKey?或?cv::p ollKey?來執行 GUI 內務處理任務,這些任務是實際顯示給定圖像并使窗口響應鼠標和鍵盤事件所必需的。否則,它不會顯示圖像,并且窗口可能會鎖定。例如,waitKey(0)?將無限顯示窗口,直到任意一個鍵(適合圖像顯示)。waitKey(25)?將顯示一個幀,并等待大約 25 ms 的按鍵作(適用于逐幀顯示視頻)。要刪除窗口,請使用?cv::d estroyWindow。
[僅限 Windows 后端]按 Ctrl+C 會將圖像復制到剪貼板。按 Ctrl+S 將顯示一個對話框以保存圖像。
[僅限 Wayland 后端]支持格式已擴展。
- 如果圖像是 8 位簽名的,則像素將偏移 128。也就是說,值范圍 [-128,127] 映射到 [0,255]。
- 如果圖像是 16 位簽名的,則像素將除以 256 并偏移 128。也就是說,值范圍 [-32768,32767] 映射到 [0,255]。
6.4、waitKey()
????????等待按下的鍵。
????????函數 waitKey 無限等待 key 事件(當delay < 0)或 delay 毫秒數(當它為正數時)。由于作系統在切換線程之間有最短時間,因此該函數不會完全等待延遲毫秒,它至少會等待延遲毫秒,具體取決于當時計算機上正在運行的其他內容。它返回所按下的鍵的代碼,如果在指定時間過去之前沒有按下任何鍵則返回 -1。要檢查是否按下了某個鍵但不等待它,請使用 polKey。
cv.waitKey([, delay]) ->retval
函數 | 描述 |
---|---|
delay | 延遲(以毫秒為單位)。0 是表示 “永遠” 的特殊值。 |
注意
函數?waitKey?和?pollKey?是 HighGUI 中唯一可以獲取和處理 GUI 事件的方法,因此需要定期調用其中一個函數以進行正常的事件處理,除非在負責事件處理的環境中使用 HighGUI。
僅當至少創建了一個 HighGUI 窗口并且該窗口處于活動狀態時,該功能才有效。如果有多個 HighGUI 窗口,則其中任何一個窗口都可以處于活動狀態。
6.5、rectangle()
cv.rectangle( img, pt1, pt2, color[, thickness[, lineType[, shift]]] ) -> img
cv.rectangle( img, rec, color[, thickness[, lineType[, shift]]] ) -> img
函數 | 描述 |
---|---|
img | 圖像。 |
pt1 | 矩形的頂點。 |
pt2 | 與 pt1 相對的矩形的頂點。 |
color | 矩形顏色或亮度(灰度圖像)。 |
thickness | 構成矩形的線條的粗細。負值(如?FILLED)表示函數必須繪制填充矩形 |
lineType | 線路的類型。 |
shift | 點坐標中的小數位數。 |