回傳目錄
目錄
7 影像上的算術運算
7.1 目標
7.2 影像加法
7.3 影像融合
7.4 按位運算
7.5 練習題
7 影像上的算術運算
7.1 目標
學習影像的幾種算術運算,例如加法,減法,按位運算等,
您將學習以下功能:cv.add,cv.addWeighted等,
7.2 影像加法
您可以通過OpenCV函式cv.add() 或僅通過numpy操作res = img1 + img2 添加兩個影像,兩個影像應具有相同的深度和型別,或者第二個影像可以只是一個標量值,
注意:OpenCV加法和Numpy加法之間有區別,OpenCV加法是飽和運算,而Numpy加法是模運算,
示例如下:
x = np.uint8([250])
y = np.uint8([25])
print(cv.add(x, y)) # [[255]]:250+25=275=>255
print(x + y) # [19]:250+25=275%256=19
當添加兩個影像時,它將更加可見,OpenCV功能將提供更好的結果,因此,始終最好堅持使用OpenCV功能,
7.3 影像融合
這也是影像加法,但是對影像賦予不同的權重,以使其具有融合或透明的感覺,根據以下等式添加影像:
通過從 從
更改,您可以在一個影像到另一個影像之間執行很酷的過渡,但是兩個影像的寬高必須一致才行,
在這里,我拍攝了兩個影像,將它們融合在一起,第一幅影像的權重為0.7,第二幅影像的權重為0.3,cv.addWeighted() 在影像上應用以下公式,
在這里, 被視為零,
import cv2 as cv
img1 = cv.imread('../girl02/05.jpg')
img2 = cv.imread('../girl02/06.jpg')
print('img1:{};img2:{}'.format(img1.shape, img2.shape)) # img1:(1080, 1920, 3);img2:(1080, 1920, 3)
cv.namedWindow('image', cv.WINDOW_NORMAL)
dst = cv.addWeighted(img1, 0.7, img2, 0.3, 0)
cv.imshow('image', dst)
cv.waitKey(0)
cv.destroyAllWindows()
融合結果如下:

7.4 按位運算
這包括按位 AND 、 OR 、NOT 和 XOR 操作,它們在提取影像的任何部分(我們將在后面的章節中看到)、定義和處理非矩形 ROI 等方面非常有用, 下面我們將看到一個例子,如何改變一個影像的特定區域, 我想把 OpenCV 的標志放在一個影像上面,如果我添加兩個影像,它會改變顏色,如果我混合它,我得到一個透明的效果,但我希望它是不透明的,如果是一個矩形區域,我可以使用 ROI,就像我們在上一章中所做的那樣,但是 OpenCV 的 logo 不是長方形的,所以你可以使用如下的按位操作來實作:
我想在影像上方放置OpenCV徽標,如果添加兩個影像,它將改變顏色,如果混合它,我將獲得透明效果,但我希望它不透明,如果是矩形區域,則可以像上一章一樣使用ROI,但是OpenCV徽標不是矩形,因此,您可以按如下所示進行按位操作:
import cv2 as cv
import matplotlib.pyplot as plt
# 讀取原影像
img = cv.imread('../girl6/14.jpg')
img = cv.cvtColor(img, cv.COLOR_BGR2RGB) # 因為opencv是BGR通道,而matplotlib是RGB通道
plt.subplot(331), plt.imshow(img, 'gray'), plt.title('img')
# 讀取logo影像
logo = cv.imread('../girl6/opencv.png')
logo = cv.cvtColor(logo, cv.COLOR_BGR2RGB)
plt.subplot(332), plt.imshow(logo, 'gray'), plt.title('logo')
# 把logo放在左上角,所以創建了ROI
rows, cols, channels = logo.shape # 獲取logo的行、列和通道數
roi = img[0:rows, 0:cols] # 在img影像上面截取roi大小的區域
plt.subplot(339), plt.imshow(roi, 'gray'), plt.title('roi')
# 現在創建logo的掩碼,并同時創建其相反掩碼
logo2gray = cv.cvtColor(logo, cv.COLOR_BGR2GRAY) # 將logo轉換為灰度影像,以便二值化
plt.subplot(334), plt.imshow(logo2gray, 'gray'), plt.title('logo2gray')
# cv.threshold將灰度圖二值化,ret為閾值,mask為二值化的影像,將低于第一個閾值的置為0,高于第二個閾值的置為255
ret, mask = cv.threshold(logo2gray, 200, 255, cv.THRESH_BINARY)
plt.subplot(335), plt.imshow(mask, 'gray'), plt.title('mask')
# bitwise_not是對二進制資料進行“非”操作,即對影像(灰度影像或彩色影像均可)每個像素值進行二進制“非”操作
mask_inverse = cv.bitwise_not(mask) # cv.bitwise_not將掩碼取反
plt.subplot(336), plt.imshow(mask_inverse, 'gray'), plt.title('mask_inverse')
# 現在將ROI中logo的區域涂黑
# bitwise_and是對二進制資料進行“與”操作,即對影像(灰度影像或彩色影像均可)每個像素值進行二進制“與”操作
img_background = cv.bitwise_and(roi, roi, mask=mask_inverse)
plt.subplot(337), plt.imshow(img_background, 'gray'), plt.title('img_background')
# 僅從logo影像中提取logo區域
logo_foreground = cv.bitwise_and(logo, logo, mask=mask)
plt.subplot(338), plt.imshow(logo_foreground, 'gray'), plt.title('logo_foreground')
# 將logo放入ROI并修改主影像
dst = cv.add(img_background, logo_foreground)
img[0:rows, 0:cols] = dst
plt.subplot(333), plt.imshow(img, 'gray'), plt.title('dst')
plt.show()
請看下面的結果,為了更加直觀的看清楚,我將其用matplotlib進行了排列,可以看清楚每一個影像的意思,

