当前位置: 首页 > news >正文

小白学OpenCV系列2-理解图像

上篇文章中,我们学习了如何安装OpenCV,以及一些简单的函数操作,今天这篇文章就一起来看看图像的本质是什么,在计算机里如何表示。

如何表示图像

二值图像

所谓二值图像,就是仅仅包含黑白两种颜色的图像,我们以下面这张图为例,来看看在计算机的世界里是如何看待图像的。
在这里插入图片描述
使用下面的代码读取,我们可以看到该图像实际上用了一个256x256的矩阵表示,其中每个单元(也称为像素点)的取值只有0(黑色)和255(白色)两种。

import cv2  
import numpy as np  # flags=0表示以单通道灰度图形式加载图像
lena = cv2.imread("lena_two.jpg", flags=0)
print(np.shape(lena))  
cv2.imshow("lena", lena)  
cv2.waitKey()    
cv2.destroyAllWindows()

灰度图像

二值图像虽然简单方便,但却不够细腻,缺少细节信息,灰度图像则是在其基础上,用了更多的数值来表示不同的颜色。通常情况下,计算机会将灰度处理为256个灰度级,用数值0-255来表示,也就是说在二值图像所表达的黑白外,增加了254个数值来表示从纯白到纯黑之间不同级别的灰度。
请添加图片描述
同样使用上述代码,可以看到矩阵大小不变,但是其数值已不再只是0和255了。
在这里插入图片描述

彩色图像

相比于二值图像和灰度图像,彩色图像在我们的日常生活中更为常见,它展现了更丰富的细节。那么计算机又如何表示一张彩色图像呢?实际上这里牵扯到一个很重要的概念-颜色空间,不同的颜色空间具有不同的表示方式。
颜色空间就是我们去看待颜色的方式,从生物学角度来看,在视网膜上存在三种不同的颜色感受器,能够感受三种不同的颜色:红色、绿色和蓝色,而自然界中常见的各种色光都可以通过这三种颜色按照一定的比例混合而成。从光学角度来看,可以将颜色解析成主波长、纯度、明度等。从视觉角度来看,可以将颜色解析成色调、饱和度、亮度等。不同的颜色空间适用于不同的场景,在选择的时候需要依据实际需求来决定,颜色空间之间可以按照公式进行转换。
RGB颜色空间是我们经常使用的一种,它存在三个通道,即红色、绿色和蓝色,每个通道的取值范围都在0-255之间,三个通道组合起来就可以表示各种颜色。下表列出了常见RGB值对应的颜色:

RGB值(R,G,B)颜色十六进制代码
(0,0,0)纯黑色#000000
(255,255,255)纯白色#FFFFFF
(255,0,0)红色#FF0000
(0,255,0)绿色#00FF00
(0,0,255)蓝色#0000FF
(255,255,0)黄色#FFFF00
(0,255,255)青色#00FFFF
(128,128,128)灰色#808080

事实上,每个通道都可以理解为一个独立的灰度图像,以下图为例,我们来看看其在计算机中是如何存储的:
在这里插入图片描述

import cv2  
import numpy as np  # flags=1表示以BGR三通道格式加载  
lena = cv2.imread("lenacolor.png", flags=1)  
print(np.shape(lena))  
cv2.imshow("lena", lena)  
cv2.waitKey()    
cv2.destroyAllWindows()

使用上述代码读取后,可以发现它是一个512x512x3的矩阵,前面的两个数字是每个通道的形状,最后的数字代表3个通道,不同的是在OpenCV中,第一个通道是B,第二个通道是G,第三个通道是R,刚好和RGB颜色空间的图像通道相反(第一个通道是R,第二个通道是G,第三个通道是B)。

像素操作

实际上,当图像被读取到计算机里之后,就是一个矩阵罢了,其类型为numpy.array,我们可以通过索引来操作数组值,也可以通过item函数更加高效地访问。下面我们就用该函数实现灰度图像上绘制一个白色矩形框的效果,代码如下所示:

import cv2  
import numpy as np  # flags=0表示以单通道灰度图加载  
lena = cv2.imread("lena.bmp", flags=0) 
# 绘制一个白色矩形框 
for i in range(10, 100):  for j in range(80, 100):  print(f"矩阵位置{i},{j}的值从{lena.item(i, j)}更改为255")  lena.itemset((i, j), 255)  cv2.imshow("lena", lena)  
cv2.waitKey()   
cv2.destroyAllWindows()

在这里插入图片描述

通道操作

之前我们介绍过用RGB颜色空间来表示一张彩色图像,它是由R通道、G通道、B通道三个通道构成的,而在OpenCV中,通道是按照B通道-G通道-R通道的顺序存储的。

通道拆分

在实际应用中,我们可能会需要将三个通道拆分出来,主要有两种方式:索引和库函数。
1、索引拆分
索引拆分的方式很简单,利用下述代码可以将彩色图像分离出三个通道的图像。

