Opencv图像基础操作

Posted 陨星落云

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Opencv图像基础操作相关的知识,希望对你有一定的参考价值。

图像基础操作

  1. 图像在numpy.ndarray中的结构
    首先我们需要创建一幅2×2的3颜色通道图像:
#创建一幅2×2的3颜色通道图像,其中数字代表像素,np.uint8是numpy数据类型[0,255]
img = np.array([[[0,1,2],[3,4,5]],[[6,7,8],[9,10,11]]],np.uint8)
#查看图像numpy.ndarray中的结构
print(img)
#查看图像的行、列、颜色通道(BGR)
print(img.shape)
#在蓝色通道中,第1行第1列的像素
print(img[0,0,0])
#在蓝色通道中,第1行第2列的像素
print(img[0,1,0])
#在蓝色通道中,第2行第1列的像素
print(img[1,0,0])
#在绿色通道中,第1行第1列的像素
print(img[0,0,1])
#在红色通道中,第1行第1列的像素
print(img[0,0,2])
#3通道中,第1行第1列的像素
print(img[0,0])
[[[ 0  1  2]
  [ 3  4  5]]

 [[ 6  7  8]
  [ 9 10 11]]]
(2, 2, 3)
0
3
6
1
2
[0 1 2]

其中在蓝通道B中,0,3代表第一行,6,9代表第二行,如下图所示

 

2.图像属性

图像的属性包括:行,列,通道,图像数据类型,像素数目等

在opencv中,图像不是传统的RGB颜色通道,而是按BGR顺序存储的。

img_BGR = cv2.imread(\'citrus-fruit-colorful-delicious-2146386.jpg\') 
print(type(img_BGR)) # numpy.ndarray类型可以用numpy对图像进行各种操作
print(img_BGR.dtype) # 图像数据类型,一张图片的像素值范围是[0,255], 因此默认类型是unit8
print(img_BGR.shape[0]) # 行
print(img_BGR.shape[1]) # 列
print(img_BGR.shape[2]) # 通道
print(img_BGR.size) # 像素数目
print(img_BGR.max()) # 最大像素值
print(img_BGR.min()) # 最小像素值
print(img_BGR.mean()) #素值平均值
<class \'numpy.ndarray\'>
uint8
4864
3648
3
53231616
255
0
211.1315848273327

3.获取并修改像素值

根据像素的行和列的坐标获取他的像素值。

img = cv2.imread("art-art-exhibition-art-gallery-2110950.jpg")
px = img[100,100] # BGR3个通道中,第100行第100列的像素
print(px)
blue = img[100,100,0]# B通道中,第100行第100列的像素
print(blue)
[215 215 199]
215

修改像素值

img = cv2.imread("art-art-exhibition-art-gallery-2110950.jpg")
img[100,100]=[255,255,255]
print(img[100,100])
[255 255 255]

例子:使大于150的像素等于255(即使灰色像素变为白色)

img = cv2.imread("art-art-exhibition-art-gallery-2110950.jpg")
# 使大于150的像素等于255
img[img>150]=255
cv2.imwrite(\'img150.jpg\',img)

 

4.图像 ROI

有时你需要对一幅图像的特定区域进行操作。例如我们要检测一副图像中眼睛的位置,我们首先应该在图像中找到脸,再在脸的区域中找眼睛,而不是直接在一幅图像中搜索。这样会提高程序的准确性和性能。

ROI 也是使用 Numpy 索引来获得的。

例子:获取图像区域像素(即裁剪)

img = cv2.imread("art-art-exhibition-art-gallery-2110950.jpg")
px = img[700:2700,1200:3900] # 获取第700-2700行、第1200-3900列的像素
cv2.imwrite(\'cut.jpg\',img)

 

例子:选择橘子的部分并把他拷贝到原图像的其他区域。

img = cv2.imread("citrus-fruit-colorful-delicious-2146386.jpg")
#print(img.shape)
px = img[3000:4800,0:3600]
img[0:1800,0:3600]=px
cv2.imwrite(\'roi.jpg\',img)

 

5.拆分图像通道

有时我们需要对 BGR 三个通道分别进行操作。这是你就需要把 BGR 拆分成单个通道。

例子:只保留绿色通道

img = cv2.imread("beautiful-branch-bright-2275453.jpg")
#b,g,r=cv2.split(img) # 不推荐使用,原因耗时
img[:,:,0] = 0
#img[:,:,1] = 0
img[:,:,2] = 0
cv2.imwrite(\'g.jpg\',img)

 

6.为图像扩边(填充)

如果你想在图像周围创建一个边,就像相框一样,你可以使用 cv2.copyMakeBorder()函数。这经常在卷积运算或 0 填充时被用到。

copyMakeBorder(src, top, bottom, left, right, borderType[, dst[, value]])

这个函数参数意义如下:

  • src:表示图像的numpy.ndarray对象

  • top,bottom,left,right :上下左右边界各填充多少

  • borderType:

    BORDER_REPLICATE:复制法,也就是复制最边缘像素。

    BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb

    BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba

    BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg

    BORDER_CONSTANT:常量法,常数值填充。

  • value:当为BORDER_CONSTANT时,需要填充颜色可以是0或255(黑白),也可以是(0,0,255)BGR

img = cv2.imread("beautiful-branch-bright-2275453.jpg")
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)

top_size,bottom_size,left_size,right_size = (300,300,300,300)

replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)

reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_REFLECT)

reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101)

wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP)

constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_CONSTANT, value=(0,0,255))# 这里(0,0,255)为RGB,为蓝色

plt.figure(figsize=(12,5),dpi=100)
plt.subplot(231), plt.imshow(img, \'gray\'), plt.axis(\'off\'), plt.title(\'ORIGINAL\')
plt.subplot(232), plt.imshow(replicate, \'gray\'), plt.axis(\'off\'), plt.title(\'REPLICATE\')
plt.subplot(233), plt.imshow(reflect, \'gray\'), plt.axis(\'off\'), plt.title(\'REFLECT\')
plt.subplot(234), plt.imshow(reflect101, \'gray\'), plt.axis(\'off\'), plt.title(\'REFLECT_101\')
plt.subplot(235), plt.imshow(wrap, \'gray\'), plt.axis(\'off\'), plt.title(\'WRAP\')
plt.subplot(236), plt.imshow(constant, \'gray\'), plt.axis(\'off\'), plt.title(\'CONSTANT\')

由于是使用 matplotlib 绘制,所以交换 R 和 B 的位置,OpenCV 中是按 BGR,matplotlib 中是按 RGB 排列,因此,使用cv2.cvtColor(img,cv2.COLOR_BGR2RGB)将BGR转换为RGB。

 

参考资料:《数字图像处理》《OpenCV-Python 中文教程》

以上是关于Opencv图像基础操作的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV-Python3.OpenCV的图像基础操作

OpenCV基础---图像像素操作

Opencv 图像处理:图像基础操作与灰度转化

Opencv图像基础操作

OpenCV高手勿入! 半小时学会基本操作 图像基础操作

在 Python 多处理进程中运行较慢的 OpenCV 代码片段