一.opencv-python簡述
其使用Numpy,所有OpenCV數組結構都轉換為Numpy數組,是一個高度優化的數據庫操作庫。
二.環境安裝
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python
三.基本概念
- 像素是圖像的基本單元,每個像素存儲著圖像的顏色、亮度和其他特征。
- 數字圖像利用0/1編碼記錄信息,opencv中常用的是8位圖像,大多數彩色和灰度圖像使用8位(uint8)表示每個通道的像素值,范圍從0到255,其中?0?最黑,1(255)?最白。
- 幾乎所有顏色都可以通過RGB三原色按照不同比例調配而成。
四.圖像存儲
- 彩色圖像:三維數組
- 灰度圖像:二維數組(矩陣)
- 在OpenCV中,默認情況下,彩色圖像是以BGR(藍-綠-紅)順序存儲
- 形狀(Shape):
圖像的尺寸由其高(h)、寬(w)和通道數(c)決定。可以通過 img.shape 屬性獲取(h,w,c)。
? - 彩色圖像,返回一個包含三個值的元組 (height, width, channels)。
? - 灰度圖像,返回一個包含兩個值的元組 (height, width),因為其只有一個通道。
- 數據類型(dtype):圖像中的每個像素值的數據類型決定了可以存儲的最大值。例如,8位無符號整數(uint8)允許的范圍是從0到255。
? - 單通道(灰度圖像):每個像素由一個數值表示,代表該點的亮度。值越低越暗,值越高越亮。
五.圖像基本操作
5.1 創建窗體(窗口)
cv2.namedWindow(winname ?[,窗口屬性])
參數:
- winname:窗口名
- 窗口屬性:窗口大小是否可調整
? ? - cv2.WINDOW_AUTOSIZE :默認,窗口會根據加載的圖像自動調整到合適的大小,并且用戶不能拖動窗口邊緣來調整窗口大小。
? ? - cv2.WINDOW_NORMAL :窗口大小是可調整的,用戶可以通過鼠標拖動窗口邊緣來自由改變窗口大小。
import cv2 as cv
import numpy as np# 創建窗體
cv.namedWindow("win1",cv.WINDOW_AUTOSIZE)
cv.imshow("win2",cv.WINDOW_NORMAL)
運行后會出現兩塊窗口,暫時不管。
5.2 讀取圖像
cv2.imread(path ?[,讀取方式])
? 參數:
? - filename:圖像路徑
? - 讀取方式:彩色·默認、灰色等
# 讀取方式為灰色
img = cv.imread("../images/cat1.png", cv.IMREAD_GRAYSCALE)
繼續往下
5.3 圖像顯示
cv2.imshow(winname,img)
參數:
- winname:顯示圖像的窗口名,以字符串類型表示
- img:要顯示的圖像
cv.imshow("win1",img)
cv.imshow("win2",img)# cv.waitKey(n):n>0,意味著程序將等待n毫秒。
cv.waitKey(0)# cv2.destroyAllWindows(winname):會在當前程序執行到該語句時立即銷毀打開的窗口,并釋放與這些窗口相關的資源。
# 默認關閉所有
cv.destroyAllWindows()
5.4 保存圖像
cv2.imwrite(path,img)
參數:
- path:圖片保存的路徑和圖片名
- img:要保存的圖像
cv.imwrite('output.jpg', img)
5.5 創建黑色圖像
使用 np.zeros() 創建全黑圖像,再修改像素值(255)成為全白圖像。
numpy.zeros((height,width,channels),dtype=np. uint8)
import cv2 as cv
import numpy as npw = 480
h = 640# c = 1 的時候就是灰度圖像,單通道,但是為二維圖像
c = 3b = np.zeros((h,w,c),dtype=np.uint8)
cv.imshow("black",b)cv.waitKey(0)
cv.destroyAllWindows()
# 更改為白色圖像
# 利用數組切片更改值
b[:,:,:] = 255cv.imshow('white',b)
cv.waitKey(0)
cv.destroyAllWindows()
# 隨機像素值圖像b[:,:,:] = np.random.randint(0,256,(h,w,c))cv.imshow('random',b)
cv.waitKey(0)
cv.destroyAllWindows()
5.6 圖像裁剪(切片)
img[y:y+h,x:x+w]
提取的是從 (x,y) 開始,高度為 h,寬度為 w 的矩形區域
import cv2 as cv
import numpy as npf = cv.imread('../images/cat1.png')y = 200
x = 200
h = 400
w = 400s = f[y:y+h,x:x+w]
cv.imshow('s',s)
cv.waitKey(0)
cv.destroyAllWindows()
5.7 調整大小
cv2.resize(img,dsize,dts)
- img:輸入圖像,通常是二維或三位NumPy數組。
- dsize:輸出圖像的尺寸,是一個二元組 (w,h)
- dst:縮放后的圖像
import cv2 as cv
import numpy as np
f = cv.imread('../images/cat1.png')s = cv.resize(f, (100,100))
cv.imshow('s', s)
cv.waitKey(0)
cv.destroyAllWindows()
六.圖像繪制
6.1 直線
cv2.line(img,start,end,color,thickness)
參數:
? - img:要繪制直線的圖像
? - start、end:直線的起點和終點,都是兩個元組(坐標)
? - color:直線的顏色,對于彩色圖像,使用 BGR 格式(b,g,r)指定顏色
? - thickness:線條粗細,值越大越寬
? - 隱藏參數,cv2.LINE_AA ,表示使用抗鋸齒算法繪制圖像,這在每個繪制函數中都隱式存在,默認為 cv2.LINE_8
import cv2 as cvimg = cv.imread('../images/cat1.png')# 畫一條直線,起點終點分別指定,同時為藍色
cv.line(img,(100,100),(200,200),(255,0,0),3)
cv.imshow('image',img)
cv.waitKey(0)
cv.destroyAllWindows()
6.2 圓形
cv2.circle(img,centerpoint,r,color,thickness)
參數:
? - img:要繪制圓形的圖片
? - centerpoint、r:圓心和半徑
? - color:線條顏色
? - tnickness:線條寬度,為-1時生成閉合圖案并填充顏色
import cv2 as cvimg = cv.imread('../images/cat1.png')cv.circle(img, (100, 100), 50, (255, 0, 0), -1)
cv.imshow('img', img)
cv.waitKey(0)
cv.destroyAllWindows()
6.3 繪制矩形
cv2.rectangle(img,leftupper,rightdown,color,thickness)
參數:
? - img:要繪制矩形的圖像
? - leftupper、rightdown:矩形的左上角和右下角坐標
? - color:線條的顏色
? - thickness:線條的寬度
import cv2 as cvimg = cv.imread('../images/cat1.png')cv.rectangle(img, (100, 100), (300, 300), (0, 255, 0), 2)
cv.imshow('img', img)
cv.waitKey(0)
cv.destroyAllWindows()
6.4 繪制文本(向圖片中添加文字)
cv2.putText(img,text,station,font,Fontscale,color,thickness,cv2.LINE_AA)
參數:
? - img:要添加文字的圖像
? - text:要寫入的文本數據(此處是不能加中文的,會顯示問號(?),matplotlib可以顯示中文)
? - station:文本的放置位置
? - font:字體樣式
? - Fontscale:字體大小
? - thickness:字體線條寬度
? - cv2.LINE_AA?:使用反走樣技術繪制文本邊框
import cv2 as cvimg = cv.imread('../images/cat1.png')cv.putText(img, 'Hello World', (50, 50), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
cv.imshow('Image', img)
cv.waitKey(0)
cv.destroyAllWindows()
6.5 讀取視頻
cap = cv2.VideoCapture(path)
- path?: 為0代表從默認攝像頭捕獲視頻流
ret,frame = cap.read()
- 得到一個布爾值和一幀圖像,布爾值表示是否成功讀取到幀,如果為False,可能是因為視頻結束或讀取失敗,如果為True,frame則是當前幀的圖像數據。
import cv2 as cv# 本地視頻
cap = cv.VideoCapture('../video/arknights_run.mp4')# 循環獲取視頻每一幀
while True:ret, frame = cap.read()# 考慮視頻最后一幀為空,跳出循環if not ret:breakcv.imshow('frame', frame)# 0xFF把鍵盤敲入的鍵轉換為ASCII碼if cv.waitKey(40) & 0xFF == ord('q'):breakcap.release()
cv.destroyAllWindows()
# 獲取攝像頭
cap = cv.VideoCapture(0)
while True:# 讀取攝像頭ret, frame = cap.read()# 顯示cv.imshow('frame', frame)# 按q鍵退出if cv.waitKey(1) & 0xFF == ord('q'):break
# 釋放攝像頭
cap.release()
# 釋放窗口
cv.destroyAllWindows()