opencv - 2 - 核心操作
一、图像的基本操作
1、访问像素值并修改它们
当成一个三维数组访问即可
import cv2 as cv
import numpy as np
img = cv.imread("img/1.png")
oneElement = img[100,100]
print(oneElement)
# 会得到[51 35 2]
oneElementColor = img[100,100,0]
print(oneElementColor)
# 会得到51
2、访问图像属性
图像属性包括行数,列数和通道数,图像数据类型,像素数等
- img.shape 得到行,列和通道数的元组(如果图像是彩色的)
- img.shape 得到行,列(如果图像是灰度的)
- img.size 得到要素数量
- img.dtype 得到图像数据类型,一般为uint8
3、设置感兴趣区域(ROI)
本质上就是数组切割
import cv2 as cv
import numpy as np
img = cv.imread("img/1.png")
ball = img[280:340, 330:390]
cv.imshow("ball",ball)
cv.waitKey(0)
cv.destroyAllWindows()
img[273:333, 100:160] = ball
甚至还能把这个img又赋值回原来图像中的一部分
4、分割和合并图像
import cv2 as cv
import numpy as np
img = cv.imread("img/1.png")
b,g,r = cv.split(img)
# 可以将彩色通道拆分成为三个灰度通道,主要这三个灰度通道的shape都是二维数组
print(b.shape)
print(g.shape)
print(r.shape)
# b[:,:] = 0
img = cv.merge((b,g,r))
# 对通道进行修改之后又可以合成为彩色通道
cv.imshow("image",img)
cv.waitKey(0)
cv.destroyAllWindows()
5、图像边框
cv.copyMakeBorder()
replicate = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REPLICATE)
reflect = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT)
reflect101 = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT_101)
wrap = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_WRAP)
constant= cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_CONSTANT,value=BLUE)
二、改变颜色空间
即将图像从一个色彩空间转换到另一个色彩空间
只有两个最广泛使用的,BGR↔灰色和BGR↔HSV。
(HSV的色相范围为[0,179],饱和度范围为[0,255],值范围为[0,255]。不同的软件使用不同的规模。因此,如果你要将OpenCV值和它们比较,你需要将这些范围标准化。)
img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
得到
img = cv.cvtColor(img, cv.COLOR_BGR2HSV)
得到
通过hsv可以更好的选中色彩方位
import cv2 as cv
import numpy as np
cap = cv.VideoCapture(0)
while True:
_,frame = cap.read()
hsv = cv.cvtColor(frame,cv.COLOR_BGR2HSV)
lower_blue = np.array([110,50,50])
upper_blue = np.array([130,255,255])
mask = cv.inRange(hsv, lower_blue, upper_blue)
# 得到一个只在有效范围内不是0的区域
res = cv.bitwise_and(frame,frame, mask=mask)
# 只显示在mask范围内的frame
# cv.imshow('hsv', hsv)
cv.imshow('res', res)
# cv.imshow('mask', mask)
# cv.imshow('frame',frame)
k = cv.waitKey(5) & 0xFF
if k == 27:
break
cv.destroyAllWindows()
- 1、先转换为hsv
hsv = cv.cvtColor(frame,cv.COLOR_BGR2HSV)
lower_blue = np.array([110,50,50])
upper_blue = np.array([130,255,255])
mask = cv.inRange(hsv, lower_blue, upper_blue)
- 2、再根据hsv的色彩范围选中区域,形成roi
mask = cv.inRange(hsv, lower_blue, upper_blue)
- 3、再用and将原图与原图合成,并只显示roi内的内容
res = cv.bitwise_and(frame,frame, mask=mask)
三、图像变换
1、放大缩小
import cv2 as cv
import numpy as np
import math
img1 = cv.imread("img/1.png")
cv.imshow("img1",img1)
height,width = img1.shape[:2]
# 方法1
# 注意传入的dsize参数必需是整数,所以需要一个取整函数
img2 = cv.resize(img1,(math.ceil(0.25*width), math.ceil(0.25*height)), interpolation = cv.INTER_CUBIC)
cv.imshow("img2",img2)
# 方法2
img3 = cv.resize(img1,None,fx=0.5, fy=0.5, interpolation = cv.INTER_CUBIC)
cv.imshow("img3",img3)
cv.waitKey(0)
cv.destroyAllWindows()
2、平移
width =列数,height =行数
利于图像与该矩阵相乘即可得到移动后的矩阵
tx为x轴上移动的距离
ty为y轴上移动的距离
import numpy as np
import cv2 as cv
img = cv.imread('img/1.png',0)
rows,cols = img.shape
M = np.float32([[1,0,100],[0,1,50]])
dst = cv.warpAffine(img,M,(cols,rows))
# 最后一个参数为图像的大小
cv.imshow('img',dst)
cv.waitKey(0)
cv.destroyAllWindows()
四、形态学变换
import cv2 as cv
import numpy as np
img = cv.imread('img/1.png')
kernel = np.ones((5,5),np.uint8)
img1 = cv.erode(img,kernel,iterations = 1) # 侵蚀,黑色部分将扩大,会把一些白色噪点去除
img2 = cv.dilate(img,kernel,iterations = 1) # 扩张,扩大白色部分,会放大噪点,但是会连接白色的损坏部分
img3 = cv.morphologyEx(img,cv.MORPH_OPEN,kernel) # 开运算,先侵蚀以去除噪点,再扩张,放大白色特征,还能在纤细处分离物体
img4 = cv.morphologyEx(img,cv.MORPH_CLOSE,kernel) # 闭运算,先扩张再侵蚀,填充物体内细小空间,连接邻近物体和平滑边界
img5 = cv.morphologyEx(img, cv.MORPH_GRADIENT, kernel) # 形态学梯度,用扩张减去侵蚀,即可得到边界范围
img6 = cv.tophat = cv.morphologyEx(img, cv.MORPH_TOPHAT, kernel) #顶帽 ,输入图像和图像开运算之差,用于显示阴影区域
img7 = cv.morphologyEx(img, cv.MORPH_BLACKHAT, kernel) # 黑帽,输入图像和图像闭运算之差,用于显示阴影区域
cv.imshow("img",img)
cv.imshow("img1",img1)
cv.imshow("img2",img2)
cv.imshow("img3",img3)
cv.imshow("img4",img4)
cv.imshow("img5",img5)
cv.imshow("img6",img6)
cv.imshow("img7",img7)
cv.waitKey(0)
cv.destroyAllWindows()
img:
img1:
img2:
img4:
img5:
img6:
img7: