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 相关文章推荐
python将unicode转为str的方法
Jun 21 Python
Python使用matplotlib绘制正弦和余弦曲线的方法示例
Jan 06 Python
python删除文本中行数标签的方法
May 31 Python
python 把列表转化为字符串的方法
Oct 23 Python
Python3使用Matplotlib 绘制精美的数学函数图形
Apr 11 Python
python语言元素知识点详解
May 15 Python
python实现点击按钮修改数据的方法
Jul 17 Python
Django时区详解
Jul 24 Python
django 使用 PIL 压缩图片的例子
Aug 16 Python
Python实现序列化及csv文件读取
Jan 19 Python
Python pip安装模块提示错误解决方案
May 22 Python
django 实现后台从富文本提取纯文本
Jul 02 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
关于php curl获取301或302转向的网址问题的解决方法
2011/06/02 PHP
php页面防重复提交方法总结
2013/11/25 PHP
php初始化对象和析构函数的简单实例
2014/03/11 PHP
php使用MySQL保存session会话的方法
2015/06/18 PHP
php 把数字转换成汉字的代码
2015/07/21 PHP
自定义min版smarty模板引擎MinSmarty.class.php文件及用法
2016/05/20 PHP
JavaScript更改class和id的方法
2008/10/10 Javascript
jQuery插件开发基础简单介绍
2013/01/07 Javascript
js 触发select onchange事件代码
2014/03/20 Javascript
再探JavaScript作用域
2014/09/24 Javascript
轻松创建nodejs服务器(8):非阻塞是如何实现的
2014/12/18 NodeJs
封装好的js判断操作系统与浏览器代码分享
2015/01/09 Javascript
Jquery Easyui验证组件ValidateBox使用详解(20)
2016/12/18 Javascript
利用Mongoose让JSON数据直接插入或更新到MongoDB
2017/05/03 Javascript
protractor的安装与基本使用教程
2017/07/07 Javascript
vue生成随机验证码的示例代码
2017/09/29 Javascript
详解webpack-dev-server使用http-proxy解决跨域问题
2018/01/13 Javascript
Vue 引入AMap高德地图的实现代码
2019/04/29 Javascript
Vue-Cli 3.0 中配置高德地图的两种方式
2019/06/19 Javascript
layui type2 通过url给iframe子页面传值的例子
2019/09/06 Javascript
小程序按钮避免多次调用接口和点击方案实现(不用showLoading)
2020/04/15 Javascript
[31:00]2014 DOTA2华西杯精英邀请赛5 24 NewBee VS iG
2014/05/25 DOTA
Python方法的延迟加载的示例代码
2017/12/18 Python
在python中利用opencv简单做图片比对的方法
2019/01/24 Python
python基于三阶贝塞尔曲线的数据平滑算法
2019/12/27 Python
python 实现有道翻译功能
2021/02/26 Python
HTML5移动端开发遇见的东西
2019/10/11 HTML / CSS
MaBelle玛贝尔香港官网:香港钻饰连锁店
2019/09/09 全球购物
什么是ESB?请介绍一下ESB?
2015/05/27 面试题
优秀应届生推荐信
2013/11/09 职场文书
个人求职简历中英文自我评价
2013/12/16 职场文书
有趣的广告词
2014/03/18 职场文书
房屋租赁协议书(标准版)
2014/10/02 职场文书
幼儿园元旦主持词
2015/07/06 职场文书
浅谈如何提高PHP代码的质量
2021/05/28 PHP
浅谈MySQL之浅入深出页原理
2021/06/23 MySQL