在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()
原图如下:
程序运行结果如下: