? ? 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython ?
一、引言
在寫該文之前,老猿就影像的一些運算已經單獨邊學邊發了,在寫這些文的程序中,發現這些運算函式共同點很多,例如大部分引數一樣、部分處理方法一樣等,另外還有些函式可以實作相同或近似的效果,因此在前面那些文章的基礎上,將其綜合為一個整體來發布,更方便大家閱讀,
OpenCV中影像存盤為矩陣,因此影像的運算其實就是矩陣的運算,影像的運算主要包括影像基礎算術運算、影像加權運算(又稱為影像融合)、按位運算等類別,這些運算可以直接通過numpy矩陣進行,也可以通過opencv的專用方法進行,但opencv的矩陣運算和numpy矩陣運算還是有些不同,例如在加法處理上,OpenCV加法是飽和運算(超過255即按255),而Numpy加法是模運算(超過255按256取模的結果作為結果),對加法來說,顏色值越大OpenCV 的結果會更好,因此推薦使用opencv的進行算術運算,本文的內容全部基于OpenCV的方法進行介紹,
二、OpenCV影像運算語法
2.1、影像運算函式串列
OpenCV影像運算包括如下函式:
- 加法運算:
add(src1, src2, dst=None, mask=None, dtype=None) - 減法運算:
subtract(src1, src2, dst=None, mask=None, dtype=None) - 乘法運算:
multiply(src1, src2, dst=None, scale=None, dtype=None) - 除法運算:
divide(src1, src2, dst=None, scale=None, dtype=None) - 冪運算:
pow(src, power, dst=None) - 開方運算:
sqrt(src, dst=None) - 自然常數e為底的指數函式:
exp(src, dst=None) - 對數運算:
log(src, dst=None) - 融合權重加法:
addWeighted(src1, alpha, src2, beta, gamma, dst=None, dtype=None) - 位與運算:
bitwise_and(src1, src2, dst=None, mask=None) - 位或運算:
bitwise_or(src1, src2, dst=None, mask=None) - 位異或運算:
bitwise_xor(src1, src2, dst=None, mask=None) - 位非運算:
bitwise_not(src, dst=None, mask=None)
2.2、影像運算常用引數說明
- src:輸入影像矩陣
- src1、src2:兩副大小和通道數相等的輸入影像或一副輸入影像和一個標量(關于標量請參考《OpenCV-Python中的標量Scalar是什么》)
- dst:目標影像輸出,要求與輸入影像大小相同,如果傳值則可以直接以實參作為目標影像存盤變數,否則可以用函式回傳值作為目標影像存盤變數,在實參非None傳入的情況下,回傳值與該實參值相同
- scale:縮放因子,影像運算時,先執行src1*scale,再以該乘積進行后續運算
- mask:影像掩膜,可選引數,為8位單通道的灰度影像,用于指定要更改的輸出影像陣列的元素,即輸出影像像素只有mask對應位置元素不為0的部分才輸出,否則該位置像素的所有通道分量都設定為0,更多關于掩膜的內容請參考《OpenCV學習02-矩陣的掩膜操作》
- dtype:可選引數,輸出影像陣列的深度,即影像單個像素值的位數(如RGB用三個位元組表示,則為24位),在幫助檔案中介紹,引數src1和src2可以有不同的影像深度(即影像像素位數,如8位、16位、24位和32位),如可以將16位影像和一個8位影像相加將輸出結果保存在32位輸出陣列中,關于這個引數老猿研究可很長時間,因為認為如果影像深度不一樣,意味著影像的通道數也不一樣,通道數不一樣,意味著陣列大小不一樣,這樣的兩個陣列無法進行運算,后來機緣契合下自認為理解了,這里說的影像深度不是通道數*8,而是單個通道值表示的位數,即單通道不一定是8位的,也可以是16位、24位或32位的,看如下代碼就明白了:
def main():
img1 = cv2.imread(r'F:\pic\shape1.png').astype(np.float32)
img2 = cv2.imread(r'F:\pic\shape2.png')
img = cv2.add(img1,img2,dtype=24)
上述代碼將以兩種不同表示方法讀入兩副影像,第一幅影像是以float32來表示影像單通道值,第二幅影像是預設值uint8來表示影像單通道值,二者機器位數不同,但相加之后轉為了24位影像,即單通道為8位元組影像,
2.3、部分影像運算函式詳解
針對部分重要的影像運算,老猿在前面已經單獨進行了介紹,包括:
- OpenCV-Python影像的加法運算cv2.add函式詳解
- OpenCV-Python影像的減法運算cv2.subtract函式詳解以及和矩陣減法的差異對比
- OpenCV-Python影像乘法運算cv2.multiply函式詳解及像素值溢位歸一化處理
- OpenCV-Python影像除法運算cv2.divide函式及影像相除處理
- OpenCV-Python影像融合cv2.addWeighted權重加法函式詳解
- OpenCV-Python影像位與運算bitwise_and函式詳解
2.4、其他影像運算函式簡介
-
冪運算:
pow(src, power, dst=None),對影像的每個通道值計算power引數對應的冪作為結果影像的通道值,如果power為整數,則直接計算冪值,如果power為浮點數,則取通道值的絕對值參與計算,即:
-
開方運算:
sqrt(src, dst=None),對影像的每個通道值開方作為結果影像的通道值,即:dst(I)=sqrt(src1(I)) -
自然常數e為底的指數函式:
exp(src, dst=None),以e為底對影像的每個通道值作為冪值計算結果影像的通道值,即:
-
對數運算:
log(src, dst=None),計算影像的每個通道值的自然對數作為結果影像的通道值,即:dst(I)=ln(src(I)) -
位或運算:
bitwise_or(src1, src2, dst=None, mask=None),計算兩副影像每個通道值或一影像通道值與一個標量的按位或的結果作為結果影像的通道值 -
位異或運算:
bitwise_xor(src1, src2, dst=None, mask=None),計算兩副影像每個通道值或一影像通道值與一個標量的按位異或的結果作為結果影像的通道值 -
位非運算:
bitwise_not(src, dst=None, mask=None),將src影像的每個通道值按位取反作為結果影像的值,
三、相關函式的作用分析
- 影像的減法、除法以及異或都可以用于分析影像的差異點,但減法和異或更準確 ;
- 加法、權重加法以及影像或運算都可以用于合并影像,但由于運算方法與差異,效果會有不同,針對不同影像的融合選擇哪種方法與影像資料及應用的目標相關;
- 影像的自乘、冪運算都可以用于調整影像的對比度;
- 非運算及異或運算可以將影像的一部分影像的視覺效果提高;
- 影像乘法、位與都可以用于提取影像的感興趣部分或者屏蔽某些部分,在這方面的功能與影像掩碼的效果相同,只是實作方式不同;
- 通過閾值處理、影像求反、與處理等可以提取影像中的結構特征
四、按位運算的簡單案例
前面部分影像運算函式詳解中舉例介紹了影像加減乘除權重加及位與的相關功能,在此補充一個簡單的按位運算的案例,代碼如下:
import numpy as np
import cv2
def main():
img1 = cv2.imread(r'F:\pic\shape1.png').astype(np.float32)
img2 = cv2.imread(r'F:\pic\shape2.png')
resultImgAnd = cv2.bitwise_and(img1, img2)
resultImgOr = cv2.bitwise_or(img1, img2)
resultImgXor = cv2.bitwise_xor(img1, img2)
resultImgNot = cv2.bitwise_not(img1)
resultImgXorScalar = cv2.bitwise_xor(img1, (255,255,255,255))
cv2.imshow('img1',img1)
cv2.imshow('img2', img2)
cv2.imshow('resultImgAnd', resultImgAnd)
cv2.imshow('resultImgOr', resultImgOr)
cv2.imshow('resultImgXor', resultImgXor)
cv2.imshow('resultImgNot', resultImgNot)
cv2.imshow('resultImgXorScalar', resultImgXorScalar)
cv2.waitKey(0)
main()
運行顯示的圖片截屏:

