今天的學習的內容是:通過 Python OpenCV 對影像實作乘除操作,涉及函式為 cv2.multiply 與 cv2.divide,后面又補充了一些像素的邏輯運算,以及一個綜合案例
cv2.multiply
該函式的語法格式如下:
cv2.multiply(src1, src2, dst=None, scale=None, dtype=None)
引數說明:
src1:第一張影像
src2:第二張影像
dst:可選引數,目標影像,需要提前分配空間,可省略
mask:掩膜
scale:縮放比,常量,即在 src1*src2 的基礎上再乘 scale
dtype:輸出影像陣列的深度,默認等于-1
測驗下面的代碼,嘗試之后,發現乘法很容易就全黑或者全白,畢竟兩個數字相乘知乎,很容易超過 255,
import cv2 as cv
def multiply_demo(src1, src2):
ret = cv.multiply(src1, src2)
cv.imshow("multiply_demo", ret)
cv.waitKey(0)
if __name__ == "__main__":
src1 = cv.imread("./18_3.jpeg")
src2 = cv.imread("./18_4.jpg")
multiply_demo(src1, src2)

如果 cv2.multiply 函式的第二個影像為一個標量,那運行結果是針對單一通道進行疊加,
import cv2 as cv
from matplotlib import pyplot as plt
def multiply_demo(src1, src2):
ret = cv.multiply(src1, 1.5)
plt.subplot(121), plt.imshow(src1), plt.title('src1')
plt.subplot(122), plt.imshow(ret), plt.title('ret')
plt.show()
if __name__ == "__main__":
src1 = cv.imread("./18_3.jpeg")
src2 = cv.imread("./18_4.jpg")
multiply_demo(cv.cvtColor(src1,cv.COLOR_BGR2RGB), cv.cvtColor(src2,cv.COLOR_BGR2RGB))
運行效果截圖:

cv2.divide
該函式的語法格式為:
divide(src1, src2, dst=None, scale=None, dtype=None)
本部分與相乘基本一致,影像相除最后很容易得到一個全黑的圖,
具體可以自行嘗試,
像素的邏輯運算
像素的邏輯運算涉及與、或、非、異或等基本運算(要進行邏輯運算,兩張圖片的形狀(shape)必須一樣)
對應函式的格式如下
cv2.bitwise_and(src1, src2,mask)
作用:對二進制資料進行“與”操作,即對影像(灰度影像或彩色影像均可)每個像素值進行二進制“與”操作,1&1=1,1&0=0,0&1=0,0&0=0,
這個里面的掩膜非常有用,我們細說一下,
在徹底學習演膜之前,需要接觸一個新的概念,又要學習新東西啦,
而且在接下來的幾篇博客,都要圍繞演膜與 ROI 展開,因為在學習的時候,發現這部分知識很重要,
ROI(感興趣區域,英文全稱叫做 Region Of Internet)
下面我們實作找到 ROI,并且移動 ROI,代碼如下:
下述代碼測驗圖片,使用的是:

