图像基本概念,Python 图像算法取经之旅 365 天的第 2 天丨【百变AI秀】
今天是持续写作的第 35 / 100 天。
如果你有想要交流的想法、技术,欢迎在评论区留言。
在上篇博客中,橡皮擦意识到学习 OpenCV 前,需要先补充一些图的基本概念,例如像素,坐标,位深,这些内容,别问为啥知道的,问就是剧情需要。
图像的基本概念
图像放大之后可以看到像素,例如下图眼睛放大之后的区域,图中的一个一个的小方块就是像素。如果你玩过我的世界,对像素可能感知会更加深刻。
像素是带颜色的,一个像素就是一个很小的图像单元,单元里面包含很多信息,最重要的就是颜色相关数据。图像颜色的取值叫做 RGB,顺手百度下 RGB 的含义。
这里有个逆向的知识点,RGB 取值范围是 0~255,数值的变化代表颜色深浅的变化,由于橡皮擦对这部分之前已经有些理解了,这部分过得比较快。
RGB 对应的值越大,颜色越浅色,0 表示黑色,255 白色,这么理解就行。
在看一下图像的构成,对于计算机来说,图像就是一个数组,数组中的每一项都装着一个像素单元,在学习的过程中我碰到了一个二维灰度图像的概念,但是能力有限,并没有太理解,橡皮擦学习技巧大放送,不理解就先按照自己能理解的尝试去解释,后面逐步补充完整。
二维灰度图像对应的是二维数组,那我依据此画出一个二维坐标系,里面都是像素,每个像素都是一个 0~255 的值。
不知道理解的是否到位,后面可能随着学习就破案了。
后来检索到三维图像包含 RBG 的 3 个值,也就是是用 3 个二维数据表示,瞬间好像明白了一些 RGB 到底是啥。
百度找到一个帮助理解的内容,咱们一起看看。
那接下来验证一下二维灰度图如何生成。两个核心的概念:1. 二维,2. 0~255。
说干就干,Python 咱写的贼 6 吖。
使用 Numpy 库生成一个数组对象不就好了。
import numpy as np
import cv2
# 生成一个数组矩阵,然后在将该矩阵进行转换
test_array = np.arange(16).reshape(4,4)
print(test_array)
# 使用 OpenCV 存储成图片
cv2.imwrite('first_img.jpg',test_array)
貌似在文件根目录确实生成了一个图片,打开图片,出现了,橡皮擦第一个人造图。下面这么一个小东西。
而且是 4x4 像素的,恰好和我弄的那个数组一致。
接下来搞大这个图,把数组生成的规则修改一下即可,由于取值范围只能是 0~255,所以代码只能这样修改了。
import numpy as np
import cv2
# 生成一个数组矩阵,然后在将该矩阵进行转换
test_array = np.arange(255)
print(test_array)
# 使用 OpenCV 存储成图片
cv2.imwrite('first_img.jpg',test_array)
代码生成一个 1x255 像素的图像,而且是个从黑到白的渐变。
计算机图像表示原理
以下内容觉得写得不错,直接转载了过来,原文地址为 : https://blog.csdn.net/weixin_42415138/article/details/108214369 ,如果作者看到并且不希望橡皮擦引用,请直接联系我即可。
计算机图像可以分为两类:位图(Bitmap)和矢量图(Metafile)。位图可以被看做是一个表格,整个图像由许多的矩形块组成,
每个矩形代表一个点,点的个数等于位图的横向矩形块的个数乘上纵向矩形块的个数,每一个点则被称为像素点,
而且每个像素点都有确定的颜色,因此形成了一幅完整的图像。通常使用的图像大部分是位图,如相机拍摄的照片,
因为位图可以表示图像的细节,能够较好的还原现实场景。位图的缺点是体积比较大,因此产生了很多压缩图像格式来存储位图图像,
目前应用最广的是 JPEG 格式,另外还有 GIF、PNG 等。还有个缺点是位图在放大时,会出现“锯齿”现象,这也由位图的本质特点决定。
所以在现实中,还需要使用另外一种图像格式:矢量图。
同位图不同,矢量图是利用数学公式通过线段绘制出来的,所以不管如何放大都不会出现失真现象,
但是矢量图不能描述非常复杂的图像。
所以各种图形图案、CAD 软件等等都是使用矢量格式来保存文件。
每个像素采用不同的位数,就可以表示出不同的颜色,颜色数量如下:
4位图像:2^4=16
8位图像:2^8=256
16位图像:2^16=65536
24位图像:2^24=16777216
由此可知当采用 1Bytes(8bit)来存储一个像素点的像素值时,可以得到256种不同的结果,采用3Bytes(24bit)时,
可以有 16777216 种不同结果,而不同的结果又代表不同的颜色,这已经接近人眼所能分辨的颜色了。
计算机中使用最多的就是 24 位色,另外在 GDI+中还有一种 32 位色,多出来一个通道用来描述Alpha,即透明分量。
在位图中使用 RGB 三色空间表示颜色(位数少时要使用调色板),在 24位彩色图像中,3个字节分别表示R、G、B三种颜色分量,
这其中是没有亮度分量的,这是因为在 RGB 表示方式中,亮度也是直接可以从颜色分量重得到的,
每一颜色分量值的范围都是 0~255,某一颜色分量的值越大,就表示这一分量的亮度值越高。
一个真彩色像素点转换为灰度图时它的亮度值则采用了心理学灰度公式计算:
Y=0.299R+0.587G+0.114B
使用上述公式转换时得到的灰度图最接近人眼对灰度图的感觉。灰度图中颜色数量一共只有 256 种(8bit),
所以转换后的图像保存为8位格式,可以节省空间。因此彩色图像转变为灰度图像是不可逆的过程。
调色板中可以保存256颜色,所以可以正好将 256 种灰度颜色保存到调色板中。
上述内容中,我学到的点主要是位图相关的知识,一个像素的最大值是 255,二进制表示 255 需要占用 8bit 空间,所以如果保存灰度图用 8 位即可。
彩色图像需要三个二维数组表示,3x8=24,莫名的对应上了 24 位彩色图像。
计算机图像的分类
查询了一下,得到如下知识。
- 灰度图像,如果图片有 种灰度的图像,则称为 8 比特图像;
- 二值图像.就是只有 0、1 黑白两种;
- RGB 彩色图像,ARGB,其中 A 代表 alpha 透明度;
- 颜色模型 RGB,HIS,YIQ。
橡皮擦脑洞改图
把一个图片读取完毕,然后把每个像素都修改成 0 ,是不是就得到一张同样大小的纯黑图了?貌似没啥应用场景,不过试试吧。
import numpy as np
import cv2
def main():
img = cv2.imread("test_img.jpg")
# 获取图片的宽度和高度
print(img.shape)
width,height,n = img.shape
# 复制一张图片
new_img = img.copy()
for i in range(width):
for j in range(height):
# 每个像素都给修改为0
# print(new_img[i,j]) # 这个每个像素输出都是一个列表 [34 32 31]
new_img[i,j] = 0
cv2.imshow("new_img",new_img)
cv2.waitKey(0)
唉,果然得到一个黑图,哈哈哈哈。而且意外知道了,彩色图像每个像素都是一个 RGB 的数组,同时 get 两个知识点。
今天的 OpenCV 尾声
记住,一起打卡 365 天哦,由于不成体系,只为学到知识,所以如果出现方向错误,大家可以及时的指出来的。
博主 ID:梦想橡皮擦,希望大家点赞、评论、收藏。
【百变AI秀】有奖征文火热进行中:https://bbs.huaweicloud.com/blogs/296704
- 点赞
- 收藏
- 关注作者
评论(0)