【Opencv3+Python3入門(3)圖像數組運算操作】

在python版本的opencv中圖像數據是以多維數組的形式讀取與操作的,因此利用opencv並結合numpy對圖像數據進行操作非常方便地可以對圖像某一位置像素數據或者某一區域的像素進行修改和添加等操作。還可以使用opencv中自帶的cv.bitwise_not(image)對圖像像素進行取反。

以及最基本的使用for循環來複制每個通道的像素,這樣會消耗更多時間。

1,圖像像素取反操作:

#3,圖像數組操作
import cv2 as cv
import numpy as np
def access_Pixels(image):
    print(image.shape);
    height = image.shape[0]
    width = image.shape[1]
    channels = image.shape[2]
    print("width : %s, height : %s channels : %s"%(width, height, channels))
    #建立一個圖像副本防止對後面其他圖像取反函數操作產生影響。
    temp=image.copy()
    for row in range(height):
        for col in range(width):
            for c in range(channels):
                pv = image[row, col, c]
                temp[row, col, c] = 255 - pv
    cv.namedWindow("pixels_demo",0)
    cv.imshow("pixels_demo", temp)
def access_Numpy(image):
    #利用了numpy數組的特性運算方式
    #在numpy中數組的運算可以直接同時進行四則運算;
    #也可以結合numpy的fancyindex對ROI即感興趣區域進行操作。
    dstImage=255-image
    cv.namedWindow('numpy_demo',0)
    cv.imshow('numpy_demo',dstImage)

def get_Inverse(image):
    #利用cv中的bitwise像素取反
    dstImage=cv.bitwise_not(image)
    cv.namedWindow("cvInverse_demo",0)
    cv.imshow("cvInverse_demo",dstImage)


srcImage1=cv.imread('F:\OutputResult\SrcImage\saber18.jpg')
srcImage2=cv.imread('F:\OutputResult\SrcImage\saber19.jpg')
cv.namedWindow("Saber1",0)
cv.imshow("Saber1",srcImage1)
cv.namedWindow("Saber2",0)
cv.imshow("Saber2",srcImage2)
#########################################################################################
#計算時間
t1=cv.getTickCount()
#通過for循環像素取反
access_Pixels(srcImage1)
t2=cv.getTickCount()
time1=(t2-t1)/cv.getTickFrequency()#getTickFrequency用於返回CPU的頻率,就是每秒的計時週期數
print("for循環執行像素取反程序時間爲:%s ms"%time1)
t1=cv.getTickCount()
#通過Numpy像素取反
access_Numpy(srcImage1)
t2=cv.getTickCount()
time2=(t2-t1)/cv.getTickFrequency()#getTickFrequency用於返回CPU的頻率,就是每秒的計時週期數
print("numpy執行像素取反程序時間爲:%s ms"%time2)
t3=cv.getTickCount()
#通過cv.bitwise_not函數取反
get_Inverse(srcImage1)
t4=cv.getTickCount()
time3=(t4-t3)/cv.getTickFrequency()#getTickFrequency用於返回CPU的頻率,就是每秒的計時週期數
print("cv執行像素取反該程序時間爲:%s ms"%time3)
#########################################################################################
#結束顯示
cv.waitKey(0)
cv.destroyAllWindows()

 程序運行效果如下:

可以發現各自的運行時間差異還是比較大的。

(450, 720, 3)
width : 720, height : 450 channels : 3
for循環執行像素取反程序時間爲:1.8634044 ms
numpy執行像素取反程序時間爲:0.0079533 ms
cv執行像素取反該程序時間爲:0.0216783 ms

顯示兩幅原始圖像:

 

通過像素for循環取反,Numpy取反操作,cv.bitwise_not()函數取反操作:

 

2.cv.bitwise_and(),cv.bitwise_or(),cv.bitwise_xor()圖像的與,或,異或運算:

import cv2 as cv
import numpy as np

def image_Operate(image1,image2):
    #兩幅圖像與,或,異或運算
    dstImage2=cv.bitwise_and(image1,image2)
    dstImage3=cv.bitwise_or(image1,image2)
    dstImage4=cv.bitwise_xor(image1,image2)
    cv.namedWindow("and_demo",0)
    cv.imshow("and_demo",dstImage2)
    cv.namedWindow("or_demo",0)
    cv.imshow("or_demo",dstImage3)
    cv.namedWindow("xor_demo",0)
    cv.imshow("xor_demo",dstImage4)

srcImage1=cv.imread('F:\OutputResult\SrcImage\saber18.jpg')
srcImage2=cv.imread('F:\OutputResult\SrcImage\saber19.jpg')
cv.namedWindow("Saber1",0)
cv.imshow("Saber1",srcImage1)
cv.namedWindow("Saber2",0)
cv.imshow("Saber2",srcImage2)
#########################################################################################
#圖像的與,或,異或運算
image_Operate(srcImage1,srcImage2)
#結束顯示
cv.waitKey(0)
cv.destroyAllWindows()

圖像的與或非等邏輯運算:
利用opencv中函數:cv.bitwise_and(),cv.bitwise_or(),cv.bitwise_xor()圖像的與,或,異或運算:
兩幅輸入圖像要求需要滿足:
where arrays have the same size and type
array op scalar
array op array
scalar op array
不然會報錯,運行失敗。

圖像加減乘除運算:

利用Opencv中的加減乘除函數即可完成:

程序如下:

#圖像加減乘除操作
import cv2 as cv
import numpy as np

def imageAdd(image1,image2):
    dst=cv.add(image1,image2)
    cv.namedWindow("add_demo",0)
    cv.imshow("add_demo",dst)
def imageSubtract(image1,image2):    
    dst=cv.subtract(image1,image2)
    cv.namedWindow("subtract_demo",0)
    cv.imshow("subtract_demo",dst)
def imageMultiply(image1,image2):
    dst=cv.multiply(image1,image2)
    cv.namedWindow("multiply_demo",0)
    cv.imshow("multiply_demo",dst)
def imageDivide(image1,image2):
    dst=cv.divide(image1,image2)
    cv.namedWindow("divide_demo",0)
    cv.imshow("divide_demo",dst)
src1=cv.imread("F:\OutputResult\SrcImage\python3.jpg")
src2=cv.imread("F:\OutputResult\SrcImage\windows1.jpg")

#加減乘除兩幅輸入圖像的類型大小高寬應該相同。
src1=cv.resize(src1,(512,512),cv.INTER_CUBIC)
src2=cv.resize(src2,(512,512),cv.INTER_CUBIC)
cv.imshow("src1",src1)
cv.imshow("src2",src2)
print(src1.shape,src2.shape)
imageDivide(src1,src2)
cv.waitKey(0)
cv.destroyAllWindows()

原圖如下:

程序運行結果如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章