计算机眼中的图像(机器视觉)


图像增强有很多方式,在最后的智能分拣项目中主要用的就是亮度的调节。 除了亮度的调节外,还做了镜像翻转的实验

一、像素

1.1 像素的概念

像素是图像的基本单元,每一个像素存储着图像的颜色、亮度和其他特征,一张图片是由很多像素组成的。 像素是组成图像的最小单元,通常以矩阵形式组织。每个像素可以理解为一个色彩点,具有不同的颜色和亮度值。

1.2 分辨率

像素数量决定图像的分辨率。图像的分辨率越高,像素越多,图像越清晰。 举例:1080p (1920 x 1080) 意味着有1920个水平像素和1080个垂直像素,总共2,073,600个像素 右边是669x669像素点,左边100x100像素点 image.png

1.3 灰度图像

灰度图像仅包含亮度信息,像素值范围为0到255(8-bit),其中0代表黑色,255代表白色。

灰度图像 image.png

二、RGB颜色

日常生活中常见的图像都是RGB三色图,R代表红色、G代表绿色、B代表蓝色。RGB图是由很多像素点构成的,每一个像素点都是由R、G、B三个颜色混合构成的,几乎所有的颜色都可以通过这三种颜色合成。 除了RGB颜色模型之外还有很多其他的颜色模型 [[01-颜色模型]]

而在计算机中,RGB三种颜色被称为RGB三通道,且每个通道的取值 image.png

[!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)0128255
(0,1)50100150
(1,0)25500
(1,1)200150100
[
	# 一维代表图像的高度(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()

image.png

image.png