第二章:图像处理基础
第二章:图像处理基础操作
- 一、图像的基本表示方法:
- 1. 二值图像:
- 2. 灰度图像:
- 3. 彩色图像:
- 二、像素处理:
- 1. 二值图像及灰度图像:
- 2.彩色图像:
- 3. 使用numpy.array访问像素:
- 三、感兴趣区域(ROI):
- 四、通道操作:
- 1. 通道拆分:
- 2. 通道合并:
- 五、获取图像属性:
本章主要介绍:
- 图像的基本表示方法
- 像素的访问和操作
- 感兴趣区域的处理
- 通道处理
等知识点。需要注意的是,使用面向Python的OpenCV必须熟练掌握Numpy库,尤其是Numpy.array库,Numpy.array库是python处理图像的基础。
一、图像的基本表示方法:
图像的基本表示方法有:
- 二值图像
- 灰度图像
- 彩色图像
1. 二值图像:
二值图像是指仅包含黑色和白色两种颜色的图像。
计算机中,通过矩阵来表示和处理图像。例如下图一个A的图像,计算机在处理该图像时,会首先将其划分为一个个的小方块,即像素点,每一个像素点都是一个独立的处理单元。然后,将其中白色的像素点置为1,黑色的像素点置为0,用于后续的存储和处理操作。
2. 灰度图像:
二值图像表示起来简单方便,但是因为其仅有黑白两种颜色,所表示的图像不够细腻。如果需要表示更多的细节,就需要使用更多的颜色。
例如,下图的灰度图像:
通常,计算机会将灰度处理为256个灰度级,用区间[0, 255]来表示。其中255表示纯白色,0表示纯黑色,其余的数值表示从纯白色到纯黑色之间前不同级别的灰度。
用于表示256个灰度级的数值0-255,正好可以用一个字节(8个2进制位)来表示。如下图是部分二进制值所对应的十进制值:
有些情况下,也会使用8位二进制来表示一幅二值图像。这种情况下,255表示白色,0表示黑色,图像中只存在255和0。
3. 彩色图像:
相比二值图像和灰度图像,彩色图像是更常见的一类图像。神经生理学实验发现,在视网膜上存在三种不同的颜色感受器,能够感受三种不同的颜色:红色、绿色和蓝色,即三基色。自然界中常见的各种色光都可以通过将三基色按照一定的比例混合构成。除此之外,从光学角度出发,可以将颜色解析为主波长、纯度、明度等。从心理学和视觉角度出发,可以将颜色解析为色调、饱和度、亮度等。通常,我们将上述方式采用不同的方式来表述颜色的模式称为色彩空间,或者颜色空间、颜色模式。
虽然,不同的色彩空间具有不同的表示方式,但是各种色彩空间之间可以根据相应的公式进行转换。
例如,在RGB色彩空间中,存在R通道、G通道、B通道,共三个通道。每个色彩通道值的方位都在[0, 255]之间。因此,通常用一个三维数组来表示一幅RGB色彩空间的彩色图像。注意,在OpenCV中,通道的顺序是B-G-R。
二、像素处理:
像素是图像构成的基本单位,像素处理是图像处理的基本操作,可以通过位置索引的形式对图像内的元素镜像访问、处理。
1. 二值图像及灰度图像:
在OpenCV中,最小的数据类型是无符号的8位数。因此,在OpenCV中实际是并没有二值图像这种数据类型,二值图像经常是通过处理得到的特殊的灰度图像,使用0表示黑色,使用255表示白色。
通过前面的分析可知,在计算机中,图像就是一个由像素点组成的矩阵。在面向Python 的OpenCV中,图像就是Numpy中的数组。一个OpenCV灰度图像就是一个二维数组,可以使用表达式访问其中的像素值。例如:可以使用image[0, 0]访问图像image第0行第0列未知上的像素点。
示例: 读取一个灰度图像,并对其像素进行访问、修改:
import cv2
img = cv2.imread('lena.bmp', 0)
cv2.imshow('before', img)
for i in range(10, 100):for j in range(80, 100):img[i, j] = 255
cv2.imshow('after', img)
cv2.waitKey()
cv2.destroyAllWindows()
2.彩色图像:
RGB模式的彩色图像在读入到OpenCV中进行处理时,会按照行方向依次读取该RGB图像的 B通道、G通道、R通道的像素点,并将像素点以行为单位存储在ndarray的列中。例如,有一幅大小为R行×C列的原始RGB图像,其在OpenCV内衣BGR模式的三维数组形式存储。
可以使用表达式访问数组内的值。例如,可以使用image[0, 0, 0] 访问图像image第0行第0列像素点的B通道。
- 第1个索引表示第0行
- 第2个索引表示第0列
- 第3个索引表示第0个颜色通道
示例: 读取一幅彩色图像,并对其像素进行访问、修改。
import cv2
img = cv2.imread('lena512color.tiff')
cv2.imshow('before', img)
# 白色
for i in range(0, 50):for j in range(0, 100):for k in range(0, 3):img[i, j, k] = 255
# 灰色
for i in range(50, 100):for j in range(0, 100):img[i, j] = [128, 128, 128]
# 黑色
for i in range(100, 150):for j in range(0, 100):img[i, j] = 0
cv2.imshow('after', img)
cv2.waitKey()
cv2.destroyAllWindows()
3. 使用numpy.array访问像素:
numpy.array提供了item()和itemset()行数来访问和修改像素值,而且这两个函数都是经过优化处理的,能够大幅度提高处理效率。在访问和修改像素点的值时,利用numpy.array提供的函数要比直接使用索引快得多,同时这两个函数的可读性也更好。
二值图像及灰度图像:
可以将二值图像理解为特殊的灰度图像。- item():访问像素点,语法:item(行,列)
- item():修改像素值,语法:itemset(索引值,新值)
示例: 读取一幅灰度图像,并对其进行像素值访问及修改。
import cv2 img = cv2.imread('../lena.bmp', 0) print('读取像素点img.item(3, 2)=', img.item(3, 2)) img.itemset((3, 2), 255) print('修改后像素点img.item(3, 2)=', img.item(3, 2)) cv2.imshow('before', img) for i in range(10, 200):for j in range(80, 300):img.itemset((i, j), 255) cv2.imshow('after', img) cv2.waitKey() cv2.destroyAllWindows()
彩色图像:
同样可以使用item()函数和itemset()函数来访问和修改彩色图像的像素值,过程与操作灰度图像 相似。不同的是需要补充通道信息。
item():访问EGB模式图像的像素值。语法:item(行,列, 通道)
itemset():修改RGB模式图像像素值。语法:itemset(三元组索引值,新值)
需要注意,针对RGB图像的访问,必须同时指定行、列以及通道,例如img.item(a, b, c)。仅指定行和列是不可以的。
示例: 读取已否彩色图像,并对其进行像素访问、修改
import cv2 img = cv2.imread('lena512color.tiff') cv2.imshow('before', img) print('访问img.item(0, 0, 0) = ', img.item(0, 0, 0)) # 白色 for i in range(0, 50):for j in range(0, 100):for k in range(0, 3):img.itemset((i, j, k), 255) cv2.imshow('after', img) print('修改后端img.item(0, 0, 0) = ', img.item(0, 0, 0)) cv2.waitKey() cv2.destroyAllWindows()
在这里插入图片描述
访问img.item(0, 0, 0) = 125
修改后端img.item(0, 0, 0) = 255
三、感兴趣区域(ROI):
在图像处理过程中,我们可能会对图像的摸一个特定区域感兴趣,该区域被称为感兴趣区域(ROI)。在设定感兴趣区域ROI后,就可以对该区域进行整体操作。例如,将一个感兴趣区域A赋值给变量B后,可以将该变量B赋值给另外一个区域C,从而达到在区域C内复制区域A的目的。
示例1: 假设当前图像名称为img,图中的数字分别表示行号和列号。那么,图像中的黑色ROI可以表示为img[200:400, 200:400],
通过一下语句,能够将图中黑色ROI复制到该区域右侧:
a = img[200:400, 200:400]
img[200:400, 600:800] = a
示例2: 获取图像lena的脸部信息,并将其显示出来。
import cv2
a = cv2.imread('lena512color.tiff', cv2.IMREAD_UNCHANGED)
face = a[220: 400, 250: 350]
cv2.imshow('original', a)
cv2.imshow('face', face)
cv2.waitKey()
cv2.destroyAllWindows()
示例3: 对lena图像脸部进行打码
import cv2
import numpy as np
a = cv2.imread('../lena512color.tiff', cv2.IMREAD_UNCHANGED)
cv2.imshow('original', a)
face = np.random.randint(0, 256, (180, 100, 3))
a[220: 400, 250: 350] = face
cv2.imshow('result', a)
cv2.waitKey()
cv2.destroyAllWindows()
四、通道操作:
在RGB图像中,图像由R通道、G通道、B通道三个通道构成的。需要注意的是,在OpenCV中,通道是按照B通道-G通道-R通道的顺序存储的。在图像处理过程中,可以根据需要对图像进行通道拆分和通道合并。
1. 通道拆分:
针对RGB图像,可以分别拆分出其R通道、G通道、B通道。在OpenCV中,即可以通过索引的方式拆分通道,也可以通过函数的方式拆分通道。
通过索引拆分通道:
通过索引的方式,可以直接将各个通道从图像内提取出来。如:针对OpneCV中的BGR图像img
- b = img[ : , : , 0]
- g = img[ : , : , 1]
- r = img[ : , : , 2]
示例: 编写程序,演示图像通道才分及通道值变换对彩色图像的影响。
import cv2 lena = cv2.imread('lena512color.tiff') cv2.imshow('lena1', lena) b = lena[:, :, 0] g = lena[:, :, 1] r = lena[:, :, 2] cv2.imshow('b', b) cv2.imshow('g', g) cv2.imshow('r', r) lena[:, :, 0] = 0 cv2.imshow('lenab0', lena) lena[:, :, 1] = 0 cv2.imshow('lenabogo', lena) cv2.waitKey() cv2.destroyAllWindows()
通过函数拆分通道:
函数cv2.split()能够拆分图像的通道。如,可以使用以下语句拆分彩色BGR图像img,得到图像的B,G,R通道。
b, g, r = cv2.split(img)
b = cv2.split(img)[0]
g = cv2.split(img)[1]
r = cv2.split(img)[2]
示例: 使用函数cv2.split()拆分图像通道
import cv2 lena = cv2.imread('../lena512color.tiff') b, g, r = cv2.split(lena) cv2.imshow('B', b) cv2.imshow('G', g) cv2.imshow('R', r) cv2.waitKey() cv2.destroyAllWindows()
2. 通道合并:
通道合并是通道拆分的逆过程,通过合并通道可以将三个通道的灰度图像构成一幅彩色图像。函数cv2.merge()可以实现图像通道的合并,如有B, G, R三个通道图像,使用函数cv2.merge()将其合并为一幅BGR三通道的彩色图像。其实现语句为:bgr_img = cv2.merge([b, g, r])
示例: 使用函数cv2.merge()合并通道。
import cv2
lena = cv2.imread('../lena512color.tiff')
b, g, r = cv2.split(lena)
bgr = cv2.merge([b, g, r])
rgb = cv2.merge([r, g, b])
cv2.imshow('lena', lena)
cv2.imshow('bar', bgr)
cv2.imshow('rgb', rgb)
cv2.waitKey()
cv2.destroyAllWindows()
五、获取图像属性:
在图像处理过程中,经常需要获取图像的属性,如图像的大小、类型等。这里介绍几个常用的属性
- shape:如果是彩色图像,则返回包含行数、列数、通道数的数组;如果是二值图像或者灰度图像,则仅返回行数和列数。通过该属性的返回值是否包含通道数,可以判断图像是灰度图像还是彩色图像。
- size:返回图像的像素数目。其值为"行数×列数×通道数",灰度图像挥着二值图像通道数为1
- dtype:返回图像的数据类型
示例:
import cv2
gray = cv2.imread('../lena.bmp', 0)
color = cv2.imread('../lena512color.tiff')
print('图像gray属性')
print('gray.shape=', gray.shape)
print('gray.size=', gray.size)
print('gray.dtype=', gray.dtype)
print('图像color属性')
print('color.shape=', color.shape)
print('color.size=', color.size)
print('color.dtype=', color.dtype)
终端输出:
图像gray属性
gray.shape= (512, 512)
gray.size= 262144
gray.dtype= uint8
图像color属性
color.shape= (512, 512, 3)
color.size= 786432
color.dtype= uint8
该文章内容参考总结自《OpenCV轻松入门》这本书,详细内容可以参考这本书。
第二章:图像处理基础相关推荐
- 《计算机视觉技术与应用》-----第二章 图像处理基础
系列文章目录 <计算机视觉技术与应用>-----第二章 图像处理基础 <计算机视觉技术与应用>-----第三章 图形用户界面 <计算机视觉技术与应用>-----第四 ...
- 数字图像处理 第二章 图像处理基础
数字图像处理基础 2.1 色度学基础 色度学 人的视觉特性 2.1.1 三基色原理 人眼的视网膜上存在有大量能在适当亮度下分辨颜色的锥状细胞,它们分别对应红.绿.蓝三种颜色,即分别对红光.绿光.蓝光敏 ...
- 数字图像处理--冈萨雷斯第4版--第二章 数字图像基础
数字图像处理--冈萨雷斯版--第二章 第二章 数字图像基础 2.1 视觉感知要素 2.1.1 人眼的结构 2.1.2 人眼中图像的形成 2.1.3 亮度适应与辨别 2.2 光和电磁波谱 2.3 图像感 ...
- 数字图像处理 第二章数字图像基础
第二章 数字图像基础 本章全都不是重点,了解就好 目标 人体视觉感知 光和电磁波谱 成像模型 图像取样与量化 一些基本概念和数学处理方法 人体视觉感知 人眼结构 上图为人眼剖面图. 人眼是一个直径约为 ...
- 《数字图像处理》第二章-数字图像基础 笔记
参考文章: 数字图像处理(冈萨雷斯第三版)学习笔记 - Chapter 1 Introduction(1) 数字图像处理(冈萨雷斯第三版)学习笔记 - Chapter 1 Introduction(2 ...
- 数字图像处理笔记 第二章 数字图像基础 第一节 人眼视觉特性
第二章 数字图像基础 第一节 人眼视觉特性 一.光与电磁波 可见光谱:380mm - 780mm 光谱图: 可见光范围内,不同波长的光给人不同的色彩感觉,不同强度的光及不同强度分布的光刺激人眼,在人脑 ...
- Python计算机视觉:第一章 图像处理基础
第一章 图像处理基础 1.1 PIL-Python图像库 1.1.1 对图片进行格式转换 1.1.2 创建缩略图 1.1.3 拷贝并粘贴区域 1.1.4 调整尺寸及旋转 1.2 Matplotlib库 ...
- 数字图像识别学习笔记(第二章-数字图像基础(1))
title: 数字图像识别学习笔记(第二章 数字图像基础(1)) categories: 数字图像识别 tags: 数字图像识别 date: 2020/9/30 21:22 mathjax: true ...
- 第一章图像处理基础概念(人眼和光)
系列文章目录 第一章 图像处理基础概念 第二章 常见算法处理 第三章 灰度变化 第四章 空间滤波 第五章 频域滤波 第六章 色彩基础 第七章 小波和多分辨率 第八章 图像表示和描述 第九章 形态学图像 ...
- 《机器学习系列教程》:第二章 机器学习基础
第二章 机器学习基础 机器学习and 数据分析 2.2 监督学习.非监督学习.半监督学习.弱监督学习? 根据数据类型的不同,对一个问题的建模有不同的方式.依据不同的学习方式和输入数据,机器学习主要分为 ...
最新文章
- Python培训:Python有哪些函数?你了解几种?
- Task04——零基础入门NLP - 基于深度学习的文本分类1
- insightface mxnet训练 out of Memory
- 假笨说-我是如何走上JVM这条贼船的
- mysql登录错误1045修改工具_mysql登录1045错误时 修改登录密码
- java peek函数_Java 8 Stream Api 中的 peek 操作
- Git下使用Beyond Compare作为比较和合并工具
- 近年来最流行网络词汇及论坛用语
- python统计时间的次数的代码_python脚本实现统计日志文件中的ip访问次数代码分享...
- 对称密钥算法与非对称密钥算法
- 微信公众号排版 | 汇总和实战
- 校园网客户端不识别网卡
- Field属性(域)
- 电信运营商移动互联网发展分析
- Type number trivially inferred from a number literal, remove type annotation.
- 全球与中国机器人随机装箱机市场深度研究分析报告
- 1.3 OC与OD门(硬件基础系列)
- EventBus介绍
- 【小程序源码】星座运势,周公解梦下载
- SQL(基础例题+SQLserver实现)
热门文章
- iOS开发拓展篇—音频处理(音乐播放器6)
- 趣味数据故事_坏数据的好故事
- leetcode 227. 基本计算器 II(栈)
- leetcode 406. 根据身高重建队列(贪心算法)
- leetcode1343. 大小为 K 且平均值大于等于阈值的子数组数目(队列)
- 特征阻抗输入阻抗输出阻抗_软件阻抗说明
- 如何让代码更易于维护_如何轻松地使您的网站更易于访问
- [树形dp] Jzoj P3914 人品问题
- 4-----Scrapy框架中选择器的用法
- 牛客网 牛客小白月赛1 H.写真がとどいています