文章目錄
- 前言
- 一、opencv基礎知識
- 1.opencv相關概念
- 1.1背景
- 1.2特點
- 1.3主要功能與應用
- 1.4.opencv-python
- 2.計算機中的圖像概念
- 2.1圖像表示
- 2.2圖像存儲
- 彩色圖像
- 二、opencv基礎操作
- 1.圖像的讀取
- 2.圖像的顯示
- 3.保存圖像
- 4.創建黑白圖及隨機像素彩圖
- 5. 圖像切片(圖片剪裁)
- 6.圖像大小調整
- 7.圖形繪制
- 7.1繪制直線
- 7.2繪制矩形
- 7.3繪制圓形
- 7.4綜合示例
- 8.視頻讀取
- 總結
前言
今天我們將要進入opencv的學習,Python中的opencv利用了numpy的一些框架,所以我們學習opencv之前還要具備numpy的相關知識。
一、opencv基礎知識
1.opencv相關概念
1.1背景
OpenCV(Open Source Computer Vision Library)是一個開源的計算機視覺和圖像處理庫,由 Intel 發起開發,現由 OpenCV.org 維護。它支持多種編程語言,包括 C++、Python 和 Java,并且能在多個平臺(Windows、Linux、macOS、Android 等)運行。
在 Python 中,我們使用 opencv-python 模塊進行開發,擁有強大的圖像處理與視覺識別能力。
1.2特點
功能強大:
算法覆蓋全面,從基礎圖像處理到高級機器學習。
性能優越:
使用 C++ 編寫并具 GPU 加速,適合實時處理
社區活躍:
由基金會維護,文檔齊全,社區支持強,樣例豐富。
1.3主要功能與應用
圖像處理:
濾波、邊緣檢測、形態轉換、角點特征提取(如 Harris、SIFT、ORB)
物體識別與檢測:
面部檢測(Haar 級聯、DNN)、行人檢測、目標跟蹤
機器學習集成:
圖像分類、聚類、對象識別與行為分析等。
攝像頭與視頻處理:
實時視頻流的處理、運動檢測、3D 重建、拼接圖像、立體視覺等
深度學習支持:
支持加載 ONNX、TensorFlow、Caffe 等格式的網絡進行目標檢測、分類等
1.4.opencv-python
OpenCV-Python
是原始OpenCV C++
實現的Python包裝器。它結合了OpenCV C++ API
的高性能與 Python 語言的易用性和簡潔性。通過 OpenCV-Python,開發者可以輕松地進行圖像處理、計算機視覺任務以及機器學習應用。
與C / C++
等語言相比,Python
速度較慢。Python可以使用C / C++擴展,這使我們可以在C / C++中編寫計算密集型代碼,并創建可用作Python模塊的Python包裝器。
兩個好處: 首先,代碼與原始C / C++代碼一樣快(因為它是在后臺工作的實際C++代碼),其次,在Python中編寫代碼比使用C / C++更容易。
OpenCV-Python
使用Numpy
,這是一個高度優化的數據庫操作庫。所有OpenCV數組結構都轉換為Numpy數組。這也使得其與使用Numpy的其他庫(如SciPy
和Matplotlib
)集成更容易。
安裝opencv-python
在終端里面,可以用pip命令安裝opencv-python
pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple
2.計算機中的圖像概念
2.1圖像表示
像素
是圖像的基本單元
,每個像素存儲著圖像的顏色
、亮度
和其他特征
。一系列像素組合到一起就形成了完整的圖像,在計算機中,圖像以像素的形式存在并采用二進制
格式進行存儲。根據圖像的顏色不同,每個像素可以用不同的二進制數表示。
計算機采用0/1編碼的系統,數字圖像也是利用0/1來記錄信息,我們平常接觸的圖像都是8位數
圖像。opencv中常用的是8位圖像,大多數彩色和灰度圖像使用8位表示每個通道的像素值,范圍從0到255
,其中0代表最黑,255表示最白
。
日常生活中常見的圖像是RGB三原色圖
。RGB圖上的每個點都是由紅(R)、綠(G)、藍(B)
三個顏色按照一定比例混合而成的,幾乎所有顏色都可以通過這三種顏色按照不同比例調配而成。在計算機中,RGB三種顏色被稱為RGB三通道
,每個通道的取值都是0-255,根據這三個通道存儲的像素值,來對應不同的顏色。
2.2圖像存儲
在OpenCV中,無論是讀取還是創建圖像,結果都是一個NumPy數組。
-
彩色圖像:三維數組
-
灰度圖像:二維數組
圖像本質上是像素值的二維或三維矩陣(對于彩色圖像)。
- 形狀(Shape):
- 圖像的尺寸由其高(height)、寬(width)和通道數(channels)決定。可以通過
img.shape
屬性獲取這些信息。 - 對于
彩色
圖像(如RGB),返回的是一個包含三個值
的元組(height, width, channels)
。 - 對于
灰度
圖像,返回的是一個包含兩個值
的元組(height, width)
,因為灰度圖像只有一個通道。
- 圖像的尺寸由其高(height)、寬(width)和通道數(channels)決定。可以通過
- 數據類型(dtype):
- 圖像中的每個像素值的數據類型決定了可以存儲的最大值。例如,8位無符號整數(
np.uint8
)允許的范圍是從0到255。
- 圖像中的每個像素值的數據類型決定了可以存儲的最大值。例如,8位無符號整數(
- 像素表示
- 單通道圖像(灰度圖像):每個像素由一個數值表示,代表該點的亮度。值越低(接近0),顏色越暗;值越高(接近255),顏色越亮。
- 多通道圖像(彩色圖像):
在OpenCV中,默認情況下,彩色圖像是以BGR(藍-綠-紅)順序存儲
彩色圖像
每個像素通常是由紅(R)、綠(G)、藍(B)三個分量來表示的,分量介于(0,255)。RGB圖像每一個像素的顏色值(由RGB三原色表示)直接存放在圖像矩陣中,由于每一像素的顏色需由R、G、B三個分量來表示,M、N分別表示圖像的行列數,三個M x N的二維矩陣分別表示各個像素的R、G、B三個顏色分量。RGB圖像的數據類型一般為8位無符號整形,通常用于表示和存放彩色圖像。
示例
生成一個512*512大小的彩色圖片 每一個像素點隨機顏色
import cv2 as cv
import numpy as np
if __name__ == '__main__':# 生成隨機彩色圖dst = np.random.randint(0,256,(512, 512, 3), dtype=np.uint8)cv.imshow('dst', dst)# 顯示cv.waitKey(0)cv.destroyAllWindows()
二、opencv基礎操作
1.圖像的讀取
基本格式:
cv2.imread(path [,讀取方式])
參數說明:
-
filename:圖像路徑
-
./
表示當前目錄。 -
../
表示當前目錄的上一級目錄(即父目錄)。當你需要引用或訪問當前目錄所在位置的上一層目錄中的文件或文件夾時使用../
-
-
讀取方式:彩色·默認、灰色等
示例
import cv2 as cv
if __name__ == '__main__':# 讀取圖像 cv.imread(path, cv.IMREAD_COLOR) 默認讀為BGR彩色圖像cat = cv.imread('../images/1.jpg')print(cat.dtype) # np.uint8 無符號8位整數print(cat.shape) # (h, w, c)
2.圖像的顯示
基本格式:
cv2.show('winname',img)
參數說明:
-
winname:顯示圖像的窗口名,以字符串類型表示
-
img:要顯示的圖像
-
cv.waitKey(0)
:表示無限期地等待任何鍵盤按鍵。這種用法常見于圖像顯示窗口中,確保圖像在窗口中顯示直到用戶決定關閉它。 -
cv.waitKey(n)
:n>0,意味著程序將等待n毫秒。這種方式常用于視頻播放或實時攝像頭捕獲場景,以便控制每一幀停留的時間,同時允許用戶通過按鍵來中斷循環或發出命令。 -
釋放內存
-
cv2.destroyAllWindows([winname]) # 釋放內存
cv2.destroyAllWindows()
:會在當前程序執行到該語句時立即銷毀打開的窗口,并釋放與這些窗口相關的資源。winname
:窗口名,關閉指定名稱的窗口。可省略,銷毀所有已打開的窗口。
注意: 在調用顯示圖像的API后,要調用
cv2.waitKey(0)
給圖像繪制留下時間,否則窗口會出現無響應情況,并且圖像無法顯示出來。 -
示例
import cv2 as cv
if __name__ == '__main__':cat = cv.imread('../images/1.jpg')# 顯示圖像 cv.imshow(window, img)cv.imshow('myimg', cat) # 無窗體就會自動創建窗口'myimg'cv.waitKey(0) # 給圖像留下繪制時間,等待n毫秒:n毫秒后關閉窗口,0表示一直等待# 釋放資源cv.destroyAllWindows()
3.保存圖像
基本格式:
cv2.imread(path, img)
參數說明:
- path:圖片保存的路徑及圖片名
- 注意加上圖片文件類型后綴(.png / .jpg等)
- img:要保存的圖像
import cv2 as cv
if __name__ == '__main__':cat = cv.imread('../images/1.jpg')cv.write('./cat.jpg',cat)
4.創建黑白圖及隨機像素彩圖
使用numpy
中的np.zeros()
創建黑色圖像
使用numpy
中的np.full()
創建白色圖像
使用numpy
中的np.random.randint()
創建隨機彩圖
示例
import numpy as np
import cv2 as cvif __name__ == '__main__':# 創建黑色圖像height = 360width = 540c = 3black = np.zeros((height, width, c))cv.imshow('black', black)# 使用np.full()創建白色圖像white = np.full((height, width, c), fill_value=255, dtype=np.uint8)cv.imshow('white', white)'''或者black[:] = 255; 或者black[:,:] = 255;或者black[:,:,:] = 255后兩種運用了numpy中的廣播機制'''# 生成隨機彩色圖dst = np.random.randint(0,256,(height, width, c), dtype=np.uint8)cv.imshow('dst', dst)# 顯示cv.waitKey(0)cv.destroyAllWindows()
5. 圖像切片(圖片剪裁)
-
Opencv中,圖像切片用于從圖像中提取一個子區域(矩形區域)。
-
假設你有一個圖像
img
,它的類型是numpy.ndarray
。img[y:y+h,x:x+w]
的含義如下:- x:子區域左上角的x坐標
- y:子區域左上角的y坐標
- w:子區域的寬度
- h:子區域的高度
-
切片操作
img[y:y+h,x:x+w]
提取的是從(x,y)
開始,高度為h
,寬度為w
的矩形區域
-
注意:
- **邊界檢查:**確保
(y,x)
和(y+h,x+w)
都在圖像的邊界內,否則會出現索引越界錯誤。 - 數據類型:
img
通常是numpy.ndarray
類型,切片操作返回的也是numpy.ndarray
類型。
- **邊界檢查:**確保
示例
import cv2 as cvif __name__ == '__main__':# 讀取圖像cat = cv.imread('../images/1.jpg')print(cat.shape)# 切片w,h(289,231)(368,297) 數組中是 h,weye = cat[231:298, 289:369]eye = cv.resize(eye, (500, 500))cv.imshow('eye', eye)cv.waitKey(0)cv.destroyAllWindows()
6.圖像大小調整
cv2.resize
是Opencv庫中用于調整圖像大小的函數,在圖像處理中很常用,特別是在要對圖像進行縮放以適應不同需求時。
基本格式:
cv2.resize(img,dsize)
參數說明:
- img:輸入圖像,通常是二維或三位NumPy數組。
- dsize:輸出圖像的尺寸,是一個二元組
(w,h)
,
示例
import cv2 as cvif __name__ == '__main__':# 讀取圖像pig = cv.imread('../images/pig.png')print(pig.shape) # (650, 1080, 3)# 調整圖像大小pig2 = cv.resize(pig, (500, 500))cv.imshow('pig2', pig2)cv.waitKey(0)cv.destroyAllWindows()
7.圖形繪制
7.1繪制直線
基本格式:
cv2.line(img,sart,end,color,thickness)
參數說明:
- img:要繪制直線的圖像
- start、end:直線的起點和終點
- color:直線的顏色(對于彩色圖像,使用 BGR 格式指定顏色)
- thickness:線條寬度
7.2繪制矩形
基本格式:
cv2.rectangle(img,leftupper,rightdown,color,thickness)
參數說明:
- img:要繪制矩形的圖像
- leftupper、rightdown:矩形的左上角和右下角坐標
- color:線條的顏色
- thickness:線條的寬度,-1時生成閉合圖案并填充顏色
7.3繪制圓形
基本格式:
cv2.circle(img,centerpoint,r,color,thickness)
參數說明:
- img:要繪制圓形的圖片
- centerpoint、r:圓心和半徑
- color:線條顏色
- tnickness:線條寬度,為-1時生成閉合圖案并填充顏色
- lineType=cv2.LINE_AA:使用反走樣技術繪制邊框(默認cv2.LINE_8)
7.4綜合示例
import cv2 as cvif __name__ == '__main__':cat = cv.imread('../images/1.jpg')# 繪制直線cv2.line(img,起始坐標,終止坐標,color,thickness,lineType'平滑度-抗鋸齒')cv.line(cat, (50,40), (300, 40),color=(0,255,255),thickness=3)# 繪制矩形cv2.rectangle(img,左上坐標,右下坐標,color,thickness,lineType'平滑度-抗鋸齒')cv.rectangle(cat,(78,106),(280, 306),color = (100,100,100), thickness=2)# 繪制圓形cv2.circle(img,圓心坐標,半徑,color,thickness,lineType'平滑度-抗鋸齒')cv.circle(cat,(325,269),30,color = (200,100,100), thickness=3,lineType=cv.LINE_AA)# 圖形顯示cv.imshow('cat', cat)cv.waitKey(0)cv.destroyAllWindows()
8.視頻讀取
基本格式:
cap = cv2.VideoCapture(path)
ret,frame = cap.read()
參數說明:
- path:視頻流資源路徑,如果設置為0,代表從默認攝像頭捕獲視頻流
- 返回值cap調用read()方法得到一個布爾值和一幀圖像,布爾值表示是否成功讀取到幀,如果為False,可能是因為視頻結束或讀取失敗,如果為True,frame則是當前幀的圖像數據。
示例
import cv2 as cvif __name__ == '__main__':# 創建一個VideoCapture對象cap = cv.VideoCapture(0)# 循環讀取每一幀while True:# 調用read()方法讀取每一幀ret, img = cap.read()# 判斷是否讀取成功if not ret:print('播放完成')breakcv.imshow('dst', img)# 捕獲按鍵,判斷是否中斷if cv.waitKey(40)&0xFF == ord('q'):# 獲取返回值的低8位print("按鍵退出")break# 釋放cap.release()cv.destroyAllWindows()
總結
今天算是opencv的入門,相較于之前的python基礎來說要輕松一點,就是要注意的細節比較多,稍微要了解的就是視頻讀取時’捕獲按鍵,判斷是否中斷’這里的原理,了解清楚之后就沒什么太難的東西了。
讓我們下期再見!