import cv2  lena = cv2.imread("lenacolor.png", flags=1)  b_lena = lena[:, :, 0]  
g_lena = lena[:, :, 1]  
r_lena = lena[:, :, 2]  print("b通道图像")  
cv2.imshow("b_lena", b_lena)  
cv2.waitKey()  print("g通道图像")  
cv2.imshow("g_lena", g_lena)  
cv2.waitKey()  print("r通道图像")  
cv2.imshow("r_lena", r_lena)  
cv2.waitKey()  cv2.imwrite("b_lena.png", b_lena)  
cv2.imwrite("g_lena.png", g_lena)  
cv2.imwrite("r_lena.png", r_lena)  
cv2.destroyAllWindows()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、库函数拆分
OpenCV也提供了split函数来拆分图像的通道:

import cv2  lena = cv2.imread("lenacolor.png", flags=1)  
b_lena, g_lena, r_lena = cv2.split(lena)

通道合并

既然可以拆分通道,那么也可以将拆分后的各通道进行合并,OpenCV提供了merge函数来实现此功能,借助下述代码可以将上述拆分的各通道合并。

import cv2  b_lena = cv2.imread("b_lena.png", flags=0)  
g_lena = cv2.imread("g_lena.png", flags=0)  
r_lena = cv2.imread("r_lena.png", flags=0)  lena = cv2.merge([b_lena, g_lena, r_lena])  
cv2.imshow("lena", lena)  cv2.waitKey()  
cv2.destroyAllWindows()

在这里插入图片描述

可以看到能够完全复原初始的彩色图像,如果我们将b,g,r三个通道颠倒过来,看看又会是怎样的呢?

import cv2  b_lena = cv2.imread("b_lena.png", flags=0)  
g_lena = cv2.imread("g_lena.png", flags=0)  
r_lena = cv2.imread("r_lena.png", flags=0)  lena = cv2.merge([r_lena, g_lena, b_lena])  
cv2.imshow("lena", lena)  cv2.waitKey()  
cv2.destroyAllWindows()

在这里插入图片描述
可以看出整张图像的风格从暖色调一下子就变到了冷色调。

获取图像属性

在图像处理过程中,经常需要获取图像的属性,常用的包括:

  • shape:如果是彩色图像,则返回包含行数、列数、通道数的数组;如果是二值图像或灰度图像,则仅返回行数和列数。
  • size:返回图像的像素数目。
  • dtype:返回图像的数据类型。

我们可以通过下述代码来展示其使用方式:

import cv2  lena = cv2.imread("lena.bmp", flags=0)  
print(f"灰度图像的属性为:")  
print(f"lena.shape={lena.shape}")  
print(f"lena.size={lena.size}")  
print(f"lena.dtype={lena.dtype}")  
lena = cv2.imread("lenacolor.png", flags=1)  
print(f"彩色图像的属性为:")  
print(f"lena.shape={lena.shape}")  
print(f"lena.size={lena.size}")  
print(f"lena.dtype={lena.dtype}")

总结

本篇文章主要介绍了几种常见的图像类型:二值图像、灰度图像和彩色图像。二值图像常用0表示黑色,255表示白色;灰度图像则使用了0-255总计256个值来表示不同颜色;彩色图像则有多种表达方式,常见的RGB颜色空间使用了R、G、B三个通道来表示一张彩色空间,每个通道都可以理解为一个独立的灰度图像。另外还介绍了一些常见的图像处理方法,如像素操作(itemset)、通道操作(split、merge)及属性获取(shape、size、dtype)。

http://www.lryc.cn/news/609174.html

相关文章:

  • 使用纯Docker命令搭建多服务环境(Linux版)
  • Web 开发 11
  • 腾讯人脸识别
  • lumerical——锥形波导偏振转换
  • 大白话讲解MCP
  • 机器学习第四课之决策树
  • Android 之 蓝牙通信(2.0 经典)
  • Kaggle 竞赛入门指南
  • ELECTRICAL靶机复现练习笔记
  • C++中多线程和互斥锁的基本使用
  • 【数据结构】二叉树的顺序结构实现
  • 15_01_opencv_形态学滤波
  • 35.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--数据缓存
  • Android 之 RxJava2
  • Kali基础知识点【1】
  • 基于图像识别与分类的中国蛇类识别系统
  • gitee使用教程
  • 电路原理图绘制专业实战教程2
  • 生成式人工智能展望报告-欧盟-04-社会影响与挑战
  • Java中手动床架一个线程池
  • [硬件电路-134]:模拟电路 - 运算放大器常见运算:两模拟信号相加、相减、单模拟信号的积分、微分...
  • template<typename R = void> 意义
  • 【Python练习】075. 编写一个函数,实现简单的语音识别功能
  • golang的包和闭包
  • slice() 和 splice()
  • 决策树模型知识点整理:从原理到实战(含可视化与调参)
  • Corrosion2靶机练习笔记
  • 【图像处理基石】如何使用deepseek进行图像质量的分析?
  • 【Django】-9- 单元测试和集成测试(上)
  • Day23--回溯--39. 组合总和,40. 组合总和 II,131. 分割回文串