opencv入门系列教学(五)图像的基本操作(像素值、属性、ROI和边框)
0.序言
每个图像是由一个个点组成的,而这些点可以表示为像素值的形式。
这篇博客里我们将学会:
- 访问像素值并修改它们 。
- 访问图像属性 。
- 设置感兴趣区域(ROI) 。
- 分割和合并图像。
对于图像的基本操作我们需要对numpy知识的了解,不需要很多,只知道基本用法即可。这里暂不赘述,读者可查阅其余资料进行学习。
1.访问和修改像素值
让我们先加载彩色图像:
import numpy as np
import cv2 as cv img = cv.imread('cat.jpg')

我们可以通过行和列坐标来访问像素值。对于 BGR 图像,它返回一个由蓝色、绿色和红色值组成的数组。而如果是灰度图像的话,它只返回相应的灰度。我们也可以用相同的方式来对像素值进行修改。
# 通过行和列坐标来访问像素值
>>> px = img[100,100]
>>> print( px )
[157 166 200] # 修改像素值
>>> img[100,100] = [255,255,255]
>>> print( img[100,100] )
[255 255 255]
Numpy是用于快速数组计算的优化库。因此,简单地访问每个像素值并对其进行修改将非常慢,因此不建议使用。对于单个像素访问,Numpy数组方法array.item()和array.itemset())被认为更好,但是它们始终返回标量。如果要访问所有B,G,R值,则需要分别调用所有的array.item()。
比如我们可以用下面的方法来进行像素的访问和编辑:
# 访问 RED 值
>>> img.item(10,10,2)
59 # 修改 RED 值
>>> img.itemset((10,10,2),100)
>>> img.item(10,10,2)
100
2.访问图像属性
图像属性包括行数,列数,通道数,图像数据类型,像素数等等。
图像的形状可通过 img.shape 访问。它返回行,列和通道数的元组(如果图像是彩色的)
注意:如果图像是灰度的,则返回的元组仅包含行数和列数,因此这是检查加载的图像是灰度还是彩色的好方法。
>>> print( img.shape )
(342, 548, 3)

像素总数可通过访问 img.size :
>>> print( img.size )
562248

图像数据类型通过 img.dtype 获得:
>>> print( img.dtype )
uint8

注意:img.dtype在调试时非常重要,因为OpenCV-Python代码中的大量错误是由无效的数据类型引起的。
3.图像感兴趣区域ROI
有时候,我们不得不处理一些特定区域的图像。比如对于图像中的眼睛检测,首先对整个图像进行人脸检测。在获取人脸图像时,我们只选择人脸区域,搜索其中的眼睛,而不是搜索整个图像。它提高了准确性和性能。
这里我们直接使用numpy的切片即可,比如:
>>> ROI = img[280:340, 330:390]

不规则形状的ROI区域的设置,我们将在以后的文章里再详细阐述。
4.拆分和合并图像通道
有时我们需要分别处理图像的B,G,R通道。在这种情况下,我们需要将BGR图像拆分为单个通道。我们可以这样做:
>>> b,g,r = cv.split(img) >>> img = cv.merge((b,g,r))

但是cv.split() 是一项耗时的操作(就时间而言)。因此,仅在必要时才这样做。我们一般采用Numpy索引的方法。比如我们要将所有的红色像素都设置为0:
>>> img [:, :, 2] = 0

