当前位置:网站首页>【 2 】 OpenCV image processing: basic knowledge of OpenCV
【 2 】 OpenCV image processing: basic knowledge of OpenCV
2022-08-05 02:19:00 【LeoATLiang】
文章目录
二、OpenCV 基础知识
1、OpenCV 的色彩空间
1.1 RGB 和 BGR
最常见的色彩空间就是RGB,人眼也是基于RGB的色彩空间去分辨颜色的.OpenCV 默认使用的是BGR.
RGB和BGR色彩空间的区别在于图片在色彩通道上的排列顺序不同.
1、RGB 如下图所示:

2、BGR 如下图所示:

Be careful when displaying pictures适配图片color space and 显示环境的色彩空间.
比如传入的图片是BGR色彩空间,显示环境是RGB色彩空间,就会出现颜色混乱的情况.
1.2 HSV、HSL 和 YUV
1、HSV(HSB)
- Hue:色相,即色彩,如红色、绿色、蓝色.
- 用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°.
- 它们的补色是:黄色为60°,青色为180°,紫色为300°.
- Saturation:饱和度,表示颜色接近光谱色的程度.
- 一种颜色,可以看成是某种光谱色与白色混合的结果.
- 其中光谱色所占的比例愈大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高.
- 饱和度高,颜色则深而艳.
- 光谱色的白光成分为0,饱和度达到最高.
- 通常取值范围为0%~100%,值越大,颜色越饱和.
- 一种颜色,可以看成是某种光谱色与白色混合的结果.
- Value(Brightness):明度,表示颜色明亮的程度.
- 对于光源色,明度值与发光体的光亮度有关;
- 对于物体色,This value is related to the transmittance or reflectance of the object.
- 通常取值范围为0%(黑)~100%(白).

OpenCV用的最多的色彩空间是HSV.
2、HSL
HUE:色相,色彩的基本属性,就是平常所说的颜色名称.如红色、黄色等.
Saturation:色彩的纯度,越高色彩越纯,低则逐渐变灰,取0%~100%的数值.
Lightness:亮度,取0%~100%

3、HSV 和 HSL 的区别:
4、YUV
YUV,是一种颜色编码方法.常使用在各个视频处理组件中. YUV在对照片或视频编码时,考虑到人类的感知能力,允许降低色度的带宽.
“Y”表示明亮度(Luminance或Luma),也就是灰阶值,“U”和“V”表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色.
YUV的发明是由于彩色电视与黑白电视的过渡时期.
黑白视频只有Y(Luma,Luminance)视频,也就是灰阶值.到了彩色电视规格的制定,是以YUV/YIQ的格式来处理彩色电视图像,把UV视作表示彩度的C(Chrominance或Chroma),如果忽略C信号,那么剩下的Y(Luma)信号就跟之前的黑白电视频号相同,这样一来便解决彩色电视机与黑白电视机的兼容问题.
YUV最大的优点在于只需占用极少的带宽.
为节省带宽起见,大多数YUV格式平均使用的每像素位数都少于24位.主要的抽样(subsample)格式有YCbCr4:2:0、YCbCr4:2:2、YCbCr4:1:1和YCbCr4:4:4.YUV的表示法称为A:B:C表示法:
- 4:4:4表示完全取样.
- 4:2:2表示2:1的水平取样,垂直完全采样.
- 4:2:0表示2:1的水平取样,垂直2:1采样.
- 4:1:1表示4:1的水平取样,垂直完全采样.

1.3 色彩空间的转换
1.3.1 cvtColor() 颜色转换
cvtColor()用法:
cv2.cvtColor(img, colorspace)
参数说明:
- img:需要转换的图像
- colorspace:What format to convert the image to
cv2.COLOR_BGR2RGBA是将BGR格式转换为RGBA格式
1.3.2 代码实现
import cv2
def callback(value):
print(value)
cv2.namedWindow('color', cv2.WINDOW_NORMAL)
cv2.resizeWindow('color', 640, 480)
# OpenCV读取的图像默认是BGR的色彩空间
img = cv2.imread('../resource/dog.jpg')
# Defines a list of color space conversions 2 = to
color_spaces = [
cv2.COLOR_BGR2RGBA, cv2.COLOR_BGR2BGRA,
cv2.COLOR_BGR2GRAY, cv2.COLOR_BGR2HSV,
cv2.COLOR_BGR2YUV
]
# 创建Trackbar
cv2.createTrackbar('trackbar', 'color', 0, 4, callback)
while True:
# 获取当前Trackbar值
index = cv2.getTrackbarPos('trackbar', 'color')
# 颜色空间转换API
cvt_img = cv2.cvtColor(img, color_spaces[index])
cv2.imshow('color', cvt_img)
key = cv2.waitKey(10)
if key & 0xFF == ord('q'):
break
cv2.destroyAllWindows()

