Opencv在圖像上的算術運算

圖像上的算術運算

1.圖像加法

圖像相加:一般用于對同一場景的多幅圖像求平均,以便有效地降低(additive)隨機噪聲。

利用求平均的方法降低噪聲信號提高信噪比的做法,只有當噪聲可以用同一個獨立分布的隨機模型描述時才會有效。

作用:圖像混合和降噪

使用函數 cv2.add() 將兩幅圖像進行加法運算,當然也可以直接使用 numpy,res=img1+img。兩幅圖像的大小,類型必須一致,或者第二個圖像可以使一個簡單的標量值。

cv2.add(src1, src2, mask) 

參數意義如下:

  • scr1:輸入的第一幅圖像
  • scr2:輸入的第二幅圖像
  • mask:可選,掩膜

補充:在有些圖像處理的函數中有的參數里面會有mask參數,即此函數支持掩膜操作,首先何為掩膜以及有什么用,如下:

數字圖像處理中的掩膜的概念是借鑒于PCB制版的過程,在半導體制造中,許多芯片工藝步驟采用光刻技術,用于這些步驟的圖形“底片”稱為掩膜(也稱作“掩模”),其作用是:在硅片上選定的區域中對一個不透明的圖形模板遮蓋,繼而下面的腐蝕或擴散將只影響選定的區域以外的區域。
圖像掩膜與其類似,用選定的圖像、圖形或物體,對處理的圖像(全部或局部)進行遮擋,來控制圖像處理的區域或處理過程。
數字圖像處理中,掩模為二維矩陣數組,有時也用多值圖像,圖像掩模主要用于:
①提取感興趣區,用預先制作的感興趣區掩模與待處理圖像相乘,得到感興趣區圖像,感興趣區內圖像值保持不變,而區外圖像值都為0。
②屏蔽作用,用掩模對圖像上某些區域作屏蔽,使其不參加處理或不參加處理參數的計算,或僅對屏蔽區作處理或統計。
③結構特征提取,用相似性變量或圖像匹配方法檢測和提取圖像中與掩模相似的結構特征。
④特殊形狀圖像的制作。

區別:OpenCV 中的加法與 Numpy 的加法是有所不同的。OpenCV 的加法是一種飽和操作,而 Numpy 的加法是一種模操作。

例子:

x = np.uint8([250])
y = np.uint8([10])
print(x+y) # 250+10 = 260 % 256 = 4
print(cv2.add(x,y))  # 250+10 = 260 => 255
[4]
[[255]]

這種差別在你對兩幅圖像進行加法時會更加明顯。OpenCV 的結果會更好一點。所以我們盡量使用 OpenCV 中的函數。

例子

import cv2
import matplotlib.pyplot as plt
import numpy as np

def img_show(name,img):
    """matplotlib圖像顯示函數
    name:字符串,圖像標題
    img:numpy.ndarray,圖像
    """
    img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    plt.imshow(img,'gray')
    plt.xticks([])
    plt.yticks([])
    plt.xlabel(name,fontproperties='FangSong',fontsize=12)
    

if __name__=="__main__":

    img1 = cv2.imread("art-art-exhibition-art-gallery-2110950.jpg")
    img2 = cv2.imread("art-exhibition-art-gallery-artwork-2110937.jpg")
    print(img1.shape)
    print(img2.shape)
    img3 = img1.copy() # 復制img1
    img3 = img3[:3339,:5008] # 裁剪圖像使img3與img2圖像大小一致
    print(img3.shape)
    img4 = img2+img3
    img5 = cv2.add(img2,img3)
    # 圖像顯示
    plt.figure(figsize=(12,8),dpi=80)
    plt.subplot(221)
    img_show('img2',img2)
    plt.subplot(222)
    img_show('img3',img3)
    plt.subplot(223)
    img_show('numpy中img2+img3',img4)
    plt.subplot(224)
    img_show('Opencv中img2+img3',img5)
(3351, 5026, 3)
(3339, 5008, 3)
(3339, 5008, 3)
加法.png

2.圖像混合

cv2.scaleAdd(InputArray src1, double alpha, InputArray src2, OutputArray dst)

可以按下面的公式對圖片進行混合操作
d s t=\alpha \cdot src 1+ src 2

cv2.addWeighted(InputArray src1, double alpha, InputArray src2,double beta, double gamma,OutputArray dst, int dtype=-1)

這其實也是加法,但是不同的是兩幅圖像的權重不同,這就會給人一種混合或者透明的感覺。圖像混合的計算公式如下:
g(x)=(1-\alpha) f_{0}(x)+\alpha f_{1}(x)
通過修改 α 的值(0 → 1),可以實現非??岬幕旌稀,F在我們把兩幅圖混合在一起。第一幅圖的權重是 0.6,第二幅圖的權重是 0.4。函數 cv2.addWeighted() 可以按下面的公式對圖片進行混合操作。
d s t=\alpha \cdot src 1+\beta \cdot src 2+\gamma
這里γ的取值為 0。

img1 = cv2.imread("fashion-fun-model-2191055.jpg")
img2 = cv2.imread("delicious-food-food-photography-2111987.jpg")
print(img1.shape)
print(img2.shape)
img3 = img1.copy()
img3 = img3[:4611,:3451]
print(img3.shape)

dst = cv2.addWeighted(img2,0.6,img3,0.4,0)

plt.figure(figsize=(8,20),dpi=80)
plt.subplot(131)
img_show('img2',img2)
plt.subplot(132)
img_show('img3',img3)
plt.subplot(133)
img_show('圖像混合',dst)
(6000, 4000, 3)
(4611, 3451, 3)
(4611, 3451, 3)
圖像混合.png

