OpenCV学习day1
一、OpenCV介绍
是一个开源的计算机视觉和机器学习软件库,由英特尔于1999年首次发布,现由开源社区维护。它支持多种编程语言(如C++、Python、Java),并能在Windows、Linux、macOS、Android和iOS等平台上运行。
1、核心功能
领域 | 主要功能 |
---|---|
图像处理 | 滤波、边缘检测、几何变换(旋转/缩放)、色彩空间转换、直方图均衡化 |
视频分析 | 运动检测、目标跟踪、光流估计 |
特征提取 | SIFT、SURF、ORB、角点检测、特征匹配 |
目标检测 | Haar级联、HOG+SVM、YOLO、SSD、Faster R-CNN(需结合深度学习框架) |
3D重建 | 立体视觉、深度图生成、PCL点云处理 |
机器学习 | KNN、SVM、决策树等传统算法,支持与TensorFlow/PyTorch集成 |
AR增强现实 | 标记识别、姿态估计、虚实融合 |
2. Python版OpenCV特点
- 安装简便:pip install opencv-python(基础版)或 opencv-contrib-python(扩展版)
- NumPy集成:所有图像都以NumPy数组形式操作
- 丰富的API:超过2500种优化算法
- 实时性能:针对Intel处理器优化,支持GPU加速(需编译OpenCV with CUDA)
二、环境安装
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python
三、图像表示
1、图像的基本数据结构
OpenCV图像本质上是NumPy数组
2. 不同图像的表示方式
(1) 灰度图 (单通道)
-
形状:(height, width)
-
像素值范围: 0(黑) ~ 255(白)
(2) 彩色图 (三通道)
- 默认BGR格式 (非RGB!)
- 形状: (height, width, 3)
(3) 带透明度的图像 (四通道)
- BGRA格式 (A表示Alpha透明度通道)
- 形状: (height, width, 4)
四、图像存储
在OpenCV中,无论是读取还是创建图像,结果都是一个NumPy数组。
-
彩色图像:三维数组
-
灰度图像:二维
-
形状(Shape):图像的尺寸由其高(height)、宽(width)和通道数(channels)决定。可以通过img.shape属性获取这些信息。
数据类型(dtype):图像中的每个像素值的数据类型决定了可以存储的最大值。例如,8位无符号整数(uint8)允许的范围是从0到255。 -
- 对于彩色图像(如RGB),返回的是一个包含三个值的元组 (height, width, channels)。
-
- 对于灰度图像,返回的是一个包含两个值的元组 (height, width),因为灰度图像只有一个通道。
图像的存储原理
属性 | 说明 |
---|---|
内存布局 | 行优先存储 (height在最外层) |
数据类型 | 默认uint8 (也可使用float32等类型处理HDR图像) |
通道顺序 | BGR (历史原因导致,与Matplotlib的RGB不同,需注意转换) |
五、基本图像操作
1、创建窗体
- cv2.namedWindow(winname ,[窗口属性])
- 使用 cv2.namedWindow() 方法创建一个新的窗口。你可以为这个窗口指定一个名称,并且可以选择窗口的属性
参数
- winname:窗口名
- 窗口属性:窗口大小是否可调整
-
- cv2.WINDOW_AUTOSIZE:默认,窗口会根据加载的图像自动调整到合适的大小,并且用户不能拖动窗口边缘来调整窗口大小。
-
- cv2.WINDOW_NORMAL:窗口大小是可调整的,用户可以通过鼠标拖动窗口边缘来自由改变窗口大小。
2、读取图像
- cv2.imread(path [,读取方式])
参数: - filename:图像路径
- 读取方式:彩色(默认)、灰色等
3、显示图像
- cv2.imshow(winname,img)
参数
- winname:显示图片的窗口名,以字符串类型表示
- img:要显示的图像
4、保存图像
- cv2.imwrite(path,img)
参数
- path:图片保存的路径和图片名
- img:要保存的图像
以上基础操作代码演示以及注释
import cv2 as cv
#创建窗体,默认不可调整大小,参数 cv.WINDOW_AUTOSIZE
cv.namedWindow('window1')
#创建窗体,参数cv.WINDOW_NORMAL,表示可以鼠标拖动窗口边缘来自由改变窗口大小
cv.namedWindow('window2',cv.WINDOW_NORMAL)#读取图像
img=cv.imread("../images/1.jpg")
print(img) #打印img图像数组的数值表示
print(img.shape) #打印img图像的形状 (h,w,c)
print(img.dtype) #打印img图像数组的数据类型
#读取图像,以灰色的方式
gray=cv.imread("../images/1.jpg",cv.IMREAD_GRAYSCALE)
print(gray,gray.shape,gray.dtype)#保存图像
cv.imwrite("./gray.jpg",gray)
#显示图像
cv.imshow( "window1",gray)
cv.imshow("window2",img)
# 留下绘制时间 等待n毫秒 0表示一直等待
cv.waitKey(0)
# 销毁窗口,释放资源
cv.destroyAllWindows()
5、创建黑白图像
使用np.zeros()创建全黑图像,再修改像素值成为全白图像。
- numpy.zeros((height,width,channels),dtype=np. uint8)
import cv2 as cv
import numpy as np#创建黑色图像
black = np.zeros((640,480,3),dtype=np.uint8)
#显示图像
cv.imshow('black',black)
#创建白色图像
white = np.full((640,480,3),255,dtype=np.uint8)
cv.imshow('white',white)#创建随机像素值图像
random = np.random.randint(0,255,(640,480,3),dtype=np.uint8)
cv.imshow('random',random)cv.waitKey(0)
cv.destroyAllWindows()
6、图片大小的调整
- cv2.resize是Opencv库中用于调整图像大小的函数,在图像处理中很常用,特别是在要对图像进行缩放以适应不同需求时。
- cv2.resize(img,dsize)
- img:输入图像,通常是二维或三位NumPy数组。
- dsize:输出图像的尺寸,是一个二元组(w,h),
import cv2 as cv
#读图
cat = cv.imread("../images/cat1.png")
#调整图像大小(w,h)
dst = cv.resize(cat,(640,480))
cv.imshow("cat", cat)
cv.imshow("dst", dst)
cv.waitKey(0)
cv.destroyAllWindows()
7、图像的切片(图像剪裁)
OpenCV中,图片切片用于从图像中提取一个子区域
假设你有一个图像img,它的类型是numpy.ndarray。img[y:y+h,x:x+w]的含义如下:
- x:子区域左上角的x坐标
- y:子区域左上角的y坐标
- w:子区域的宽度
- h:子区域的高度
import cv2 as cv
#读图
cat = cv.imread("../images/cat1.png")
#剪裁 380,240 477,374 [h1:h2,w1:w2]
cat1 = cat[240:374,380:477]
cv.imshow("eye", cat1)
cv.imshow("cat", cat)
cv.waitKey(0)
cv.destroyAllWindows()
如果改变截取的图像属性,那么原图像本来被截取的属性也随之发生更改;说明在切片操作过程中,只是将原图像的部分进行一个浅copy操作,他们实际的内存还是指向同一个地址
六、图像绘制
1、绘制直线
- cv2.line(img,sart,end,color,thickness)
- 参数
- img:要绘制直线的图像
- start、end:直线的起点和终点
- color:直线的颜色(对于彩色图像,使用 BGR 格式指定颜色)
- thickness:线条宽度
2、绘制圆形
- cv2.circle(img,centerpoint,r,color,thickness)
- 参数:
- img:要绘制圆形的图片
- centerpoint、r:圆心和半径
- color:线条颜色
- tnickness:线条宽度,为-1时生成闭合图案并填充颜色
3、绘制矩形
- cv2.rectangle(img,leftupper,rightdown,color,thickness)
- 参数:
- img:要绘制矩形的图像
- leftupper、rightdown:矩形的左上角和右下角坐标
- color:线条的颜色
- thickness:线条的宽度
图像绘制代码:
import cv2 as cv
#读图
cat = cv.imread("../images/cat1.png")
#绘制直线 (w,h)
cv.line(cat,(200,200),(200,400),(0,0,255),2)
#绘制矩形 (左上),(右上)
cv.rectangle(cat,(66,72),(312,331),(0,255,0),3)
#绘制圆 参数cv.LINE_AA:反走样技术 抗锯齿 平滑
cv.circle(cat,(606,401),80,(0,0,0),2,cv.LINE_AA)cv.imshow("cat",cat)
cv.waitKey(0)
cv.destroyAllWindows()
七、读取视频
- cap = cv2.VideoCapture(path)
- path:视频流资源路径设置为0,代表从默认摄像头捕获视频流
- ret,frame = cap.read()
- 返回值cap调用read()方法得到一个布尔值和一帧图像,布尔值表示是否成功读取到帧,如果为False,可能是因为视频结束或读取失败,如果为True,frame则是当前帧的图像数据。
import cv2 as cv
#创建一个videocapture对象
#传具体路径,读取视频文件
cap1 = cv.VideoCapture("../images/videocap.mp4")
#传0,从默认摄像头获取实时视频流
cap = cv.VideoCapture(0)
#循环读取每一帧图像
while True:ret, frame = cap1.read()#判断是否读取成功if not ret:print("读取失败!!")breakcv.imshow("video", frame)if cv.waitKey(40)&0xff == ord("q"):print("按键退出!!")break
cap1.release()
cv.destroyAllWindows()