5.为图像设置边框
如果我们要在图像周围创建边框(如相框),那可以使用 cv.copyMakeBorder() 。它在以后对图像进行高级处理的时候,比如卷积运算,零填充等方面将有更多应用。此函数采用以下参数:
- src - 输入图像
- top,bottom,left,right 边界宽度(以相应方向上的像素数为单位)
- borderType - 定义要添加哪种边框的标志。它可以是以下类型:
- cv.BORDER_CONSTANT - 添加恒定的彩色边框。该值应作为下一个参数给出。
- cv.BORDER_REFLECT - 边框将是边框元素的镜像,如下所示: fedcba | abcdefgh hgfedcb
- **cv.BORDER_REFLECT_101**或 **cv.BORDER_DEFAULT**与上述相同,但略有变化,例如: gfedcb | abcdefgh | gfedcba
- **cv.BORDER_REPLICATE**最后一个元素被复制,像这样: aaaaaa | abcdefgh | hhhhhhh
- **cv.BORDER_WRAP**看起来像这样: cdefgh | abcdefgh | abcdefg
- value -边框的颜色,如果边框类型为**cv.BORDER_CONSTANT**
下面我们来看一下各个边框类型在图片显示上的结果。注意因为图像是基于matplotlib一起显示的。所以红色和蓝色通道将会互换。
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
BLUE = [255,0,0]
img1 = cv.imread('opencv-logo.png')
replicate = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REPLICATE)
reflect = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT)
reflect101 = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT_101)
wrap = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_WRAP)
constant= cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_CONSTANT,value=BLUE)
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入门系列教学(五)图像的基本操作(像素值、属性、ROI和边框)的更多相关文章
- opencv入门系列教学(六)图像上的算术运算(加法、融合、按位运算)
0.序言 这一篇博客我们将学习图像的几种算术运算,例如加法,减法,按位运算等. 1.图像加法 我们可以通过OpenCV函数 cv.add() 或仅通过numpy操作 res=img1+img2 res ...
- openCV入门系列教学(一) 图像的读取、展示与保存
序言 笔者最近做了两个CV领域的项目,因为数据量不足所以主要使用的是传统的CV方法.这时候不得不夸一句opencv库,让复杂的算法原理变得如此简单(调包调参侠表示很骄傲).所以闲暇下来对opencv的 ...
- opencv入门系列教学(二)图像入门:读取、展示并保存视频
一.从相机读取视频 通常情况下,我们必须用摄像机捕捉实时画面.让我们从摄像头捕捉一段视频(我使用的是我笔记本电脑内置的网络摄像头) ,将其转换成灰度视频并显示出来. 要捕获视频,我们需要 ...
- opencv入门系列教学(七)改变颜色空间、提取彩色对象
0.序言 之前的博客里我们介绍了opencv在图像上的基本操作,下面我们来进行稍微深入一点的介绍,从这里开始我们可以发现opencv库能给我们带来的更多更有趣的功能.从现在开始,我们将逐步深入了解 ...
- opencv入门系列教学(四)处理鼠标事件
一.鼠标事件的简单演示 opencv中的鼠标事件,值得是任何与鼠标相关的任何事物,例如左键按下,左键按下,左键双击等.我们先来看看鼠标事件有哪些,在python中执行下面代码: import cv2 ...
- OpenCV入门系列教学(三)绘制几何形状及添加文本
一.绘制简单的几何形状和添加文本 opencv中绘制图形很简单,我们只需要使用下面这些常用函数即可. #画线 cv2.line() #画圆 cv2.circle() #画矩形 cv. rectangl ...
- 【OpenCV入门教程之三】 图像的载入,显示和输出 一站式完全解析(转)
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/20537737 作者:毛星云(浅墨) ...
- Angular2入门系列(五)———— 路由参数设置
Angular2入门系列(五)---- 路由参数设置路由配置: { path: '', component: CarProFile, children: [ { path: 'add', compon ...
- Vue入门系列(五)Vue实例详解与生命周期
Vue官网: https://cn.vuejs.org/v2/guide/forms.html#基础用法 [入门系列] (一) http://www.cnblogs.com/gdsblog/p/78 ...
随机推荐
- 高版本(8以上)tomcat不支持rest中的delete和put方式请求怎么办
出现问题 当我们去访问delete方式和put方式: 后来才知道tomcat8以上是不支持delete方式和put方式 解决方法: 在跳转目标的jsp头文件上改为(加上了isErrorPage=&qu ...
- 7Java基础补充
1.标准Java bean写法 包括:private修饰的成员变量.getter和setter以及无参和有多个参数的有参构造方法 2.String原理 String底层是字节数组byte[]. Str ...
- etcd学习(3)-grpc使用etcd做服务发现
grpc通过etcd实现服务发现 前言 服务注册 服务发现 负载均衡 集中式LB(Proxy Model) 进程内LB(Balancing-aware Client) 独立 LB 进程(Externa ...
- 测试龙芯 LoongArch .NET之 使用 FastTunnel 做内网穿透远程计算机
龙芯3A5000 已经上市,与龙芯3A5000配套的三大编译器GCC.LLVM.GoLang和三大虚拟机Java.JavaScript..NET均已完成开发,从老伙计哪里搞来一台3A5000 机器,安 ...
- POJ2482 Stars in Your Window 题解
Fleeting time does not blur my memory of you. Can it really be 4 years since I first saw you? I stil ...
- 使用bind部署DNS主从服务器
说明:这里是Linux服务综合搭建文章的一部分,本文可以作为单独搭建主从DNS服务器的参考. 注意:这里所有的标题都是根据主要的文章(Linux基础服务搭建综合)的顺序来做的. 如果需要查看相关软件版 ...
- Spring事务管理中的配置文件(三)
在开发中,遇到了sql语句报错,但是并没有回滚的情况. 经过几天的排查,终于找到了事务没有回滚的原因. 原来的项目用的是informix的数据库,原来针对事务回滚的机制都是好用的.我本地用的是mysq ...
- 将py文件打包成exe文件
PyInstaller工具是跨平台的,它既可以在 Windows平台上使用,也可以在 Mac OS X 平台上运行.在不同的平台上使用 PyInstaller 工具的方法是一样的,它们支持的选项也是一 ...
- 开发者如何快速搭建自己的电商App?
面向电商购物场景,HMS Core提供了创新的电商解决方案,帮助应用快速获客.提升转化率,实现业务增长.为了帮助开发者了解如何在电商购物类应用中集成HMS Core的各项能力,HMS Core开发了电 ...
- 🏆【Java技术专区】「延时队列专题」教你如何使用【精巧好用】的DelayQueue
延时队列前提 定时关闭空闲连接:服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之. 定时清除额外缓存:缓存中的对象,超过了空闲时间,需要从缓存中移出. 实现任务超时处理:在网络协议滑动窗口请求 ...