OpenCV---图像基础
OpenCV—图像基础
文章目录
- OpenCV---图像基础
- 一、什么是OpenCV
- 二、OpenCV优势
- 三,环境安装
- 四,图像表示
- 五,图像存储
- 彩色图像
- 六,基本图像操作
- 6.1 创建窗体
- 6.2 读取图像
- 6.3 显示图像
- 6.4 保存图像
- 6.5 创建黑白图像
- 6.6 图像切片
- 6.7图像大小调整
- 七,图像绘制
- 7.1绘制直线
- 7.2绘制圆形
- 7.3绘制矩形
- 7.4绘制文本
- 7.5 读取视频
一、什么是OpenCV
OpenCV(开放源代码计算机视觉库)是一个开源的计算机视觉和机器学习软件库。由一系列 C++ 类和函数构成,用于图像处理、计算机视觉领域的算法实现。
二、OpenCV优势
-
开源免费:完全开源,可以自由使用,降低开发成本和技术门槛。
-
多语言支持:除C++原生接口外,还支持Java、Python等编程语言。
-
跨平台:支持多种操作系统,Windows、Linux、ios、Android等,方便开发和部署。
-
丰富API:完善的传统计算机视觉算法,涵盖主流的机器学习算法,同时添加了对深度学习的支持。
三,环境安装
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python
四,图像表示
像素是图像的基本单元,每个像素存储着图像的颜色、亮度和其他特征。一系列像素组合到一起就形成了完整的图像,在计算机中,图像以像素的形式存在并采用二进制格式进行存储。根据图像的颜色不同,每个像素可以用不同的二进制数表示。
计算机采用0/1编码的系统,数字图像也是利用0/1来记录信息,我们平常接触的图像都是8位数图像。opencv中常用的是8位图像,大多数彩色和灰度图像使用8位表示每个通道的像素值,范围从0到255,其中0,代表最黑,1,表示最白。
日常生活中常见的图像是RGB三原色图。RGB图上的每个点都是由红(R)、绿(G)、蓝(B)三个颜色按照一定比例混合而成的,几乎所有颜色都可以通过这三种颜色按照不同比例调配而成。在计算机中,RGB三种颜色被称为RGB三通道,每个通道的取值都是0-255,根据这三个通道存储的像素值,来对应不同的颜色。
五,图像存储
在OpenCV中,无论是读取还是创建图像,结果都是一个NumPy数组。
-
彩色图像:三维数组
-
灰度图像:二维
图像本质上是像素值的二维或三维矩阵(对于彩色图像)。
- 形状(Shape):图像的尺寸由其高(height)、宽(width)和通道数(channels)决定。可以通过
img.shape
属性获取这些信息。- 对于彩色图像(如RGB),返回的是一个包含三个值的元组 (height, width, channels)。
- 对于灰度图像,返回的是一个包含两个值的元组 (height, width),因为灰度图像只有一个通道。
- 数据类型(dtype):图像中的每个像素值的数据类型决定了可以存储的最大值。例如,8位无符号整数(uint8)允许的范围是从0到255。
- 像素表示
- 单通道图像(灰度图像):每个像素由一个数值表示,代表该点的亮度。值越低(接近0),颜色越暗;值越高(接近255),颜色越亮。
- 多通道图像(彩色图像):
在OpenCV中,默认情况下,彩色图像是以BGR(蓝-绿-红)顺序存储
彩色图像
每个像素通常是由红(R)、绿(G)、蓝(B)三个分量来表示的,分量介于(0,255)。RGB图像每一个像素的颜色值(由RGB三原色表示)直接存放在图像矩阵中,由于每一像素的颜色需由R、G、B三个分量来表示,M、N分别表示图像的行列数,三个M x N的二维矩阵分别表示各个像素的R、G、B三个颜色分量。RGB图像的数据类型一般为8位无符号整形,通常用于表示和存放彩色图像。
import cv2 as cvimport numpy as np# 设置图像尺寸
height, width = 512, 512
# 创建一个空白的彩色图像
img = np.zeros((height, width, 3), dtype=np.uint8)
# 修改像素值
img[::] = np.random.randint(0, 256, img.shape)
# 显示图像
cv.imshow('Random Color Image', img)
cv.waitKey(0)
cv.destroyAllWindows()
六,基本图像操作
6.1 创建窗体
dWindow()` 方法创建一个新的窗口。你可以为这个窗口指定一个名称,并且可以选择窗口的属性(例如,是否可调整大小)。
参数:
winname
:窗口名- 窗口属性:窗口大小是否可调整
cv2.WINDOW_AUTOSIZE
:默认,窗口会根据加载的图像自动调整到合适的大小,并且用户不能拖动窗口边缘来调整窗口大小。cv2.WINDOW_NORMAL
:窗口大小是可调整的,用户可以通过鼠标拖动窗口边缘来自由改变窗口大小。
#可调整窗口
cv.namedWindow('mywindow', cv.WINDOW_NORMAL)
#不可调整窗口
cv.namedWindow('mywindow1', cv.WINDOW_AUTOSIZE)
cv.waitKey(0)
cv.destroyAllWindows()
上层是不可调节窗口,下层是可调节窗口
6.2 读取图像
-
2.imread(path [,读取方式])**
参数:
- filename:图像路径
-
读取方式:彩色·默认、灰色等
#创建窗体
img_path = 'txjc/cat1.png'
img = cv.imread(img_path)
cv.imshow('mywindow', img)
简单的读取图像不会显示,需要显示图像要进行下一步
6.3 显示图像
cv2.imshow(winname,img)
参数:
- winname:显示图像的窗口名,以字符串类型表示
- img:要显示的图像
注意:在调用显示图像的API后,要调用cv2.waitKey(0)给图像绘制留下时间,否则窗口会出现无响应情况,并且图像无法显示出来。
-
cv.waitKey(0):表示无限期地等待任何键盘按键。这种用法常见于图像显示窗口中,确保图像在窗口中显示直到用户决定关闭它。
-
cv.waitKey(n):n>0,意味着程序将等待n毫秒。这种方式常用于视频播放或实时摄像头捕获场景,以便控制每一帧停留的时间,同时允许用户通过按键来中断循环或发出命令。
-
cv2.destroyAllWindows([winname])
cv2.destroyAllWindows()
:会在当前程序执行到该语句时立即销毁打开的窗口,并释放与这些窗口相关的资源。winname
:窗口名,关闭指定名称的窗口。可省略,销毁所有已打开的窗口。
#创建窗体
img_path = 'txjc/cat1.png'
img = cv.imread(img_path)
cv.imshow('mywindow', img)
cv.waitKey(0)
cv.destroyAllWindows()
6.4 保存图像
cv2.imwrite(path,img)
参数:
- path:图片保存的路径和图片名
- img:要保存的图像
img_path = 'txjc/cat1.png'
img = cv.imread(img_path)
cv.imshow('mywindow', img)
cv.waitKey(0)
cv.destroyAllWindows()
cv.imwrite('txjc/cat2.jpg', img)
6.5 创建黑白图像
使用np.zeros()
创建全黑图像,再修改像素值成为全白图像。
- numpy.zeros((height,width,channels),dtype=np. uint8)
#创建黑白图像
h = 512
w = 512
black = np.zeros((h, w), np.uint8)
white = np.ones((h, w),np.uint8) * 255
cv.imshow('black', black)
cv.imshow('white', white)
cv.waitKey(0)
cv.destroyAllWindows()
6.6 图像切片
-
Opencv中,图像切片用于从图像中提取一个子区域(矩形区域)。
-
假设你有一个图像
img
,它的类型是numpy.ndarray
。img[y:y+h,x:x+w]
的含义如下:- x:子区域左上角的x坐标
- y:子区域左上角的y坐标
- w:子区域的宽度
- h:子区域的高度
-
切片操作
img[y:y+h,x:x+w]
提取的是从(x,y)
开始,高度为h
,宽度为w
的矩形区域
-
示例
import cv2 as cvimg = cv.imread('txjc/cat1.png')
#定义剪切图像的起点和宽高
print(img.shape)
x, y, w, h = 100, 200, 300, 300
img2=img[y:y+h, x:x+w]#
cv.imshow('img', img)
cv.imshow('img2', img2)
print(img2.shape)cv.waitKey(0)
cv.destroyAllWindows()
6.7图像大小调整
-
cv2.resize
是Opencv库中用于调整图像大小的函数,在图像处理中很常用,特别是在要对图像进行缩放以适应不同需求时。 -
cv2.resize(img,dsize,dts)
- img:输入图像,通常是二维或三位NumPy数组。
- dsize:输出图像的尺寸,是一个二元组
(w,h)
, - dst:缩放后的图像
#调整图像大小
cat = cv.imread('txjc/cat1.png')
print(cat.shape)
#调整图像的大小:cv.resize(img, (宽, 高))
new_cat2 = cv.resize(cat, (500, 500))
cv.imshow('cat', cat)
cv.imshow('new_cat2', new_cat2)
cv.imwrite('image/new_cat2.png', new_cat2)
cv.waitKey(0)
cv.destroyAllWindows()
print(new_cat2.shape)
七,图像绘制
7.1绘制直线
-
cv2.line(img,sart,end,color,thickness)
-
参数
- img:要绘制直线的图像
- start、end:直线的起点和终点
- color:直线的颜色(对于彩色图像,使用 BGR 格式指定颜色)
- thickness:线条宽度
#图像绘制
#绘制直线
cat = cv.imread('txjc/cat1.png')
cv.line(cat, (100, 0), (500, 500), (14, 241, 154), 5)
cv.imshow('cat', cat)
cv.waitKey(0)
cv.destroyAllWindows()
7.2绘制圆形
-
cv2.circle(img,centerpoint,r,color,thickness)
-
参数:
- img:要绘制圆形的图片
- centerpoint、r:圆心和半径
- color:线条颜色
- tnickness:线条宽度,为-1时生成闭合图案并填充颜色
#绘制圆
cat = cv.imread('txjc/cat1.png')
#cv.LINE_AA,反走样技术,抗锯齿
cv.circle(cat, (435, 300), 100, (14, 241, 154), 100,cv.LINE_8)
cv.circle(cat, (600, 400), 100, (14, 241, 154), 100,cv.LINE_8)
cv.imshow('cat', cat)
cv.waitKey(0)
cv.destroyAllWindows()
翻译失败
7.3绘制矩形
-
cv2.rectangle(img,leftupper,rightdown,color,thickness)
-
参数:
- img:要绘制矩形的图像
- leftupper、rightdown:矩形的左上角和右下角坐标
- color:线条的颜色
- thickness:线条的宽度
#绘制矩形
cat = cv.imread('txjc/cat1.png')
cv.rectangle(cat, (100, 100), (500, 500), (14, 241, 154), 5)
cv.imshow('cat', cat)
cv.waitKey(0)
cv.destroyAllWindows()
7.4绘制文本
-
cv2.putText(img,text,station,font,Fontscale,color,thickness,cv2.LINE_AA)
-
参数:
- img:要添加文字的图像
- text:要写入的文本数据
- station:文本的放置位置
- font:字体样式
- Fontscale:字体大小
- thickness:字体线条宽度
- cv2.LINE_AA:使用反走样技术绘制文本边框
- 反走样是一种提高图形质量的技术,通过混合颜色和像素边缘来减少锯齿状效果,使文本看起来更加平滑、清晰。
#绘制文字
cat = cv.imread('txjc/cat1.png')
cv.putText(cat, 'Hello World', (100, 100), cv.FONT_HERSHEY_SIMPLEX, 1, (14, 241, 154), 5)
cv.imshow('cat', cat)
cv.waitKey(0)
cv.destroyAllWindows()
7.5 读取视频
-
cap = cv2.VideoCapture(path)
- path:视频流资源路径设置为0,代表从默认摄像头捕获视频流
-
ret,frame = cap.read()
-
返回值cap调用read()方法得到一个布尔值和一帧图像,布尔值表示是否成功读取到帧,如果为False,可能是因为视频结束或读取失败,如果为True,frame则是当前帧的图像数据。
-
捕获摄像头的实时视频流
#读取视频
cap = cv.VideoCapture('txjc/1.mp4')
#设置窗口大小
cv.namedWindow('video', cv.WINDOW_NORMAL)
cv.resizeWindow('video', 480, 780)while True:ret, frame = cap.read()if not ret:breakcv.imshow("video", frame)if cv.waitKey(40) & 0xFF == ord('q'):break
cap.release()cv.destroyAllWindows()