7.5 練習題
使用cv.addWeighted 函式在檔案夾中創建影像的幻燈片放映,并在影像之間進行平滑過渡,
大家可以先自己想想應該怎么做,我這里做的是回圈讀取檔案夾的圖片,達到幻燈片放映效果,先上運行結果:

具體代碼如下:
import cv2 as cv
import os
from PIL import Image
# 讀取檔案夾下圖片的數量
image_dir = '../girl6/'
count = os.listdir(image_dir) # 讀取image_dir檔案夾中圖片個數
print('count=', len(count)) # 列印檔案夾中圖片個數,我這里count=26
# 將圖片裁剪成相同尺寸
for i in range(0, len(count)):
# 獲取圖片的尺寸
img = Image.open(image_dir + str(i).zfill(2) + '.jpg')
img_size = img.size # im_size[0]獲取的是圖片寬度,im_size[1]獲取的是圖片的高度
# print('圖片寬度和高度分別是{}'.format(img_size))
img = img.resize((450, 288)) # 可以根據自己需求裁剪圖片大小,第一個是寬度,第二個是高度
# 將裁剪的圖片按照0~count保存,zfill(2)表示兩位數,不夠前面填0
img.save(image_dir + str(i).zfill(2) + '.jpg')
# 新建一個視窗
cv.namedWindow('image', cv.WINDOW_NORMAL)
a = 0 # 初始化權重系數
cv.waitKey(0) # 等待按鍵開始
# 遍歷檔案夾下所有圖片
for i in range(0, len(count)):
image1 = cv.imread(image_dir + str(i).zfill(2) + '.jpg', 1)
image2 = cv.imread(image_dir + str(i + 1).zfill(2) + '.jpg', 1)
while a < 1.0:
dst = cv.addWeighted(image2, a, image1, 1 - a, -1)
cv.imshow('image', dst)
cv.waitKey(88) # 這里是自動跳轉,也可以設定按鍵進行跳轉
a += 0.1
a = 0 # 重新初始化權重系數
print(i)
i += 1
cv.waitKey(0) # 等待按鍵結束
cv.destroyAllWindows()
歡迎評論區留言,一起探討OpenCV成神之路的奧秘,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/287829.html
標籤:其他