2、Numpy 基本操作
Numpy是一个经高度优化的Python数值库.OpenCV中用到的矩阵都要转换成Numpy数组,然后再进行后续操作.
在使用Numpywhen performing basic operations,都需要导入Numpy库,即import numpy as np.
2.1 创建矩阵
1、创建数组 array()
- 一维数组
a = np.array([1, 2, 3])
- 二维数组
b = np.array([[1, 3, 5], [2, 4, 6]])
2、创建全 0 / 1 数组 zeros() / ones()
zeros()用法:
c = np.zeros((480, 640, 3), np.uint8)
参数说明:
- (480, 640, 3):(行的个数, 列的个数, 通道数/层数)
- np.uint8:矩阵中的数据类型
实例1:4 * 4 * 3(方便演示)
c = np.zeros((4, 4, 3), np.uint8)
print(c)
[[[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]]
[[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]]
[[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]]
[[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]]]
实例2:4 * 4(The number of channels may not be specified/层数,即默认1通道/层)
c = np.zeros((4, 4), np.uint8)
print(c)
[[0 0 0 0]
[0 0 0 0]
[0 0 0 0]
[0 0 0 0]]
ones()用法:
d = np.ones((480, 640, 3), np.uint8)
ones() 用法和 zeros() 用法基本一致,其主要区别是:ones() The created array values are all 1 ,而 zeros() The created arrays are all 0 .
3、创建全值数组 full()
full()用法:
e = np.full((480, 640, 3), 255, np.uint8)
参数说明:
- (480, 640, 3):(行的个数, 列的个数, 通道数/层数)
- 255:表示每个元素的数值
- np.uint8:矩阵中的数据类型
实例1:
e = np.full((4, 4, 3), 255, np.uint8)
print(e)
[[[255 255 255]
[255 255 255]
[255 255 255]
[255 255 255]]
[[255 255 255]
[255 255 255]
[255 255 255]
[255 255 255]]
[[255 255 255]
[255 255 255]
[255 255 255]
[255 255 255]]
[[255 255 255]
[255 255 255]
[255 255 255]
[255 255 255]]]
实例2:Of course, the number of channels may not be specified/层数
e = np.full((4, 4), 255, np.uint8)
print(e)
[[255 255 255 255]
[255 255 255 255]
[255 255 255 255]
[255 255 255 255]]
4、创建单元数组 identity() / eye()
identity()用法:
f = np.identity(3)
参数说明:
- 3:表示几维数组,即 3 * 3(3行3列)
- The main diagonal is1,其它是0
实例1:3 * 3
f = np.identity(3)
print(f)
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
实例2:5 * 5
f = np.identity(5)
print(f)
[[1. 0. 0. 0. 0.]
[0. 1. 0. 0. 0.]
[0. 0. 1. 0. 0.]
[0. 0. 0. 1. 0.]
[0. 0. 0. 0. 1.]]
eye()用法:
g = np.eye(3, 5, k=3)
参数说明:
- (3, 5):3行5列
- k=3:从下标为3The starting diagonal is 1,其它为0(下标0,1,2,3,…)
实例1:
g = np.eye(3, 5, k=3)
print(g)
[[0. 0. 0. 1. 0.]
[0. 0. 0. 0. 1.]
[0. 0. 0. 0. 0.]]
实例2:如果不指定k或者k为0,The default is to start with one(下标为0)That is, the main diagonal assignment1,其它为0.
g = np.eye(3, 5)
h = np.eye(3, 5, 0)
print(g)
print(h)
[[1. 0. 0. 0. 0.]
[0. 1. 0. 0. 0.]
[0. 0. 1. 0. 0.]]
# 效果一样
[[1. 0. 0. 0. 0.]
[0. 1. 0. 0. 0.]
[0. 0. 1. 0. 0.]]
2.2 检索与赋值[y, x] / [y, x, channel]
1、检索
- [y, x]
img = np.zeros((480, 640, 3), np.uint8)
print(img[100, 100])
[0 0 0]
- [y, x, channel]
img = np.zeros((480, 640, 3), np.uint8)
print(img[100, 100, 0])
0
channelUsed to specify the number of channels,由于OpenCV默认是BGR三通道,所以取值0,1,2
2、赋值
实例1:img[y, x] = 255
img[count, 100] = 255
不指定channel,默认白色.

