【OpenCV】第2章 核心操作

目录

2.1 图像基本操作

2.1.1 访问和修改像素值

 2.1.2 获取图片属性

2.1.3 图片分割

2.1.4 分割与合并通道

2.1.5 为图像创建边框

2.2 图像的运算

2.2.1 图像的加法

2.2.2 图像混合

2.2.3 图片位运算

2.3 性能测量和改进技术

2.3.1 用OpenCV测量代码性能

2.3.2 OpenCV中的默认优化


OpenCV: Core Operationshttps://docs.opencv.org/4.1.1/d7/d16/tutorial_py_table_of_contents_core.html

2.1 图像基本操作

OpenCV: Basic Operations on Imagesicon-default.png?t=L9C2https://docs.opencv.org/4.1.1/d3/df2/tutorial_py_basic_ops.html

2.1.1 访问和修改像素值

import numpy as np
import cv2 as cv
import os

# 图片读取
img_path = os.getcwd() + r"\resources\02\keji.jpeg"
img = cv.imread(img_path)

print(img.shape)

print(img[100,100]) #一个像素值,bgr

print(img[100,100,0]) #像素值的b值

#注意,不要一个一个像素改,要学会用numpy加速

 2.1.2 获取图片属性

import numpy as np
import cv2 as cv
import os

# 图片读取
img_path = os.getcwd() + r"\resources\02\keji.jpeg"
img = cv.imread(img_path)

print(img.shape)
print(img.size) #多少个数据,461x640x3
print(img.dtype)#数据类型


#访问和修改像素更好的方法
#访问
print(img.item(10,10,2))

#修改
img.itemset((10,10,2),100) #将图片10X10位置像素的r值改为100
print(img.item(10,10,2))

2.1.3 图片分割

 

#比如我们要截取图片左上角、中间的一部分
import numpy as np
import cv2 as cv
import os

# 图片读取
img_path = os.getcwd() + r"\resources\02\keji.jpeg"
img = cv.imread(img_path)

img_leftup = img[0:300,0:300]
cv.imshow("img_leftup",img_leftup)
cv.waitKey(0)
cv.destroyAllWindows()

 

 

2.1.4 分割与合并通道

#比如我们要截取图片左上角、中间的一部分
import numpy as np
import cv2 as cv
import os

# 图片读取
img_path = os.getcwd() + r"\resources\02\keji.jpeg"
img = cv.imread(img_path)

#分割通道
b,g,r = cv.split(img)

#合并通道
img = cv.merge((b,g,r))

注意:split是个耗时的操作,必要时才需要,否则,最好用numpy索引(如:img[0:300,0:300])

2.1.5 为图像创建边框

(在jupyter编辑)如果不知道函数的参数,按住Shift 并双击tab,即会打开函数说明。

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
import os

BLUE = [255,0,0]

img_path = os.getcwd() + r"\resources\02\115.jpg"
img=cv.imread(img_path,1)

#转为rgb
b,g,r = cv.split(img)
img=cv.merge((r,g,b))

replicate = cv.copyMakeBorder(img, 20, 20,20,20,cv.BORDER_REPLICATE)  #复制边缘像素
reflect = cv.copyMakeBorder(img,20, 20,20,20,cv.BORDER_REFLECT) #镜像边缘像素
reflect101 = cv.copyMakeBorder(img,20, 20,20,20,cv.BORDER_REFLECT101) #镜像边缘像素
wrap = cv.copyMakeBorder(img,20, 20,20,20,cv.BORDER_WRAP)
constant = cv.copyMakeBorder(img,20, 20,20,20,cv.BORDER_CONSTANT,value=BLUE) #加上特定颜色的边框


