opencv与numpy的图像基本操作

作者:邹成卓 时间:2022-06-20 12:20:10 

1. 像素基本操作

1.1 读取、修改像素

可以通过[行,列]坐标来访问像素点数据,对于多通道数据,返回一个数组,包含所有通道的值,对于单通道数据(如gray),返回指定坐标的值,也可以通过 [行,列,通道index] 来访问某坐标某通道的值。


>>> import cv2
>>> import numpy as np
>>> img = cv2.imread('messi5.jpg')

>>> px = img[100,100]
>>> print( px )
[157 166 200]
# accessing only blue pixel
>>> blue = img[100,100,0]
>>> print( blue )
157

可以直接通过坐标修改像素值


>>> img[100,100] = [255,255,255]
>>> print( img[100,100] )
[255 255 255]

然而直接像上面这样去读取、修改每个像素的值,效率是比较低的,可以使用下面的方法,效率是更高的


# accessing RED value
>>> img.item(10,10,2)
59
# modifying RED value
>>> img.itemset((10,10,2),100)
>>> img.item(10,10,2)
100

1.2 读取图像属性

读取图像尺寸,返回一个元组 (行,列,通道数)


>>> print( img.shape )
(342, 548, 3)

读取像素大小, 行 通道数


>>> print( img.size )
562248

像素数据类型


>>> print( img.dtype )
uint8

1.3 图像ROI操作

可以直接编辑像素区域,例如把图像左下角50*50的像素复制到左上角


import cv2
import numpy as np
img = cv2.imread("test.jpg")
print(img.shape)
roiTest = img[475:525, 0:50]
img[0:50, 0:50] = roiTest
cv2.imshow("image",img)
cv2.waitKey(0)

opencv与numpy的图像基本操作

1.4 分割、合并通道

有些情况下需要对图像的某一通道数据进行操作,此时会用到分割、合并通道数据


>>> b,g,r = cv2.split(img)
>>> img = cv2.merge((b,g,r))

或者


b = img[:,:,0]

假设想编辑红色通道的数据,全部设置为0,不需要这样分割后编辑, img[:,:,2] = 0 这样即可。cv2.split操作是一个很耗时的操作,可以用numpy索引替代的操作,尽量用numpy索引来做。

1.4 生成图像边框

使用 cv2.copyMakeBorder 函数可添加图像边框,支持多种边框算法


void cv::copyMakeBorder (
InputArray src, //原图
//目标图(cpp版本中,若传入此数据且选BORDER_TRANSPARENT,则此数据被top/bottom/left/right切出来的roi部分不会被做任何修改,此图像大小=dst.rows+top+bottom,dst.cols+left+right)
OutputArray dst,
int top, //top/left/bottom/right 四个方向上的边框像素
int bottom,
int left,
int right,
int borderType, //边框类型见下图
const Scalar & value = Scalar() //边框类型为BORDER_CONSTANT时的边框像素
)

opencv与numpy的图像基本操作


BLUE = [255, 0, 0]
img1 = cv2.imread("test.jpg")
replicate = cv2.copyMakeBorder(img1, 100, 100, 100, 100, cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img1, 100, 100, 100, 100, cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img1, 100, 100, 100, 100, cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img1, 100, 100, 100, 100, cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img1, 100, 100, 100, 100, cv2.BORDER_CONSTANT, value=BLUE)
print(img1.shape, reflect.shape)
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的图像基本操作 

上面的例子可以比较直观的看到各种border的效果,同时也能发现,python版的api与cpp版本的相比,默认初始化了一块原始图尺寸+各方向边框尺寸的图像内存,作为内置的dst参数。

输出尺寸:(525, 700, 3) (725, 900, 3)

2. 图像的基本算术操作

2.1 图像相加

图像相加,两个图像应该有相同的shape,或者图像和一个标量相加,或者图像和一个与其通道数相同的一维数组相加。

opencv的相加与numpy相加时,在超出数据类型范围时的处理不同


>>> x = np.uint8([250])
>>> y = np.uint8([10])
>>> print( cv2.add(x,y) ) # 250+10 = 260 => 255
[[255]]
>>> print( x+y )  # 250+10 = 260 % 256 = 4
[4]

cpp版本的api还支持mask等参数


void cv::add (
InputArray src1,
InputArray src2,
OutputArray dst,
InputArray mask = noArray(),
int dtype = -1
)

2.2 图像混合

opencv通过 cv::addWeighted 函数提供了将两个图像混合在一起的方法

dst=α⋅img1+β⋅img2+γ


img1 = cv2.imread('ml.png')
img2 = cv2.imread('opencv-logo.png')
dst = cv2.addWeighted(img1,0.7,img2,0.3,0)
cv2.imshow('dst',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

opencv与numpy的图像基本操作

通过cv2.seamlessClone函数还能做更精细的图像局部融合。

来源:https://www.zoucz.com/blog/2019/03/07/50ef43b0-40a5-11e9-9947-3d7b79f522a2/

标签:opencv,numpy,图像
0
投稿

猜你喜欢

  • 大家都对vertical-align的各说各话

    2008-06-19 12:11:00
  • django中SMTP发送邮件配置详解

    2022-12-29 15:08:43
  • Python处理Excel文件实例代码

    2022-02-15 23:13:01
  • Python实现12种降维算法的示例代码

    2023-03-17 14:04:21
  • PyCharm 安装与使用配置教程(windows,mac通用)

    2023-08-21 01:15:39
  • ORACLE常见错误代码的分析与解决三

    2010-07-26 13:28:00
  • python的pygal模块绘制反正切函数图像方法

    2021-08-01 18:48:21
  • 讲解数据库管理系统必须提供的基本服务

    2009-01-04 14:33:00
  • python十进制和二进制的转换方法(含浮点数)

    2021-04-03 02:26:24
  • Python3 pandas 操作列表实例详解

    2021-11-30 14:24:12
  • Android界面与交互设计原则

    2012-02-04 09:28:32
  • Python实现随机生成图片验证码详解

    2023-02-26 12:20:20
  • python脚本框架webpy的url映射详解

    2021-10-27 18:55:05
  • php使用composer常见问题及解决办法

    2023-07-10 13:54:53
  • 了解WEB页面工具语言XML(四)应用分类

    2008-09-05 17:18:00
  • 基于Python函数和变量名解析

    2022-10-26 13:49:56
  • Python matplotlib超详细教程实现图形绘制

    2023-04-20 06:37:53
  • 解决pycharm回车之后不能换行或不能缩进的问题

    2023-06-11 10:45:40
  • python 对任意数据和曲线进行拟合并求出函数表达式的三种解决方案

    2021-10-02 12:40:16
  • 如何判断用户是否非正常离开聊天室?

    2010-01-18 20:30:00
  • asp之家 网络编程 m.aspxhome.com