图像的基本操作
目标:
- 访问并修改像素值
- 访问图像属性
- 设置感兴趣区域(ROI)
- 分割与合并图像
访问并修改像素值
首先加载一张图片
import numpy as np
import cv2 as cv
img = cv.imread("E:\opencv4.5.4\opencv\sources\samples\data\messi5.jpg")
#assert断言操作,条件为False时执行后面语句
assert img is not None,'File could not be read,check with os.path.exists()'
你可以通过行坐标列坐标来返回图像的像素值。BGR返回蓝、绿、红值的数组,灰度图返回相应的强度(intensity )。
#获取坐标100,100的像素值
px = img[100,100]
#只获取蓝色通道上坐标的值 0为B,1为G,2为R
blue = img[100,100,0]
#可以使用列表的切片操作来返回更多像素值
more_px = img[0:100,0:100]
提醒:最好不要使用numpy做单独像素值的操作。因为numpy是一个用于快速数组计算的优化库。
如果要访问单个像素可以使用array.item()和array.itemset()
array.item():访问图像单个像素值
array.itemset():对图像单个像素值进行修改
#访问红色通道指定位置的值
img.item(10,10,2)
#修改红色通道的值
img.itemset((10,10,2),100)
>>print(img.item(10,10,2))
100
访问图像属性
图像属性:包含行数、列数、通道数、图像类型、像素数等。
img.shape:访问图像的形状
img.size:访问图像的像素乘积数
img.dtype:访问图像数据类型
注:img.dtype 在调试时非常重要,因为 OpenCV-Python 代码中的大量错误是由无效数据类型引起的
>>print(img.shape)
(342,548,3)
>>print(img.size)
562248
>>print(img.dtype)
uint8
图像ROI(感兴趣的区域)
截取出图像中我们感兴趣的区域。
使用Numpy的索引进行操作。
img = cv.imread("E:\opencv4.5.4\opencv\sources\samples\data\messi5.jpg")
#截取出感兴趣的球区域,并将该区域的值赋值到另一个指定区域上
ball = img[280:340,330:390]
img[273:333,100:160] = ball
#显示图片
cv.imshow('messi',img)
cv.waitKey(0)
cv.destroyAllWindows()
分离和合并图像通道
有时我们需要单独处理图像的B\G\R通道,所以就引申了一个方法来分割BGR到单个通道。
cv.split():将参数中的图片分割为三个通道的值(若只传入灰度图则报错)
cv.merge():将分离的三个通道合并。注意传进去的是一个ndarray。
#通道分离
b,g,r = cv.split(img)
#通道合并
img = cv.merge((b,g,r))
#单独获取b通道
b = img[:,:,0]
#将Red通道所有值赋为0
img[:,:,2] = 0
最好不要使用cv.split,这是一个代价高昂的操作,最好使用numpy索引操作。
Red通道值为0时的图像如下:
为图像制作边框(Padding)
cv.copyMakeBorder() 参数如下:
- src - 输入的图像
- top,bottom,left,right - 各个方向上边框的宽度(像素数)
- borderType - 各个边框样式的参数
- cv.BORDER_CONSTANT - 添加恒定的彩色边框,若使用该参数,需额外加入一个value参数,设定颜色。
- cv.BORDER_REFLECT - 边框元素的镜面反射
- cv.BORDER_REFLECT_101 or cv.BORDER_DEFAULT - 与上面相同但略有变化
- cv.BORDER_REPLICATE - 最后一个元素被复制
- cv.BORDER_WRAP - 无法解释,看图
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
BLUE = [255,0,0]
img1 = cv.imread('opencv-logo.png')
assert img1 is not None, "file could not be read, check with os.path.exists()"
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)
plt.subplot(231),plt.imshow(img1,'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('REFLECT_101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')
plt.show()
效果如图:
总结
本篇文章展示了如何使用Opencv访问图像的属性或像素值,使用Numpy索引或内置函数对图像进行的一系列操作。
注:该文章为一篇学习笔记,可能有什么遗漏或者错误的地方,希望大家帮忙指正,感谢。