天天看點

OpenCV 4.圖像基本操作和圖像運算

OpenCV 中文官方文檔:http://woshicver.com/

圖像基本操作:

  • 通路像素值并修改它們
  • 通路圖像屬性
  • 設定感興趣區域(ROI)
  • 分割和合并圖像

圖像運算主要有:圖像加法和圖像融合

實作效果:塗紅一塊區域;複制一塊區域;僅顯示藍色通道;将紅色通道置0

OpenCV 4.圖像基本操作和圖像運算
OpenCV 4.圖像基本操作和圖像運算
OpenCV 4.圖像基本操作和圖像運算
OpenCV 4.圖像基本操作和圖像運算
import numpy as np
import cv2 as cv

# 通路和修改像素值

image = cv.imread("keyboard.webp")
# 通過行和列坐标來通路像素值。對于 BGR 圖像,它傳回一個由藍色、綠色和紅色值組成的數組。對于灰階圖像,隻傳回相應的灰階
px = image[10, 10]
print(px)  # [45 36 29]
# 通路藍色像素
print(image[10, 10, 0])  # 45

# 修改像素值
# note: Numpy是用于快速數組計算的優化庫。是以,簡單地通路每個像素值并對其進行修改将非常緩慢
# 這種方法通常用于選擇數組的區域,例如前5行和後3列
image[10:80, 10:80] = [0, 0, 255]
print(image[10, 10])  # [  0   0 255]
cv.imshow("image", image)
cv.waitKey(0)
cv.destroyAllWindows()

# 對于單個像素通路,Numpy數
# 組方法array.item()和array.itemset())被認為更好,但是它們始終傳回标量
# .item() 隻能通路單通道
print(image.item(10, 10, 2))  # 255
image.itemset((10, 10, 2), 100)
print(image.item(10, 10, 2))  # 100

####################################################################
# 通路圖像屬性:行數,列數和通道數,圖像資料類型,像素數

# .shape 傳回行、列和通道數 (行和列下标都是從0開始);如果圖像是灰階的,則傳回的元組僅包含行數和列數
print(image.shape)  # (340, 510, 3)
# 像素總數
print(image.size)  # 520200 = 340*510*3
# 圖像資料類型
print(image.dtype)  # uint8

####################################################################
# 圖像感興趣區域ROI: 比如找人眼,可以先确定人臉區域,然後在這個區域搜尋眼睛,而不用搜尋整張圖像
# 可以使用numpy索引
region = image[100:200, 100:200]
image[200:300, 200:300] = region
cv.imshow("image", image)
cv.waitKey(0)
cv.destroyAllWindows()

####################################################################
# 拆分、合并圖像通道
# cv.split() 是一項耗時的操作(就時間而言)。是以,僅在必要時才這樣做。否則請進行Numpy索引
b, g, r = cv.split(image)
print(b.shape)  # (340, 510)
cv.imshow("image", b)
cv.waitKey(0)
cv.destroyAllWindows()

# 下面更快
# b = image[:, :, 0]

# 将紅色通道設為紅色
image[:, :, 2] = 0
cv.imshow("image", image)
cv.waitKey(0)
cv.destroyAllWindows()

# 合并通道
img = cv.merge((b, g, r))
           

圖像運算

圖像加法:

  • 兩個圖像應具有相同的深度和類型
  • OpenCV函數cv.add():飽和運算 250+10 = 260 => 255 (推薦)
  • Numpy操作:模運算 250+10 = 260 % 256 = 4

圖像融合:

  • 也是圖像加法,但是對圖像賦予不同的權重,以使其具有融合或透明的感覺

實際效果:分别是飽和運算、模運算和按權重融合

OpenCV 4.圖像基本操作和圖像運算
OpenCV 4.圖像基本操作和圖像運算
OpenCV 4.圖像基本操作和圖像運算
import numpy as np
import cv2 as cv

image1 = cv.imread("keyboard.webp")
image2 = cv.imread("background.jpg")
print(image1.shape)  # (340, 510, 3)
print(image2.shape)  # (175, 146, 3)
image3 = image1[:175, :146]
des1 = cv.add(image2, image3)
des2 = image2 + image3
des3 = cv.addWeighted(image2, 0.3, image3, 0.7, 0)

# show
cv.imshow("image", image2)
cv.waitKey(0)
cv.imshow("image", image3)
cv.waitKey(0)
cv.imshow("image", des1)
cv.waitKey(0)
cv.imshow("image", des2)
cv.waitKey(0)
cv.imshow("image", des3)
cv.waitKey(0)
cv.destroyAllWindows()
           

按位運算:

OpenCV 4.圖像基本操作和圖像運算
OpenCV 4.圖像基本操作和圖像運算
OpenCV 4.圖像基本操作和圖像運算
import numpy as np
import cv2 as cv

image1 = cv.imread("keyboard.webp")
image2 = cv.imread("background.jpg")
print(image1.shape)  # (340, 510, 3)
print(image2.shape)  # (175, 146, 3)
image1Copy = image1.copy()
rows, cols, channels = image2.shape

# 處理的區域
roi = image1[:rows, :cols]
# 現在建立logo的掩碼,并同時建立其相反掩碼
image2gray = cv.cvtColor(image2, cv.COLOR_BGR2GRAY)
ret, mask = cv.threshold(image2gray, 10, 255, cv.THRESH_BINARY)
mask_inv = cv.bitwise_not(mask)
# 現在将ROI中logo的區域塗黑
image1_bg = cv.bitwise_and(roi, roi, mask=mask_inv)
# 僅從logo圖像中提取logo區域
image2_fg = cv.bitwise_and(image2, image2, mask=mask)
# 将logo放入ROI并修改主圖像
dst = cv.add(image1_bg, image2_fg)
image1[:rows, :cols] = dst
# show
cv.imshow("image", image1Copy)
cv.waitKey(0)
cv.imshow("image", image2)
cv.waitKey(0)
cv.imshow("image", image1)
cv.waitKey(0)
cv.destroyAllWindows()
           

繼續閱讀