我們要獲取的是蕾姆的犄角
import cv2 as cv
path = r"1919.jpeg"
# 讀取圖片
image = cv.imread(path)
# 輸出圖片形狀
# 注意輸出的元組(rows,cols,dtype)
print(image.shape)
# cv.imshow("image", image)
# 捕捉犄角區域
horn = image[60:100, 180:240]
# cv.imshow("horn", horn)
# 框選犄角區域
# image = cv.rectangle(image, (180, 55), (240, 105), (0, 0, 255), thickness=2)
# print(horn.shape)
# 拷貝一個犄角
# image[60:100, 120:180] = image[60:100, 180:240]
# 只要形狀大小相同就可以移動 ROI 到另一部分
# image[100:140, 220:280] = horn
# 犄角轉換成灰度圖
horn = cv.cvtColor(horn, cv.COLOR_BGR2GRAY)
# 灰度圖在轉換成BGR圖
back_horn = cv.cvtColor(horn, cv.COLOR_GRAY2BGR)
# image[250:370, 250:350] = back_horn
image[60:100, 180:240] = back_horn
cv.imshow("Region Of Interest(ROI)", horn)
cv.imshow("horn", image)
cv.waitKey()
cv.destroyAllWindows()
上述代碼,你可以在學習程序中自行解開查閱,重點部分都已經寫在注釋里面了,
獲取到犄角圖之后,我們在對其進行二值化操作,具體代碼如下
import cv2 as cv
path = r"1919.jpeg"
# 讀取圖片
image = cv.imread(path)
# 輸出圖片形狀
# 注意輸出的元組(rows,cols,dtype)
print(image.shape)
# cv.imshow("image", image)
# 捕捉犄角區域
horn = image[60:100, 180:240]
# 犄角轉換成灰度圖
gray_horn = cv.cvtColor(horn, cv.COLOR_BGR2GRAY)
# 獲取到了犄角的二值化影像
thresh, mask = cv.threshold(gray_horn, 160, 255, cv.THRESH_BINARY)
# 獲取 mask 的反色影像
mask_inv = cv.bitwise_not(mask)
# cv.imshow("mask", mask)
# 打開一個彩色糖果圖片
colors = cv.imread(r"colors.jpg")
# 選中一塊與 mask 相同大小的 ROI
rows, cols = mask.shape[:2]
pie_colors = colors[10:10+rows, 20:20+cols]
print(pie_colors.shape)
print(mask.shape)
cv.imshow("pie_colors", pie_colors)
# 選出犄角部分
img1_bg = cv.bitwise_and(horn, pie_colors, mask=mask)
# cv.imshow("img1_bg", img1_bg)
img2_fg = cv.bitwise_and(horn, horn, mask=mask_inv)
# cv.imshow("img2_fg", img2_fg)
# 兩個犄角合并在一起
add_img = image.copy() # 對原影像進行拷貝
dst = cv.addWeighted(img1_bg, 0.3, img2_fg, 1, 0)
# cv.imshow("dst", dst)
add_img[60:100, 180:240] = dst
# image[60:100, 180:240] = back_horn
cv.imshow("origin", image)
cv.imshow("new", add_img)
cv.waitKey()
cv.destroyAllWindows()
上面的代碼,理解起來有寫難度,本階段先嘗試理解即可(橡皮擦在寫的時候,也暈掉了,總感覺缺少一些知識,沒有吃透)
用到了以前學習的二值化操作,用到了灰度圖,也用到了影像疊加,
也有可能是因為案例選擇的不好,最后更換犄角之后的圖片很難看,如下圖所示,
看起來,缺少一部分融合的效果,后面知識比較全面之后,可能對這些理解會更加深入,

效果雖然丑爆了,但是終究是能操作指定區域了,
上述代碼也用到了下面的邏輯運算,先理解含義,后面逐步展開內容,
cv2.bitwise_or(src1, src2,mask)
作用:對不同通道相同位置的二進制值進行"或"運算(對應位置只要有一個為 1,結果就為 1),
cv2.bitwise_not()
作用:按位取反
cv2.bitwise_xor(src1,src2,dst,mask)
作用:輸出兩個影像的異或 dst = src1 ^ src2
測驗代碼如下:
import cv2
import numpy as np
from matplotlib import pyplot as plt
src1 = cv2.imread('18_1.jpg')
src2 = cv2.imread('18_2.jpg')
d_and = cv2.bitwise_and(src1, src2)
d_or = cv2.bitwise_or(src1, src2)
d_not = cv2.bitwise_not(src1)
d_xor = cv2.bitwise_xor(src1, src2)
title = ['src1', 'src2', 'and', 'or', 'not', 'xor']
images = [src1, src2, d_and, d_or, d_not, d_xor]
for i in range(6):
plt.subplot(2, 3, i+1)
plt.imshow(cv2.cvtColor(
images[i], cv2.COLOR_BGR2RGB), 'gray'), plt.title(title[i])
plt.show()
代碼運行之后的效果如圖:

下篇博客,將使用之前的內容,加上像素的邏輯運算完成一個【扣章效果】,
學習完今天的效果之后,發現對以前學過的地方有遺漏,后面幾篇博客,基于已經學習的知識,好好夯實幾天吧,
OpenCV 尾聲
1 個小時又過去了,對 Python OpenCV 相關的知識點,你掌握了嗎?
空閑之余,可以訂閱橡皮擦的爬蟲百例課程學習爬蟲知識,
想學 Python 爬蟲,可以訂閱橡皮擦專欄哦~ 🈲🈲🈲🈲 點擊發現驚喜 🈲🈲🈲🈲
今天是持續寫作的第 56 / 100 天,
如果你有想要交流的想法、技術,歡迎在評論區留言,
如果你想跟博主建立親密關系,可以關注博主,或者關注博主公眾號 “
非本科程式員”,了解一個非本科程式員是如何成長的,
博主 ID:夢想橡皮擦,希望大家點贊、評論、收藏
CSDN認證博客專家
高級產品經理
互聯網從業者
業余編程愛好者
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/250234.html
標籤:python
上一篇:Django REST framework框架深度學習(一)
下一篇:女生生日沒禮物送?