#显示
plt.subplot(231),plt.imshow(img,'gray'),plt.title('ORIGINAL')
plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('replicate')
plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('reflect')
plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('reflect101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('wrap')
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('constant')

plt.show()

 

2.2 图像的运算

OpenCV: Arithmetic Operations on Images

2.2.1 图像的加法

x = np.uint8([250])
y = np.uint8([10])
print(cv.add(x,y)) # 250+10 = 260 => 255 ,最大只能是255

print( x+y )          # 250+10 = 260 % 256 = 4 ,这个就溢出了

import numpy as np
import cv2 as cv
import os

# 图片读取
img_path1 = os.getcwd() + r"\resources\02\keji.jpeg"
img1 = cv.imread(img_path1)
img1 = cv.resize(img1,(300,300))  #注意矩阵大小一致

img_path2 = os.getcwd() + r"\resources\02\115.jpg"
img2 = cv.imread(img_path2)
img2 = cv.resize(img2,(300,300))

img3 = cv.add(img1,img2)
cv.imshow("img3",img3)
cv.waitKey(0)
cv.destroyAllWindows()

 

2.2.2 图像混合

这个也是图像的加法,只不过两个加起来时各自的权重不同

其中:α的取值范围是0-1
下面是变换后的公式

import cv2 as cv
import os

img1 = cv.imread(os.getcwd()+ r"\resources\02\ml.png")
img1 = cv.resize(img1,(196,233))
img2 = cv.imread(os.getcwd()+ r"\resources\02\opencv-logo.png")
img2 = cv.resize(img2,(196,233))
dst = cv.addWeighted(img1,0.7,img2,0.3,0)  #相当于减淡了img2
cv.imshow('dst',dst)
cv.waitKey(0)
cv.destroyAllWindows()

 

2.2.3 图片位运算

这个包含与,或,非和异或操作,在提取图片的任何一部分、非矩形剪切时非常有用。
现在,我想把opencv的logo放在一幅图上面,如果用add叠加,图片颜色会改变。如果用混合的办法,只能是透明度的变化。下面看下如何叠加logo更加显眼。

#加载图片
import cv2 as cv
import os
import typing

img1 = cv.imread(os.getcwd() + r"\resources\02\robot.jpeg")
img2 = cv.imread(os.getcwd() + r"\resources\02\opencv-logo.png")

def img_show(name:str,img, time:int): #1 表示略过,0 表示一直显示,除非按enter跳过
    cv.imshow(name,img)
    cv.waitKey(time)
    cv.destroyAllWindows()

#获取img2的shape
rows,cols,channels = img2.shape
roi = img1[0:rows,0:cols] #按照图像2的大小获取图片1的区域(剪切)

img2gray = cv.cvtColor(img2, cv.COLOR_BGR2GRAY)#将图片2转为灰度图
ret, mask = cv.threshold(img2gray, 10, 255, cv.THRESH_BINARY) #将10作为阈值,小于10,置为0,大于10,置为255,相当于做二值化处理
img_show("mask", mask, 0)  

mask_inv = cv.bitwise_not(mask)  #图像反转,即非操作
img_show("mask_inv", mask_inv, 0)

img1_bg = cv.bitwise_and(roi, roi, mask = mask_inv)  #mask表示要用什么盖住
img_show("img1_bg", img1_bg, 0)

img2_fg = cv.bitwise_and(img2, img2, mask = mask)
img_show("img2_fg", img2_fg, 0)

dst = cv.add(img1_bg,img2_fg)
img1[0:rows, 0:cols] = dst  #修改img1的像素
img_show("img1", img1, 0)

 

 

2.3 性能测量和改进技术

OpenCV: Performance Measurement and Improvement Techniquesicon-default.png?t=L9C2https://docs.opencv.org/4.1.1/dc/d71/tutorial_py_optimization.html

2.3.1 用OpenCV测量代码性能

import cv2 as cv

start = cv.getTickCount() #开始计时点

#代码
for i in range(100000):
    pass

end = cv.getTickCount() #再次计时点

time = (end - start)/cv.getTickFrequency()  #运行代码所用的时间,单位是秒

print(time)

 ​​​​​​​

2.3.2 OpenCV中的默认优化

  OpenCV中的很多函数是用SSE2,AVX等优化的,当然也包含非优化代码。如果我们的系统支持,那么我们就应该使用优化代码,从而提高运行速度。你可以用cv.useOptimized()来检查系统是否可以用优化代码,并且用cv.setUseOptimized()来设置是否使用优化功能。代码优化是默认设置

import cv2 as cv
import os

img = cv.imread(os.getcwd() + r"\resources\02\keji.jpeg")

# print(cv.useOptimized())
# cv.setUseOptimized(True)

start = cv.getTickCount()

for i in range(5,49,2):
    img = cv.medianBlur(img,i)  #中值滤波
    
end = cv.getTickCount()
time = (end-start)/cv.getTickFrequency()

print(str(time) + " s")

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

维度攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值