3.圖像相減

圖像相減即在兩幅圖像之間對應像素做減法運算。圖像相減可以檢測出兩幅圖像的差異信息,因此這項技術在工業、醫學、氣象以及軍事等領域中都有廣泛的應用。
主要應用:
(1)去除一幅圖像中不需要的圖案,如緩慢變化的背景陰影,周期性噪聲等;
(2)檢測同一場景的兩幅圖像之間的變化
(3)運動檢測

cv2.subtract(src1, src2, mask)

參數意義參見cv2.add()。

img1 = cv2.imread("lenaNoise.png")
img2 = cv2.imread("lena.jpg")

img3 = cv2.subtract(img1,img2)

plt.figure(figsize=(10,8),dpi=80)
plt.subplot(231)
img_show('lenaNoise',img1)
plt.subplot(232)
img_show('lena',img2)
plt.subplot(233)
img_show('圖像相減',img3)
subtract.png

4.乘法運算

可以用來實現掩模處理,即屏蔽掉圖象的某些部分。此外由于時域的卷積和相關運算與頻域的乘積運算對應,因此乘法運算有時也被用來做為一種技巧來實現卷積或相關處理。

cv2.multiply(src1, src2)

5.除法運算

可用于校正成像設備的非線性影響,在特殊形態的圖像(如斷層掃描等醫學圖像)處理中用到。也可用于校正照明不足或者傳感器的非線性影響造成的偏差。

cv2.divide(src1, src2)

6.按位運算

按位操作有:AND,OR,NOT,XOR 等。

  • bitwise_and是對二進制數據進行“與”操作,即對圖像(灰度圖像或彩色圖像均可)每個像素值進行二進制“與”操作,1&1=1,1&0=0,0&1=0,0&0=0
  • bitwise_or是對二進制數據進行“或”操作,即對圖像(灰度圖像或彩色圖像均可)每個像素值進行二進制“或”操作,1|1=1,1|0=0,0|1=0,0|0=0
  • bitwise_xor是對二進制數據進行“異或”操作,即對圖像(灰度圖像或彩色圖像均可)每個像素值進行二進制“異或”操作,1 ^ 1=0,1 ^ 0=1,0 ^ 1=1,0 ^ 0=0
  • bitwise_not是對二進制數據進行“非”操作,即對圖像(灰度圖像或彩色圖像均可)每個像素值進行二進制“非”操作,~ 1=0,~ 0=1
cv2.bitwise_and(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray()) # dst = src1 & src2
cv2.bitwise_or(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray()) # dst = src1 | src2
cv2.bitwise_xor(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray()) # dst = src1 ^ src2
cv2.bitwise_not(InputArray src, OutputArray dst,InputArray mask=noArray()) # dst = ~src

當我們提取圖像的一部分,選擇非矩形 ROI 時這些操作會很有用(下一章你就會明白)。下面的例子就是教給我們如何改變一幅圖的特定區域。我想把 OpenCV 的標志放到另一幅圖像上。如果我使用加法,顏色會改變,如果使用混合,會得到透明效果,但是我不想要透明。如果它是矩形我可以使用 ROI。但是它不是矩形。但是我們可以通過下面的按位運算實現:

img1 = cv2.imread("delicious-food-food-photography-2111987.jpg")
img2 = cv2.imread("opencv-logo.png")

# 創建一個ROI,并放在左上角
rows,cols,channels = img2.shape
roi = img1[0:rows,0:cols]

# 創建一個mask,并創建一個inverse mask
img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
ret,mask = cv2.threshold(img2gray,175,255,cv2.THRESH_BINARY) #閾值處理,后面內容會詳細介紹
mask_inv = cv2.bitwise_not(mask)

# logo的白色區域為感興趣的區域ROI
# 取roi中與mask中不為零的值對應的像素的值,其他值為0
# 注意這里必須有mask=mask或者mask=mask_inv,其中mask=不能忽略
img1_bg = cv2.bitwise_and(roi,roi,mask=mask)
# 取roi中與mask_inv中不為零的值對應的像素的值,其他值為0。
# Take only region of logo from logo image.
img2_fg = cv2.bitwise_and(img2,img2,mask=mask_inv)

# 將logo中的ROI放到主圖像中
dst = cv2.add(img1_bg,img2_fg)
img3 = img1.copy()
img3[0:rows,0:cols] = dst

# 顯示圖像
plt.figure(figsize=(20,8),dpi=80)
plt.subplot(241)
img_show('img1',img1)
plt.subplot(242)
img_show('img2',img2)
plt.subplot(243)
img_show('roi',roi)
plt.subplot(244)
img_show('mask',mask)
plt.subplot(245)
img_show('mask_inv',mask_inv)
plt.subplot(246)
img_show('img2_fg',img1_bg)
plt.subplot(247)
img_show('img2_fg',img2_fg)
plt.subplot(248)
img_show('圖像混合',img3)
位caozuo.png

7.其他算數運算

cv2.sqrt(InputArray src, OutputArray dst) # 計算每個矩陣元素的平方根
cv2.pow(InputArray src, double power, OutputArray dst) # src的power次冪
cv2.exp(InputArray src, OutputArray dst) # dst = e**src(**表示指數的意思)
cv2.log(InputArray src, OutputArray dst) # dst = log(abs(src))

更多詳情請參考opencv官網。

參考資料:
網址:
https://blog.csdn.net/Gavinmiaoc/article/details/80856246
https://blog.csdn.net/u011028345/article/details/77278467
書籍:《數字圖像處理》《OpenCV-Python-Toturial-中文版》

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370