本节所涉及的操作主要是关于numpy的,而不是opencv,想要写出高效的opencv代码需要对numpy有很好的了解。
获取并修改像素值
首先加载一个彩色图像
import cv2 import numpy as np img = cv2.imread('test.jpg') # print(img.item(10, 10, 2)) # px = img[100, 100] # print(px)#返回一个数组 #只返回蓝色通道值 # blue = img[100, 100, 0] # print(blue) #修改像素值,修改在原地修改而不是副本修改 # img[100, 100] = [255, 255, 255] # print(img[100, 100]) #更好的访问和修改像素的方法 result = img.item(10, 10, 2) print(result) img.itemset((10, 10, 2), 100) print(img.item(10, 10, 2)) cv2.namedWindow('img', cv2.WINDOW_AUTOSIZE) cv2.imshow('img', img) cv2.waitKey(0) cv2.destroyAllWindows()
结果:每个人的图片都不一致,便不放上结果,只放上举例时用的图片
获取图像的属性
图像的属性包括图像的行列数,通道数,图像数据类型,像素点的数量等
图像的形状(长宽、通道)可以通过img.shape
得到,它将返回一个元组,包含图像的行列数以及通道数(若是彩色图的话)
import cv2 import numpy as np img = cv2.imread('test.jpg') #返回行列数和通道数 shape = img.shape print(shape) #获取图像的总的像素点的数目 size = img.size print(size) #查看图像的数据类型 type = img.dtype print(type) cv2.namedWindow('img', cv2.WINDOW_AUTOSIZE) cv2.imshow('img', img) cv2.waitKey(0) cv2.destroyAllWindows()
若图像是灰度图,返回的元组只包含行列数,所以检查载入的图像是灰度图还是彩色图像是一个有效的方法。
可通过img.size
获取图像的总的像素点的数目
- 图像的数据类型通过
img.dtype
查看 img.dtype
在debug的时候是非常有用的,因为大部分的opencv-python代码错误都是因为无效的数据类型造成的。
图像边界(Border)
如果你想给图像周围添加一个边框,类似于相框,你可以用cv2.copyMakeBorder()
函数。但是边界常常在卷积操作中应用更为多,比如边界填充0值。该函数有以下参数:
- src,输入的图像
- top,bottom,left,right,4个方向上边界宽度(像素为单位)
- borderType,定义需要添加的是什么类型的边界,它有以下值:
- cv2.BORDER_CONSTANT,常量填充边界,值由下一个参数value指定。
- cv2.BORDER_REFLECT,将会在边界上进行镜像操作。如fedcba|abcdefgh|hgfedcb
- cv2.BORDER_REFLECT_101或cv2.BORDER_DEFAULT,和上一个值BORDER_REFLECT类似,仅存在微小变换。如 gfedcb|abcdefgh|gfedcba
- cv2.BORDER_REPLICATE,使用最后一个元素进行重复填充,如aaaaaa|abcdefgh|hhhhhhh
- cv2.BORDER_WRAP,不做解释,它是这样的cdefgh|abcdefgh|abcdefg
- value,边界的颜色值(当boder的type是
cv2.BORDER_CONSTANT
时)
下面是一个示例代码,展示各种边界类型
import cv2 import numpy as np import matplotlib.pyplot as plt BLUE = [255, 0, 0] img = cv2.imread('opencv.png') replicate = cv2.copyMakeBorder(img, 10,10,10,10, cv2.BORDER_REPLICATE) reflect = cv2.copyMakeBorder(img, 10, 10, 10, 10, cv2.BORDER_REFLECT) reflect101 = cv2.copyMakeBorder(img, 10, 10,10, 10, cv2.BORDER_REFLECT_101) wrap = cv2.copyMakeBorder(img, 10, 10,10, 10, cv2.BORDER_WRAP) constant = cv2.copyMakeBorder(img, 10, 10,10, 10, cv2.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('REFLECT_101') plt.subplot(235), plt.imshow(wrap,'gray'), plt.title('WRAP') plt.subplot(236), plt.imshow(constant,'gray'), plt.title('CONSTANT') plt.show()
效果如下图所示:
举例时用的图片: