三、Opencv-Python-Opencv基本操作
三、OpenCV基本操作
影象基本操作
3.1 影象的IO操作
3.1.1 讀取影象
import cv2 as cv
cv.imread("圖片.jpg",0) # 灰度影象
# 等同於:cv.imread('圖片.jpg', cv.IMREAD_GRAYSCALE)
引數:
-
要讀取的影象
-
讀取方式的標誌
-
cv.IMREAD*COLOR:以彩色模式載入影象,任何影象的透明度都將被忽略。這是預設引數。
-
cv.IMREAD*GRAYSCALE:以灰度模式載入影象
-
cv.IMREAD_UNCHANGED:包括alpha通道的載入影象模式。
可以使用1、0或者-1來替代上面三個標誌
-
3.1.2 顯示影象
import cv2 as cv
cv.imread("圖片.jpg",0) # 灰度影象
cv.imshow("視窗名稱",載入的影象)
引數:
- 顯示影象的視窗名稱,以字串型別表示
- 要載入的影象
3.1.3 儲存影象
import cv2 as cv
cv.imread("圖片.jpg",0) # 灰度影象
cv.imshow("視窗名稱",載入的影象)
cv.imwrite('儲存圖片的名字',儲存的圖片)
引數:
- 檔名,要儲存在哪裡
- 要儲存的影象
3.2 繪製幾何圖形
3.2.1 繪製直線
import cv2 as cv cv.line(img,start,end,color,thickness)
引數:
- img:要繪製直線的影象
- Start,end: 直線的起點和終點
- color: 線條的顏色
- Thickness: 線條寬度
具體程式碼:
pt_start = (60, 60)
pt_end = (200, 200)
point_color = (255, 245, 0) # BGR
cv.line(img, pt_start, pt_end, point_color, thickness=5)
3.2.2 繪製圓形
import cv2 as cv
cv.circle(img,centerpoint, r, color, thickness)
引數:
- img:要繪製圓形的影象
- Centerpoint, r: 圓心和半徑
- color: 線條的顏色
- Thickness: 線條寬度,為-1時生成閉合圖案並填充顏色
# 繪製圓形
center_point = (250, 250)
r = 100
point_color = (255, 245, 0) # BGR
cv.circle(img, center_point, r, point_color, thickness=3)
3.2.3 繪製矩形
import cv2 as cv
cv.rectangle(img,leftupper,rightdown,color,thickness)
引數:
- img:要繪製矩形的影象
- Leftupper, rightdown: 矩形的左上角和右下角座標
- color: 線條的顏色
- Thickness: 線條寬度
# 繪製矩形
left_upper = (80, 80)
right_down = (200, 200)
point_color = (255, 245, 0) # BGR
cv.rectangle(img, left_upper, right_down, point_color, thickness=3)
3.2.4 向影象中新增文字
cv.putText(img,text,station, font, fontsize,color,thickness,cv.LINE_AA)
引數:
- img: 影象
- text:要寫入的文字資料
- station:文字的放置位置
- font:字型
- Fontsize :字型大小
# 向影象中新增文字
text = "Lena"
station = (10, 100)
font = cv.FONT_HERSHEY_DUPLEX
font_size = 2
font_color = (255, 245, 0) # BGR
cv.putText(img, text, station, font, font_size, font_color, thickness=3)
3.3 獲取並修改影象中的畫素點
我們可以通過行和列的座標值獲取該畫素點的畫素值。對於BGR影象,它返回一個藍,綠,紅值的陣列。對於灰度影象,僅返回相應的強度值。使用相同的方法對畫素值進行修改。
import numpy as np
import cv2 as cv
img = cv.imread('lena.jpg')
# 獲取某個畫素點的值
px = img[100,100]
# 僅獲取藍色通道的強度值
blue = img[100,100,0]
# 修改某個位置的畫素值
img[100,100] = [255,255,255]
如下圖,左圖的位置的畫素點修改為右圖的白點
3.4 獲取影象的屬性
影象屬性包括行數,列數和通道數,影象資料型別,畫素數等。
# 影象屬性包括行數,列數和通道數,影象資料型別,畫素數等。
print(img.shape) #獲取影象的形狀,返回值是一個包含行數、列數、通道數的元組。
print(img.size) #獲得影象的畫素數目。
print(img.dtype) #獲得影象的資料型別。
結果:
(512, 512, 3)
786432
uint8
3.5 影象通道的拆分與合併
有時需要在B,G,R通道影象上單獨工作。在這種情況下,需要將BGR影象分割為單個通道。或者在其他情況下,可能需要將這些單獨的通道合併到BGR影象。你可以通過以下方式完成。
b, g, r = cv.split(img)
print(b)
print(g)
print(r)
# 通道合併
img = cv.merge((b, g, r))
結果:
[[125 125 133 ... 122 110 90]
[125 125 133 ... 122 110 90]
[125 125 133 ... 122 110 90]
...
[ 60 60 58 ... 84 76 79]
[ 57 57 62 ... 79 81 81]
[ 57 57 62 ... 79 81 81]]
[[137 137 137 ... 148 130 99]
[137 137 137 ... 148 130 99]
[137 137 137 ... 148 130 99]
...
[ 18 18 27 ... 73 68 62]
[ 22 22 32 ... 70 71 74]
[ 22 22 32 ... 70 71 74]]
[[226 226 223 ... 230 221 200]
[226 226 223 ... 230 221 200]
[226 226 223 ... 230 221 200]
...
[ 84 84 92 ... 173 172 177]
[ 82 82 96 ... 179 181 185]
[ 82 82 96 ... 179 181 185]]
3.6 色彩空間的改變
OpenCV中有150多種顏色空間轉換方法。最廣泛使用的轉換方法有兩種
-
BGR↔Gray
-
BGR↔HSV
cv.cvtColor(input_image,flag)
引數:
- input_image: 進行顏色空間轉換的影象
- flag: 轉換型別
- cv.COLOR_BGR2GRAY : BGR↔Gray
- cv.COLOR_BGR2HSV: BGR→HSV
具體程式碼:
# 色彩空間的改變
img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
算數操作
1. 影象加法
你可以使用OpenCV的cv.add()函式把兩幅影象相加,或者可以簡單地通過numpy操作新增兩個影象,如res = img1 + img2。兩個影象應該具有相同的大小和型別,或者第二個影象可以是標量值。
注意:OpenCV加法和Numpy加法之間存在差異。OpenCV的加法是飽和操作,而Numpy新增是模運算。
將下面的兩幅圖相加:
實列程式碼:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 1 讀取圖片
img1 = cv.imread("../img/lena.png")
img2 = cv.imread("../img/rain.jpg")
# 2 加法操作
x, y = 300, 50 # 疊放位置
W1, H1 = img1.shape[1::-1] # 大圖尺寸
W2, H2 = img2.shape[1::-1] # 小圖尺寸
if (x + W2) > W1 : x = W1 - W2 # 調整影象疊放位置,避免溢位
if (y + H2) > H1 : y = H1 - H2
imgCrop = img1[y:y + H2, x:x + W2] # 裁剪大圖,與小圖 imgS 的大小相同
img3 = cv.add(imgCrop, img2) # cv2 加法,裁剪圖與小圖疊加
img4 = imgCrop + img2
# 3 影象顯示
cv.imshow(u"img3", img3)
cv.imshow(u"img4", img4)
cv.waitKey(0)
2. 影象的混合
這其實也是加法,但是不同的是兩幅影象的權重不同,這就會給人一種混合或者透明的感覺。影象混合的計算公式如下:
g(x) = (1−α)f0(x) + αf1(x)
通過修改 α 的值(0 → 1),可以實現非常炫酷的混合。
現在我們把兩幅圖混合在一起。第一幅圖的權重是0.7,第二幅圖的權重是0.3。函式cv2.addWeighted()可以按下面的公式對圖片進行混合操作。
dst = α⋅img1 + β⋅img2 + γ
這裡γ取為零。
例項:
addWeighted(InputArray src1,
double alpha,
InputArray src2,
double beta,
double gamma,
OutputArray dst,
int dtype=-1)
引數:
-
第一個引數,InputArray型別的src1,表示需要加權的第一個陣列,常常填一個Mat。
-
第二個引數,alpha,表示第一個陣列的權重。
-
第三個引數,src2,表示第二個陣列,它需要和第一個陣列擁有相同的尺寸和通道數。
-
第四個引數,beta,表示第二個陣列的權重值。
-
第五個引數,dst,輸出的陣列,它和輸入的兩個陣列擁有相同的尺寸和通道數。
-
第六個引數,gamma,一個加到權重總和上的標量值。看下面的式子自然會理解。
-
第七個引數,dtype,輸出陣列的可選深度,有預設值-1。;當兩個輸入陣列具有相同的深度時,這個引數設定為-1(預設值),即等同於src1.depth()。
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 1 讀取圖片
img1 = cv.imread("../img/lena.png")
img2 = cv.imread("../img/rain.jpg")
# 2 混合操作
x, y = 300, 50 # 疊放位置
W1, H1 = img1.shape[1::-1] # 大圖尺寸
W2, H2 = img2.shape[1::-1] # 小圖尺寸
if (x + W2) > W1:
x = W1 - W2 # 調整影象疊放位置,避免溢位
if (y + H2) > H1:
y = H1 - H2
imgCrop = img1[y:y + H2, x:x + W2] # 裁剪大圖,與小圖 imgS 的大小相同
img3 = cv.addWeighted(imgCrop, 0.7, img2, 0.3, 0) # cv2 影象混合
# 3 影象顯示
cv.imshow(u"img3", img3)
cv.waitKey(0)