五、小結
本文詳細介紹了OpenCV-Python影像的加減乘除冪開方對數及位運算相關的函式及語法,并總結了相關函式的作用,OpenCV中影像存盤為矩陣,因此影像的運算其實就是矩陣的運算,影像的運算主要包括影像基礎算術運算、影像加權運算(又稱為影像融合)、按位運算等類別,這些運算可以直接通過numpy矩陣進行,也可以通過opencv的專用方法進行,但opencv的矩陣運算是飽和運算,其運算效果比純粹的矩陣運算效果更好,
更多OpenCV-Python介紹請參考專欄《OpenCV-Python圖形影像處理 》
專欄網址:https://blog.csdn.net/laoyuanpython/category_9979286.html
關于老猿的付費專欄
老猿的付費專欄《使用PyQt開發圖形界面Python應用 》(https://blog.csdn.net/laoyuanpython/category_9607725.html)專門介紹基于Python的PyQt圖形界面開發基礎教程,付費專欄《moviepy音視頻開發專欄》 (https://blog.csdn.net/laoyuanpython/category_10232926.html)詳細介紹moviepy音視頻剪輯合成處理的類相關方法及使用相關方法進行相關剪輯合成場景的處理,兩個專欄都適合有一定Python基礎但無相關知識的小白讀者學習,
付費專欄文章目錄:《moviepy音視頻開發專欄文章目錄》(https://blog.csdn.net/LaoYuanPython/article/details/107574583)、《使用PyQt開發圖形界面Python應用專欄目錄 》(https://blog.csdn.net/LaoYuanPython/article/details/107580932),
對于缺乏Python基礎的同仁,可以通過老猿的免費專欄《專欄:Python基礎教程目錄》(https://blog.csdn.net/laoyuanpython/category_9831699.html)從零開始學習Python,
如果有興趣也愿意支持老猿的讀者,歡迎購買付費專欄,

跟老猿學Python、學OpenCV!
? ? 前往老猿Python博文目錄 https://blog.csdn.net/LaoYuanPython ?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/184644.html
標籤:其他