实例2:img[y, x] = [B, G, R]
通道组合 [B, G, R] Generally only need to master the following:
- [255, 0, 0]:蓝色通道(B)
- [0, 255, 0]:绿色通道(G)
- [0, 0, 255]:红色通道
- [255, 255, 255]:白色(混合)
img[count, 100] = [0, 0, 255]

img[count, 100] = [255, 255, 255]

实例3:img[y, x, channel] = 255
OpenCV默认是BGR三通道,所以channel可以取0、1或2,即:
- channel = 0:蓝色通道(B)
- channel = 1:绿色通道(G)
- channel = 2:红色通道
img[count, 100, 0] = 255

代码实现(完整)
import cv2
import numpy as np
img = np.zeros((480, 640, 3), np.uint8)
# Read the value of an element from a matrix
print(img[100, 100])
print(img[100, 100, 1])
count = 0
# Assign a value to an element in a matrix
while count < 200:
# img[count, 100] = 255
# img[count, 100, 0] = 255
img[count, 100] = [255, 255, 255]
count += 1
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.3 获取子矩阵[:, :]
1、[y1: y2, x1: x2]获取像素点x1~x2,y1~y2的区域.
2、[:, :] 或 [:] Get all pixels.
import cv2
import numpy as np
img = np.zeros((480, 640, 3), np.uint8)
roi = img[100:400, 100:600]
# roi[:, :] = [0, 0, 255]
roi[:] = [0, 0, 255]
roi[10:200, 10:200] = [0, 255, 0]
cv2.imshow('img', roi)
cv2.waitKey(0)
cv2.destroyAllWindows()

3、OpenCV 的重要数据结构—Mat
3.1 Mat 介绍
Mat是OpenCV在 C++ 语言中用来表示图像数据的一种数据结构,在 Python 中转换为numpy的ndarray.
- Mat由header和data组成,header中记录了图片的维数、Data such as size and data type.

- Mat在C++中的原型:
class CV_EXPORTS Mat{
public:
...
int dims; //维数
int rows, cols; //行、列数
uchar *data; //存储数据的指针
int *refcount; //引用计数
...
};
- Mat属性
| 字段 | 说明 | 字段 | 说明 |
|---|---|---|---|
| dims | 维度 | channels | 通道数 RGB是3 |
| rows | 行数 | size | 矩阵大小 |
| cols | 列数 | type | dep + dt + chs CV_8UC3 |
| depth | 像素的位深 | data | 存放数据 |
3.2 Mat 拷贝
MatThe default is shallow copy when copying,只拷贝Header中的内容,数据不变.

1、Mat浅拷贝
Mat A
A = imread(file, IMREAD_COLOR)
Mat B(A)
B 与 A 的 Header 不同,但指向的数据相同,如下代码:
img1 = cv2.imread('../resource/cold.jpg', cv2.IMREAD_COLOR)
img2 = img1
img1[10:100, 10:100] = [0, 0, 255]

2、Mat深拷贝
C++中实现方式有两种:
cv::Mat::clone()
cv::Mat::copyTo()
将 Data 也重新赋值一份,A 与 B 完全切断.
在Python中:
img3 = img1.copy()
进行深拷贝后,The original image is not affected during image processing.
img1 = cv2.imread('../resource/cold.jpg', cv2.IMREAD_COLOR)
img3 = img1.copy()
img1[10:100, 10:100] = [0, 0, 255]

