计算机视觉之OpenCV图像的基础操作
程序员文章站
2022-03-25 20:37:15
...
9. 图像的基础操作
import cv2
import numpy as np
import matplotlib.pyplot as plt
for i in [cv2, np]:
print(i.__name__,": ",i.__version__,sep="")
输出:
cv2.cv2: 4.2.0
numpy: 1.17.4
# 定义显示图片函数
def showImage(img):
plt.figure()
plt.imshow(img)
plt.axis("off")
plt.show()
9.1 获取并修改像素值
# 根据行列坐标获取像素值
img = cv2.imread("1.jpg")
showImage(img)
px = img[100,100]
print(px)
blue = img[100,100,0]
print(blue)
px2 = img[100,100,1]
print(px2)
输出:
[252 154 100]
252
154
img[100,100] = [255,255,255]
print(img[100,100])
showImage(img)
输出:
[255 255 255]
可以看到坐标(100,100)附近有个白点,即是修改的像素值。
numpy是非常高效的运算库,对于获取和修改像素值,使用array.item()和array.itemset()会更好。
print(img.item(100,100,1))
img.itemset((200,100,0),255)
img.itemset((200,100,1),255)
img.itemset((200,100,2),255)
print(img[200,100])
showImage(img)
输出:
255
[255 255 255]
9.2 获取图像属性
图像属性:包括行、列、通道、图像数据类型、像素数目等
img = cv2.imread("1.jpg")
print("shape: ",img.shape)
print("number of pixel: ",img.size)
print("data type: ",img.dtype)
输出:
shape: (600, 800, 3)
number of pixel: 1440000
data type: uint8
9.3 图像ROI(Region of Interest)
img = cv2.imread("2.jpg")
print(img.shape)
showImage(img)
ball = img[20:100,50:90]
print(ball.shape)
img[200:280,100:140] = ball
print(img[273:333,100:160].shape)
showImage(img)
输出:
(280, 450, 3)
(80, 40, 3)
(7, 60, 3)
9.4 拆分及合并图像通道
img = cv2.imread("2.jpg")
b,g,r = cv2.split(img)
img = cv2.merge((b,g,r))
showImage(img)
输出:
img[:,:,2]=0 # 通道2像素值全部设为0
showImage(img)
输出:
9.5 为图像扩边(填充)
cv2.copyMakeBorder()函数通常在卷积运算或0填充时使用,参数如下:
- 1. src:输入图像
- 2. top,bottom,left,right:对应边界的像素数目
- 3. borderType:添加边界的类型
- cv2.BORDER_CONSTANT:添加常数值像素边界,需要value参数指定该常数
- cv2.BORDER_REFLECT:添加像素镜像对称,例如:fedcba|abcdefgh|hgfedcb
- cv2.BORDER_REFLECT101:与上面类似,微小差别,例如gfedcb|abcdefgh|gfedcba
- cv2.BORDER_REPLICATE:最后一个像素值被重复
- cv2.BORDER_WRAP:无法书面描述,类似cdefgh|abcdefgh|abcdefg
- 4. value:边界颜色
BLUE = [255,0,0]
img1 = cv2.imread("4.jpg")
constant = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_CONSTANT,value=BLUE)
reflect = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT101)
replicate = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REPLICATE)
warp = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_WRAP)
img_list = [img1,constant,reflect,reflect101,replicate,warp]
names_list = ["origin","constant","reflect","reflect101","replicate","warp"]
plt.figure(figsize=(10,5))
plt.subplots_adjust(wspace=0.1,hspace=0.1)
for i in range(len(img_list)):
plt.subplot(2,3,i+1)
plt.imshow(img_list[i])
plt.axis("off")
plt.title(names_list[i]+": "+str(img_list[i].shape))
plt.tight_layout()
plt.show()
输出:
10. 图像上的算术运算
学习函数:cv2.add(),cv2.addWeighted()等
10.1 图像加法
x = np.uint8([250,222,100])
y = np.uint8([10,20,30])
print(cv2.add(x,y))
print(x+y)
输出:
[[255]
[242]
[130]]
[ 4 242 130]
第一个输出结果:如果像素值相加后大于255,则取255。第二个输出结果:250+10=260%256=4。(因为uint8只能表示0-255之间的数)
10.2 图像混合
与图像加法类似,但可以设置权重。也就说图像加法类似普通加法,图像混合类似加权求和。
img1 = cv2.imread("1.jpg")
img1 = cv2.resize(img1,(500,500))
showImage(img1)
img2 = cv2.imread("2.jpg")
img2 = cv2.resize(img2,(500,500))
showImage(img2)
dst = cv2.addWeighted(img1,0.5,img2,0.5,0)
showImage(dst)
输出:
10.3 按位运算
按位操作有:AND,OR,NOT,XOR等。
如果将OpenCV标志放到另外的图像上。如果使用加法,则颜色被改变。如果使用混合,会产生透明效果。此时按位运算就派上用场了。
img1 = cv2.imread("2.jpg")
img2 = cv2.imread("3.jpg")
rows, cols, channels = img2.shape
roi = img1[0:rows,0:cols]
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
showImage(img2gray)
ret, mask = cv2.threshold(img2gray, 175, 255, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)
img1_bg = cv2.bitwise_and(roi, roi, mask=mask)
img2_fg = cv2.bitwise_and(img2,img2,mask=mask_inv)
dst = cv2.add(img1_bg, img2_fb)
img1[0:rows,0:cols] = dst
showImage(img1)
输出:
11. 程序性能检测及优化
学习函数:cv2.getTickCount, cv2.getTickFrequency
11.1 使用OpenCV检测程序效率
img1 = cv2.imread("1.jpg")
e1 = cv2.getTickCount()
for i in range(5,49,2):
img1 = cv2.medianBlur(img1,i)
e2 = cv2.getTickCount()
time = (e2 - e1)/ cv2.getTickFrequency()
print(time)
输出:
0.7994256561491656
import time
start = time.time()
for i in range(5,49,2):
img1 = cv2.medianBlur(img1,i)
end = time.time()
times = end - start
print(times)
输出:
0.7700002193450928
两种方法计算出的时间还是有一定的差别。
11.2 OpenCV中的默认优化
OpenCV中很多代码都被优化过,并且编译时默认开启了优化。使用cv2.useOptomized()来查看优化是否被开启,使用cv2.setUseOptimized()来开启优化。
cv2.useOptimized()
输出:
True
%timeit res = cv2.medianBlur(img1, 49)
输出:
33.3 ms ± 174 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
cv2.setUseOptimized(False)
cv2.useOptimized()
输出:
False
%timeit res = cv2.medianBlur(img1, 49)
输出:
35.8 ms ± 153 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
从以上对比的结果可以发现,开启优化时间效率更高。
上一篇: 《反制“项目破坏者”》手册
推荐阅读
-
OpenCV计算机视觉实战(Python)| 02、图像基本操作
-
深度学习02-(计算机视觉基础、图像色彩操作、图像形态操作理论)
-
OpenCV基础操作指南之图片的读取与写出
-
学习《OpenCV 2 计算机视觉编程手册》第二章遍历图像和领域操作实例——对图像进行锐化
-
详解Python+OpenCV进行基础的图像操作
-
OpenCV计算机视觉实战(Python)| 02、图像基本操作
-
深度学习02-(计算机视觉基础、图像色彩操作、图像形态操作理论)
-
计算机视觉之OpenCV图像的基础操作
-
CV:计算机视觉图像的基础知识—以python的cv2库来了解计算机视觉图像基础
-
OpenCV半小时掌握基本操作之图像基础操作