计算机视觉之OpenCV图像的基础操作

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)

从以上对比的结果可以发现,开启优化时间效率更高。

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值