![](/myblog/blog-placeholder-4.jpg)
计算机眼中的图像(机器视觉)
图像增强有很多方式,在最后的智能分拣项目中主要用的就是亮度的调节。 除了亮度的调节外,还做了镜像翻转的实验
一、像素
1.1 像素的概念
像素是图像的基本单元,每一个像素存储着图像的颜色、亮度和其他特征,一张图片是由很多像素组成的。 像素是组成图像的最小单元,通常以矩阵形式组织。每个像素可以理解为一个色彩点,具有不同的颜色和亮度值。
1.2 分辨率
像素数量决定图像的分辨率。图像的分辨率越高,像素越多,图像越清晰。
举例:1080p (1920 x 1080) 意味着有1920个水平像素和1080个垂直像素,总共2,073,600个像素
右边是669x669像素点,左边100x100像素点
1.3 灰度图像
灰度图像仅包含亮度信息,像素值范围为0到255(8-bit),其中0代表黑色,255代表白色。
灰度图像
二、RGB颜色
日常生活中常见的图像都是RGB三色图,R代表红色、G代表绿色、B代表蓝色。RGB图是由很多像素点构成的,每一个像素点都是由R、G、B三个颜色混合构成的,几乎所有的颜色都可以通过这三种颜色合成。 除了RGB颜色模型之外还有很多其他的颜色模型 [[01-颜色模型]]
而在计算机中,RGB三种颜色被称为RGB三通道,且每个通道的取值
[!CAUTION] 三通道的拓展 在计算机内部,三通道的图像不是三张独立的图片,而是通过逐像素存储颜色分量的方式来保存整个图像。 每张图片都是由多个像素组成的,而每一个像素存储三个值,分别代表红绿蓝三个颜色的强度。例如一个像素的颜色值可能是(255,153,153)这个颜色会呈现一种粉色。如果一张图片是100x100那么就会有10000个像素。
通常计算机会逐行存储每一个像素的RGB值。 假设图像宽度
W
像素,高度H
像素,那么在内存中存储的时候,图像的大小为W*H*3
字节(每一个通道占用1字节,8位图像情况下) 每一个像素颜色数据按照顺序依次存储:R1,G1,B1,R2,G2,B2,...Rn,Gn,Bn
常见的格式:通常RGB图像可以以不同的格式存储,如BMP、PNG、JPEG等,不同格式的压缩方式和元数据结构可能不同,但是底层依旧基于RGB通道的存储方式。 除了上面提到的逐像素存储之外,还有分通道存储,分通道存储就是将图像中所有红色通道存储在一个数组中,所有绿色通道存储在一个数据中,所有蓝色通道存储在一个数组中,这种方式较少使用,因为它增加图像处理的复杂度。
三、计算机中图像的存储方式
在计算机中,图像都是以数组的形式存在的。一个RGB图像放到内存中就是一个三维数组,其中第一维表示图像的宽度,第二维表示图像的高度,第三维则是图像中每一个像素点的RGB三个像素点,但是在OpenCV中,像素值的存储顺序是BGR,而不是RGB。
计算机处理图像本质上就是三维数组中的像素值进行操作。 、
假设我们有一张 2x2 的彩色图片,它的像素值如下(表示为 BGR):
位置 | 蓝色(B) | 绿色(G) | 红色(R) |
---|---|---|---|
(0,0) | 0 | 128 | 255 |
(0,1) | 50 | 100 | 150 |
(1,0) | 255 | 0 | 0 |
(1,1) | 200 | 150 | 100 |
[
# 一维代表图像的高度(2行)
[
# 二维代表图像的宽度(2列)
[0,128,255], # 三维是每个像素的三个通道,存储着BGR值(蓝色、绿色、红色)
[50,100,150]
],
[
[255,0,0],
[200,150,100]
]
]
四、实验代码
import numpy as np
import cv2
import matplotlib.pyplot as plt
# 创建一个空白的700 * 700 彩色图像
image = np.zeros((700,700,3),dtype = np.uint8)
# 显示 image 图像
# cv2.imshow("image",image)
# cv2.waitKey(0)
# 使用plt 显示 image 图像
plt.imshow(image)
plt.title("image") # 显示标签
plt.axis("off")
plt.show()
import numpy as np
import cv2
import matplotlib.pyplot as plt
# 创建一个空白的700 * 700 彩色图像
image = np.zeros((700,700,3),dtype = np.uint8)
# 对图像进行处理,添加上白色分割线
block_size = 100
for i in range(0,700,block_size):
for j in range(0,700,block_size):
image[i, :, :] = (255,255,255)
image[:, j, :] = (255,255,255)
# 给图像的 3*3 的位置一个颜色
rand_color = (125,250,255)
# 要填充的位置的顶点坐标
top_left = (200, 200)
bottom_right = (300, 300)
cv2.rectangle(image, top_left, bottom_right, rand_color,-1)
# 将BGR通道顺序转换为RGB顺序,用于matplotlib显示
image_rgb = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
# 显示 image 图像
# cv2.imshow("image",image)
# cv2.waitKey(0)
# 使用plt 显示 image 图像
plt.imshow(image_rgb)
plt.title("image") # 显示标签
plt.axis("off")
plt.show()
'''
测试一下cv2.split 是如何拆分三通道的
'''
# test_image = np.zeros((2,2,3),dtype=np.uint8)
#
# m = 1
# for x in range(0,2):
# for y in range(0,2):
# for z in range(0,3):
# test_image[x, y, z] = m
# m+=1
#
# print(test_image)
# 对上面的图像拆分三通道
# b, g, r = cv2.split(test_image)
#
# print("b = ",b)
# print("g = ",g)
# print("r = ",r)
b,g,r = cv2.split(image)
# 创建空白通道,用于每个通道
blue_channel = np.zeros((700,700,3),dtype=np.uint8)
green_channel = np.zeros((700,700,3),dtype=np.uint8)
red_channel = np.zeros((700,700,3),dtype=np.uint8)
# 分配颜色通道数据
blue_channel[:, :, 0] = b
green_channel[:, :, 1] = g
red_channel[:, :, 2] = r
# 将BGR通道顺序转换为RGB顺序,用于matplotlib显示
blue_rgb = cv2.cvtColor(blue_channel,cv2.COLOR_BGR2RGB)
green_rgb = cv2.cvtColor(green_channel,cv2.COLOR_BGR2RGB)
red_rgb = cv2.cvtColor(red_channel,cv2.COLOR_BGR2RGB)
# 按照1行3列的布局,这是第1行
plt.subplot(131)
plt.imshow(blue_rgb)
plt.title("blue Channel")
plt.axis("off")
plt.subplot(132)
plt.imshow(green_rgb)
plt.title("green Channel")
plt.axis("off")
plt.subplot(133)
plt.imshow(red_rgb)
plt.title("red Channel")
plt.axis("off")
# 自动调整子图之间的关系,使得更加紧凑
plt.tight_layout()
plt.show()