Continue 玩转像素点,Python 图像处理学习的第 3 天
今天是持续写作的第 36 / 100 天。
如果你有想要交流的想法、技术,欢迎在评论区留言。
今天要学习的内容还是围绕图像、像素展开,直觉这部分对后面的学习会有帮助,来自老程序员的经验。
从数组对比彩色图像与灰度图像
通过 cv2 库读取一个图片之后,可以展示图像的 shape 属性,该属性与 numpy shape,它表示的数组的维度。这是一个整数的元组,元组中的每一个元素对应着每一维度的大小(size)。
若元组只有一个元素,则说明这个数组是一维数组:如元组(2,) 表示一维数组,只含有 2 个元素;同理,可知(1,3)表示的是一个 2 维数组,因为含有 2 个元素 :1,3。
import numpy as np
import cv2
# 读取图片
color_img = cv2.imread("test.jpg")
print(color_img.shape)
输出的内容是 (516, 787, 3)
,核对一下图片的宽度和高度,恰好与刚才的数值对应。
上述输出的元组最后的 3 表示这张图片是一个 RGB 图像。
相应的修改一下读取图片的参数,读取进来一个灰度图,再输出 shape 属性,得到的就没有最后的 3 了。
import numpy as np
import cv2
# 读取灰度图片
gray_img = cv2.imread("test.jpg", cv2.IMREAD_GRAYSCALE)
# 输出的结果中并没有 3
print(gray_img.shape)
输出的结果如下。
(516, 787)
如果直接输出元组里面的内容,得到的数据如下:
[[70 70 70 ... 70 70 70]
[69 70 69 ... 70 70 70]
[70 70 70 ... 70 70 70]
...
[26 26 25 ... 27 27 27]
[26 26 25 ... 27 27 27]
[27 26 26 ... 26 26 26]]
如果读取正常的彩色图片,得到的数组为:
# 正常读取图片
img = cv2.imread("test.jpg")
print(img.shape)
print(img)
[[[43 67 87]
[43 67 87]
[43 67 87]
...
[43 67 87]
[43 67 87]
[43 67 87]]
[[42 66 86]
[43 67 87]
[42 66 86]
...
可以看到上述两个内容最大的区别是,彩色图片输出的是三维数组,灰度图片输出的是二维数组,如果不太清楚,可以反复多尝试几次,如果橡皮擦把概念说错了,咱就先按能理解的理解,后面慢慢进行更正,非专业人士,请谅解。
操作图片的像素点
既然图片都能当成一个矩阵来进行操作了,那对于每个位置的元素都可以进行获取与修改,例如获取 100,100 位置的像素颜色。
import numpy as np
import cv2
img = cv2.imread("test.jpg")
pixel = img[100, 100]
print(pixel)
输出结果是 [44 69 89] ,这个知识点经过检索发现说法一般叫做使用 OpenCV 获取每个像素点的 RGB 颜色分量,还有一个需要注意,得到的数组是按照 BGR 的顺序返回,这个要记忆一下。
设置像素点的 RGB 颜色分量。
import numpy as np
import cv2
img = cv2.imread("test.jpg")
pixel = img[100, 100]
print(pixel)
img[100, 100] = [200, 220, 1] # 设置像素值
cv2.imshow("img show", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
打开图片,在 100,100 位置寻找设置的点,可以预先猜一下这个点的颜色是什么颜色。
[200,220,1] 对应的 BGR,200 的蓝色,220 的绿色,1 的红色,实际用屏幕取色工具找到那个点,发现颜色为 1, 220, 200,注意下图的小点。
通过取色器对应了一下,发现颜色对应的没有问题。
其实看到这里,我就在想如果在图片上随机画白点,岂不是能得到好看的图片?
椒盐现象图片
搜了一下,还真找到了,刚才提及的叫做椒盐图片,还挺有趣的,说干就干,看代码。
不过在实现之前,还要
import numpy as np
import cv2
img = cv2.imread("test.jpg")
# pixel = img[100, 100]
# print(pixel)
# img[100, 100] = [255, 255, 255] # 设置像素值
# 输出的是(高度像素,宽度像素)
print(img.shape)
for k in range(1000):
i = int(np.random.random() * img.shape[1])
j = int(np.random.random() * img.shape[0])
img[j, i] = [255, 255, 255]
img[j, i] = [255, 255, 255]
img[j, i] = [255, 255, 255]
cv2.imshow("img show", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行之后的效果还可以,有那么点意思了。
上述代码,在实验的时候,可以按照下面的代码设置内容。
img[j, i] = 255
img[j, i] = 255
img[j, i] = 255
通过该方法修改之后,得到的结果和直接设置三个值是一样的。
今天的 OpenCV 尾声
1 个小时好快,尤其是在学习新的东西的时候,今天的日程到这里啦,一起加油吧。本阶段可以执着于像素点上的操作,这个应该是未来解决图片问题的最佳突破点。
如果你想跟博主建立亲密关系,可以关注同名公众号 梦想橡皮擦,近距离接触一个逗趣的互联网高级网虫。
博主 ID:梦想橡皮擦,希望大家点赞、评论、收藏。
- 点赞
- 收藏
- 关注作者
评论(0)