3.3 代码实现
import cv2
img1 = cv2.imread('../resource/cold.jpg', cv2.IMREAD_COLOR)
# 浅拷贝
img2 = img1
# 深拷贝
img3 = img1.copy()
img1[10:100, 10:100] = [0, 0, 255]
cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.imshow('img3', img3)
cv2.waitKey(0)
cv2.destroyAllWindows()

3.4 访问图像(Mat)的属性
import cv2
img = cv2.imread('../resource/structure.jpg', cv2.IMREAD_COLOR)
方便演示!
1、img.shape用法:
shape 中包含三个信息:高度、宽度和通道数.
print(img.shape)
(3000, 4500, 3)
i.e. the image(高:3000,宽:4500,通道数:3).
2、img.size用法:
size i.e. the image takes up space = 高度 * 宽度 * 通道数 .
print(img.size)
40500000
3000 * 4500 * 3 = 40500000
3、img.dtype用法:
dtype Represents each element in the image位深.
print(img.dtype)
uint8
uint8 表示 8位无符号整型(0~255).
3.5 通道分离与合并
1、split(mat): 分离
import cv2
import numpy as np
img = np.zeros((480, 640, 3), np.uint8)
b, g, r = cv2.split(img)
b[10:100, 10:100] = 255
g[10:100, 10:100] = 255
cv2.imshow('img', img)
cv2.imshow('b', b)
cv2.imshow('g', g)
cv2.waitKey(0)
cv2.destroyAllWindows()

2、merge((ch1, ch2, ...)): 合并
import cv2
import numpy as np
img = np.zeros((480, 640, 3), np.uint8)
b, g, r = cv2.split(img)
b[10:100, 10:100] = 255
g[10:100, 10:100] = 255
img_merge = cv2.merge((b, g, r))
cv2.imshow('img', img)
cv2.imshow('b', b)
cv2.imshow('g', g)
cv2.imshow('img_merge', img_merge)
cv2.waitKey(0)
cv2.destroyAllWindows()

边栏推荐
- dotnet 6 为什么网络请求不跟随系统网络代理变化而动态切换代理
- 程序员失眠时的数羊列表 | 每日趣闻
- the mechanism of ideology
- 后期学习计划
- 在这个超连接的世界里,你的数据安全吗
- Optimizing the feed flow encountered obstacles, who helped Baidu break the "memory wall"?
- Matlab map with color representation module value size arrow
- [parameters of PyQT5 binding functions]
- select 标签自定义样式
- CMS website construction process
猜你喜欢
![Chapter 09 Use of Performance Analysis Tools [2. Index and Tuning] [MySQL Advanced]](/img/e7/61863c356e4c7bb03ba27865ee7be0.png)
Chapter 09 Use of Performance Analysis Tools [2. Index and Tuning] [MySQL Advanced]

蚁剑高级模块开发

迁移学习——Joint Geometrical and Statistical Alignment for Visual Domain Adaptation

《.NET物联网从零开始》系列

2022了你还不会『低代码』?数据科学也能玩转Low-Code啦!

Transfer Learning - Joint Geometrical and Statistical Alignment for Visual Domain Adaptation

Live playback including PPT download | Build Online Deep Learning based on Flink & DeepRec

Leetcode brushing questions - 22. Bracket generation

J9数字货币论:web3的创作者经济是什么?

Transfer Learning - Distant Domain Transfer Learning
随机推荐
开篇-开启全新的.NET现代应用开发体验
优化Feed流遭遇拦路虎,是谁帮百度打破了“内存墙”?
Leetcode刷题——22. 括号生成
CMS website construction process
学习笔记-----左偏树
后期学习计划
oracle将restful接口封装到视图中
Amazon Cloud Technology joins hands with Thundersoft to build an AIoT platform for industry customers
C语言实现简单猜数字游戏
特殊矩阵的压缩存储
".NET IoT from scratch" series
Xunrui cms website cannot be displayed normally after relocation and server change
Flink 1.15.1 集群搭建(StandaloneSession)
Opening - Open a new .NET modern application development experience
Oracle encapsulates restful interfaces into views
PHP技能评测
Using OpenVINO to implement the flying paddle version of the PGNet inference program
leetcode-另一棵树的子树
SuperMap iDesktop.Net之布尔运算求交——修复含拓扑错误复杂模型
ExcelPatternTool: Excel table-database mutual import tool