我是靠谱客的博主 笑点低老师,最近开发中收集的这篇文章主要介绍【OpenCV】学习笔记1-图像基础知识以及OpenCV基本操作,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

什么是数字图像?

我们可以用一个二维函数 f ( x , y ) f(x,y) f(x,y)来定义一张图像,其中 ( x , y ) (x,y) (x,y)是空间坐标,任意一对空间坐标 ( x , y ) (x,y) (x,y)处的幅值 f f f称为图像在该点的强度或灰度。特别地,当 x , y x,y x,y和灰度值 f f f都是有限的离散值时,我们称该图像为数字图像

比特平面

数字图像中每一个像素点的灰度值通常用8bits来存储,所以一共有256个灰度级。需要注意的是,我们一般用无符号八位整型来存储灰度值,在numpy中的数据类型为uint8,无符号数的最高位不代表符号,一个n位的无符号数的表示范围为 0∼2????−1 ,为了更好地理解无符号数,我们需要知道什么是有符号数,这里介绍两种有符号数的表示方式:

a) 原码

在机器中,数的正负号是无法识别的,我们一般规定“0”代表正数,“1”代表负数,并约定二进制数的最高位为符号数,即将符号位放在有效数字的前面组成有符号数。原码就是一种有符号数的表示方式,原码的最高位为符号位,n位的原码表示范围为 −2????−1+1∼2????−1−1 ,例如8位的原码表示范围为 −127∼127 ,0110 0011表示99,1110 0011表示-99。

b) 补码

计算机中有符号数大多都是以补码的形式存储,因为原码不好做减法,而补码做减法却很方便。一个n位的补码表示范围为 −2????−1∼2????−1−1 ,补码的最高位同样为符号位,正的补码与原码相同,对于负数来说,我们先用原码表示除这个负数,然后对符号位外的每位取反,最后加1就可以得到该数的补码。例如补码的0110 0011同样表示99,要表示-99我们需要先写出-99的原码,即1110 0011,除符号位之外每位取反:1001 1100,最后加1: 1001 1101就是-99的补码。

颜色组成

  • 彩色图

我们通常用R(红)、G(绿)、B(蓝)三个通道来表示一张彩色图像,也就是说,一张彩色图像由三个函数 R ( x , y ) R(x, y) R(x,y) G ( x , y ) G(x, y) G(x,y) B ( x , y ) B(x, y) B(x,y)组成。如果每个通道的灰度值用8bits来存储,那一张彩色图像总共可以表示$2^{8+8+8}=16777216 $种颜色,这就是经常所说的“24位真彩色” 。
在这里插入图片描述

  • 灰度图

彩色图像是由R、G、B三通道组成的图片,灰度图(如图(a))就是单通道图片。彩色图像可以通过著名的心理学公式转换为灰度图:

G r a y = 0.299 × R + 0.587 × G + 0.114 × B Gray = 0.299times R + 0.587 times G + 0.114 times B Gray=0.299×R+0.587×G+0.114×B

OpenCV基本操作

1.读取图片

import cv2
import numpy as np
img = cv2.imread('images/doge.png') 
img.shape  
#输出结果:(446, 1678, 3)

默认是彩色图片,图片路径中不能包含中文,读出的数据结构是numpy数组。446是三维数组的第一个维度,对应图片的高;1678是三维数组的第二个维度,对应图片的宽;3对应图片的通道数,这里是彩色图片所以为3。其中读取方式还有以下两种:

含义数字表示
加载一张灰度图0
加载图像,包括它的Alphat通道-1
gray = cv2.imread('images/doge.png', 0)  # 第二个参数为0读取为灰度图片,
gray.shape#输出结果(446, 1678)

2.显示图片

  • cv2.imshow(‘窗口名’,‘numpy数组’)
cv2.imshow('origin', img)  # 显示彩色图,第一个参数是窗口名,第二个参数是图像所对应的numpy数组
cv2.imshow('gray', gray)  # 显示灰度图
cv2.waitKey(0) 
cv2.destroyAllWindows()  # 关闭窗口,默认删除所有窗口

cv2.waitKey里面的参数为等等时间,单位为毫秒,参数为0或负数为按任意键继续。

3.保存图片

  • cv2.imwrite(‘文件名’, numpy数组)
    需要注意文件名要带后缀名,比如jpg,png等等。

4.灰度转换及改变通道顺序

转换为灰度图
其目的是把三通道(彩色图)转换为单通道图像(灰度图),可以通过通过著名的心理学公式转换为灰度图。对于灰度图来说,0对应黑色,255对应白色,灰度值越大对应颜色越白(亮),越小颜色越黑(暗)。

  • cv2.cvtColor(img, flag)
flag解释
cv2.COLOR_GRAY2RGB单通道转三通道
cv2.COLOR_BGR2GRAY彩色转灰度图
cv2.COLOR_BGR2RGBBGR转RGB
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('origin', rgb)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果:
在这里插入图片描述
可以知道,由三通道转为为单通道,按任意键即可关闭窗口。

改变通道顺序
因为历史原因,OpenCV读取和显示的图片通道顺序为B、G、R,而其他包如matplotlib和Pillow通道顺序为RGB,所以如果我们想用OpenCV读取图片再用matplotlib或Pillow显示的话,需要将BGR转化为RGB。将BGR转为RGB主要有下面两种方式:

  • 使用opencv自带的方法
import matplotlib.pyplot as plt
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)#cv2.COLOR_BGR2RGB
plt.subplot(1,2,1)
plt.imshow(rgb)
plt.subplot(1,2,2)
plt.imshow(img)

运行结果:
在这里插入图片描述
其左边为已经转换成RGB在利用matplotlib绘图,右边是BGR顺序,可以发现图片轮廓没有什么差别,颜色有明显的区别。
-使用numpy

# 方法一:
rgb1 = img[:, :, ::-1]  # ::-1代表倒序,BGR倒序后就为RGB
# 方法二:
rgb2 = img[:, :, [2, 1, 0]]  # 利用索引将B和R调换位置
cv2.imshow('rgb1', rgb1)
cv2.imshow('rgb2', rgb2)
cv2.waitKey(0)
cv2.destroyAllWindows()

笔者在学习时经常会对img输出的数组产生疑惑,比如哪个是通道哪个是图片的形状等等,接下来请看下面的图片:
在这里插入图片描述
红色方框总共有446个,下面看一个简答的例子,总的来说,里面的二维数组可以看成是3个通道的侧面积。
在这里插入图片描述

5.通道分离

把彩色图像分离出R、G、B3个通道,方便后续对三个通道分别进行其他的操作

  • cv2.split(img)
    img:待分离通道的图像
B,G,R=cv2.split(img)
cv2.imshow('blue',B)
cv2.imshow('green',G)
cv2.imshow('red',R)
cv2.waitKey(0)
cv2.destroyAllWindows()
#思考:为什么不是蓝色、绿色、红色的三张图片

6.通道合并

通道分离修改后,把三个通道合并成彩色图像

  • cv2.merge([])
B,G,R=cv2.split(img)
B[:]=0
R[:]=0
Img_merge=cv2.merge([B,G,R])
cv2.imshow('merge',Img_merge)
cv2.waitKey(0)
cv2.destroyAllWindows()

同时可以发现,如果只绘制单通道的一张图片,那么是灰度图,如果想看单通道所显示的颜色,需要把另外两个通道px赋值为0在绘制

最后

以上就是笑点低老师为你收集整理的【OpenCV】学习笔记1-图像基础知识以及OpenCV基本操作的全部内容,希望文章能够帮你解决【OpenCV】学习笔记1-图像基础知识以及OpenCV基本操作所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部