opencv与numpy的图像基本操作


Posted in Python onMarch 08, 2019

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函数还能做更精细的图像局部融合。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
tornado框架blog模块分析与使用
Nov 21 Python
以一个投票程序的实例来讲解Python的Django框架使用
Feb 18 Python
python线程池(threadpool)模块使用笔记详解
Nov 17 Python
Python实现的插入排序算法原理与用法实例分析
Nov 22 Python
python list是否包含另一个list所有元素的实例
May 04 Python
python3监控CentOS磁盘空间脚本
Jun 21 Python
Python 面试中 8 个必考问题
Nov 16 Python
使用k8s部署Django项目的方法步骤
Jan 14 Python
树莓派+摄像头实现对移动物体的检测
Jun 22 Python
利用Tensorflow的队列多线程读取数据方式
Feb 05 Python
Django数据结果集序列化并展示实现过程
Apr 22 Python
python编程的核心知识点总结
Feb 08 Python
Python脚本修改阿里云的访问控制列表的方法
Mar 08 #Python
python实现整数的二进制循环移位
Mar 08 #Python
Python3实现的反转单链表算法示例
Mar 08 #Python
Python3实现的判断回文链表算法示例
Mar 08 #Python
python字符串循环左移
Mar 08 #Python
详解Python Matplot中文显示完美解决方案
Mar 07 #Python
详解Python安装tesserocr遇到的各种问题及解决办法
Mar 07 #Python
You might like
从C/C++迁移到PHP——判断字符类型的函数
2006/10/09 PHP
php实现的支持断点续传的文件下载类
2014/09/23 PHP
php常量详细解析
2015/10/27 PHP
浅析PHP中的闭包和匿名函数
2017/12/25 PHP
用js实现计算加载页面所用的时间
2010/04/02 Javascript
Javascript 页面模板化很多人没有使用过的方法
2012/06/05 Javascript
JS命名空间的另一种实现
2013/08/09 Javascript
jQuery制作简洁的多级联动Select下拉框
2014/12/23 Javascript
javascript背景时钟实现方法
2015/06/18 Javascript
jQuery实现从身份证号中获取出生日期和性别的方法分析
2016/02/25 Javascript
javascript cookie基础应用之记录用户名的方法
2016/09/20 Javascript
利用nodejs监控文件变化并使用sftp上传到服务器
2017/02/18 NodeJs
Webpack常见静态资源处理-模块加载器(Loaders)+ExtractTextPlugin插件
2017/06/29 Javascript
Angular.js初始化之ng-app的自动绑定与手动绑定详解
2017/07/31 Javascript
vue 实现的树形菜的实例代码
2018/03/19 Javascript
解决angularjs service中依赖注入$scope报错的问题
2018/10/02 Javascript
Vue 2.0双向绑定原理的实现方法
2019/10/23 Javascript
微信小程序 获取手机号 JavaScript解密示例代码详解
2020/05/14 Javascript
[01:10:16]DOTA2上海特级锦标赛B组资格赛#2 Fnatic VS Spirit第一局
2016/02/27 DOTA
Python使用SocketServer模块编写基本服务器程序的教程
2016/07/12 Python
深入理解Python单元测试unittest的使用示例
2017/11/18 Python
python监测当前联网状态并连接的实例
2018/12/18 Python
Python字符串中添加、插入特定字符的方法
2019/09/10 Python
Pycharm如何导入python文件及解决报错问题
2020/05/10 Python
浅谈Selenium 控制浏览器的常用方法
2020/12/04 Python
美国网上书店:Barnes & Noble
2018/08/15 全球购物
Trench London官方网站:高级风衣和意大利皮夹克
2020/07/11 全球购物
公司行政经理岗位职责
2013/12/24 职场文书
经贸日语专业个人求职信范文
2014/04/29 职场文书
庆六一文艺汇演活动方案
2014/08/26 职场文书
群众路线教育实践活动民主生活会个人检查对照思想汇报
2014/10/04 职场文书
夫妻分居协议书范文
2014/11/26 职场文书
2014年食品安全工作总结
2014/12/04 职场文书
入党积极分子培养人意见
2015/06/02 职场文书
redis哨兵常用命令和监控示例详解
2021/05/27 Redis
Apache Kafka 分区重分配的实现原理解析
2022/07/15 Servers