1. 程式人生 > 其它 >三、Opencv-Python-Opencv基本操作

三、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)