目标
學會:
- 學習圖像的幾種算術運算
- 加法
- 減法
- 按位運算
- 學習以下函數
-
cv2.add
-
cv2.addWeighted
-
圖像加法
可以通過OpenCV函數
cv2.add()
或僅通過numpy操作
res = img1 + img2
添加兩個圖像。兩個圖像應具有相同的深度和類型,或者第二個圖像隻是一個标量值。
注意:OpenCV加法和Numpy加法之間有差別。OpenCV加法是飽和運算(超過最大值隻取最大值),而Numpy加法是模運算(超過最大值,取模)
x = np.uint8([250])
y = np.uint8([10])
print(cv2.add(x, y)) # 250+10 = 260 => 255
# [[255]]
print(x+y) # 250+10 = 260 % 256 = 4 (0~255 -> 256)
# [4]
當添加兩個圖像時,它将更加可見。OpenCV功能将提供更好的結果。是以,始終最好堅持使用OpenCV功能。
圖像融合
這也是圖像加法,但是對圖像賦予不同的權重,以使其具有融合或透明的感覺。根據以下等式按照權重加圖像:
G(x) =
(1 - alpha) * f_0(x) + alpha * f_1(x)
alpha取值從0~1,可以在一個圖像到另一個圖像之間執行很酷的過渡。
cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]]) → dst
函數效果如下
dst = src1 * alpha + src2 * beta + gamma;
找到兩個圖像,将它們融合在一起。第一幅圖像的權重為0.7,第二幅圖像的權重為
0.3。在圖像上應用以下公式
cv2.addWeighted()
img1 = cv2.imread('ml.png')
img2 = cv2.imread('origin.png')
dst = cv2.addWeighted(img1, 0.7, img2, 0.3, 0)
cv2.imshow('dst', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL3EGZjBTN0IzN3MTZiFjM5UzN1QTOilTZ4QTZkNjNlBzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
注意
img1和img2的尺寸大小要保持一緻,否則無法對位相加。如果不一樣,可以通過cv2.resize實作尺寸變換。
cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) -> dst
src - 原圖
dst - 目标圖像。
dsize - 目标圖像大小。
interpolation - 插值方法。共有5種:
1)INTER_NEAREST - 最近鄰插值法
2)INTER_LINEAR - 雙線性插值法(預設)
3)INTER_AREA - 基于局部像素的重采樣。
4)INTER_CUBIC - 基于4x4像素鄰域的3次插值法
5)INTER_LANCZOS4 - 基于8x8像素鄰域的Lanczos插值
example:
h, w, _ = img1.shape
img2 = cv2.resize(img2, (w,h), interpolation=cv2.INTER_AREA) # 将img2轉換成img1大小
按位運算
這包括按位
AND(與) 、 OR(或) 、 NOT(非) 、 XOR(異或)
操作。它們在提取圖像的任何部分、定義和處理非矩形 ROI 等方面非常有用。 下面将看到一個例子,如何改變一個圖像的特定區域。 想把 OpenCV 的标志放在一個圖像上面。如果添加兩個圖像,它會改變顔色。如果混合它,我得到一個透明的效果。但希望它是不透明的。如果是一個矩形區域,可以使用 ROI,就像在上一章中所做的那樣。但是 OpenCV 的 logo 不是長方形的。是以可以使用如下的按位操作來實作:
cv2.bitwise_and():位與運算,有0則為0, 全為1則為1
cv2.bitwise_not():或運算,有1則為1, 全為0則為0
cv2.bitwise_or():非運算,非0為1, 非1為0
cv2.bitwise_xor():異或運算,不同為1, 相同為0
img1 = cv2.imread('messi.png')
img2 = cv2.imread('origin.png')
# logo left top
rows, cols, channel = img2.shape
roi = img1[0: rows, 0: cols] # 獲得bg
# mask of logo
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)
# 現在将ROI中logo的區域塗黑
img1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
# 僅從logo圖像中提取logo區域
img2_fg = cv2.bitwise_and(img2, img2, mask=mask)
# 将logo放入ROI并修改主圖像
dst = cv2.add(img1_bg, img2_fg)
img1[0:rows, 0:cols] = dst
cv2.imshow('res',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
- roi區域
opencv06:圖像上的算術運算 - logo mask
opencv06:圖像上的算術運算 - logo mask inv
opencv06:圖像上的算術運算 - img1_bg
opencv06:圖像上的算術運算 - img2_fg
opencv06:圖像上的算術運算 - dst
opencv06:圖像上的算術運算