机器视觉:第二讲–OpenCV基础操作

第一讲 开发环境搭建

第二讲:随着机器视觉技术的快速发展,想要观看数据处理产生的中间参数,想要通过窗口显示,掌握OpenCV以下基础操作(主要包括:窗口操作函数,图像读写,视频流处理,图形绘制,鼠标事件处理)有助于为后续更复杂的图像处理算法学习打下坚实基础。

如有错误,恳请指教



前言

提示:以下代码默认已经导入:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下代码默认已经导入:

import cv2
import numpy as np

一、窗口操作函数速查表

函数名称 参数说明 常用标志位 注意事项 应用场景
cv2.namedWindow() winname(窗口标识名),flags WINDOW_NORMAL( 窗口大小可调) WINDOW_AUTOSIZE( 自适应内容) 窗口名称必须是唯一标识 创建可交互窗口
cv2.resizewindow() winname,size size包含长和宽 调整预设窗口尺寸
cv2.imshow() winname,image 图像可视化
cv2.waitKey() delay(毫秒) 0(无限等待) 返回按键的ascii码的值 控制图像显示时长
cv2.destroyAllwindws() 程序退出时资源清理

关键注意事项:
窗口名称必须保持唯一性
waitKey(0)会阻塞程序直到按键响应
教义组合使用WINDOW_NORMAL与resizewindow实现灵活布局

注:python中返回x的ascii码的值使用ord(‘x’)

二、图像读写深度解析

1.图像读取最佳实践

image_path = 'data/images/sample.jpg'
img = cv2.imread(image_path)

# 增强型错误处理
if img is None or img.size == 0:
    raise FileNotFoundError(f"图像加载失败,请检查路径:{image_path}")
    
# 通道转换演示(BGR转RGB)
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

2.图像保存参数详解

# 保存为高质量JPEG
cv2.imwrite('output.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, 95])

# PNG无损压缩
cv2.imwrite('output.png', img, [cv2.IMWRITE_PNG_COMPRESSION, 9])

文件格式对照表:

格式 压缩类型 透明度支持 典型应用
JPEG 有损 自然场景图像
PNG 无损 需要透明通道的图像
TIFF 无损 高质量存档
BMP 无损 Windows系统兼容

关键注意事项:
image_path可以是相对路径也可以是绝对路径,路径中不能包含中文字符。图片不存在时返回空值。

三、视频流处理核心技术

1.摄像头实时捕获框架

cap = cv2.VideoCapture(0)  # 主摄像头,摄像头编号0

# 视频参数设置
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
cap.set(cv2.CAP_PROP_FPS,  144.0)

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
        
    # 实时处理模块
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    cv2.imshow('Live Feed', gray)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()

2.视频保存关键技术点

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640,480))

while recording:
    # 获取帧并写入
    out.write(frame)

编码器 文件格式 压缩效率 兼容性
编解码器对照表:

编码器 文件格式 压缩效率 兼容性
XVID AVI 跨平台
H264 MP4 极高 现代设备
MJPG AVI 中等 旧版Windows

关键注意事项:
Python是严格缩进的语言.
1000//144表示向下取整

四、图形绘制高级技巧

注:以下均使用纯黑图片img作画

img = np.zeros((480,640,3), np.uint8)

1.画直线

line(img,pt1,pt2,color,thickness,lineType,shift)
cv2.line(img, (10, 20), (300, 400), (0, 0, 255), 5, 4)
cv2.line(img, (80, 20), (300, 480), (0, 0, 255), 5, 16)

参数说明:
	img:输出图像,通常是一个 NumPy 数组.
	pt1&pt2:直线的端点,是一个包含两个元素 ( x, y) 的元组,代表该点坐标
	color:画线的颜色,对于BGR 图像需要包含三个整数(B, G, R)的元组,对于灰度图只需要一个整数
	thickness:,定义直线的宽度,默认为1
	shift:与直线平滑程度有关(锯齿情况),shift越大越平滑

2.画矩形

rectangle(img,pt1,pt2,color,thickness,lineType,shift)
cv2.rectangle(img, (10, 20), (300, 400), (0, 255, 0), 4, 10)

参数说明:参数同画线,shift越大越平滑

3.画园

circle(img, center, radius, color[, thickness[, lineType[, shift]]])
cv2.circle(img, (320,240), 50, (0, 0, 255), 5, 16)

参数说明:
	img:输出图像,通常是一个 NumPy 数组.
	center:圆心的坐标
	radius:圆的半径
	color:圆的颜色,通常是包含三个整数(B, G, R)的元组,例如(0, 255, 0)表示绿色
	thickness:圆边界线条的宽度
	shift:与直线平滑程度有关(锯齿情况),shift越大越平滑

4.画椭园

ellipse(img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]])
cv2.ellipse(img, (320,240), (100, 50), 45, 0, 180, [0, 0, 255], 5, 16)

参数说明:
	axes:轴的复数(axis(轴) ->axes),需要写入长短轴数据
	center:椭园中心的坐标
	angle:绘画的角度
	startAngle:长轴角度,逆时针
	endAngle:绘画的角度,四分之一90°
	color:椭园的颜色,通常是三个整数(B, G, R)的元组,例如(0, 255, 0)表示绿色
	thickness:椭园边界线条的宽度
	shift:与椭园边界平滑程度有关(锯齿情况),shift越大越平滑

5.画多边形

polylines(img,[pts],isclose,color[, thickness[, lineType[, shift]]])
#具体使用方法如下
pts = np.array([(10, 10), (100, 150), (300, 70), (200, 75)], np.int32)
cv2.polylines(img, [pts], True, (0, 0, 255), 5)

参数说明:
	img:输出图像,通常是一个 NumPy 数组.
	pts:pts点集必须是int32位的坐标集
	isclose:是否封闭
	color:多边形线条颜色,通常是包含三个整数(B, G, R)的元组
	thickness:圆边界线条的宽度
	shift:与直线平滑程度有关(锯齿情况),shift越大越平滑

五、鼠标事件

设置鼠标回调函数

setMouseCallback(winName,callback,userdata)

其中callback可以改为其它
callback(event,x,y,flags,userdata)需要与上面callback对应
event:表示鼠标事件类型的常量(
#define CV_EVENT_MOUSEMOVE 0 //滑动
#define CV_EVENT_LBUTTONDOWN 1 //左键点击
#define CV_EVENT_RBUTTONDOWN 2 //右键点击
#define CV_EVENT_MBUTTONDOWN 3 //中键点击
#define CV_EVENT_LBUTTONUP 4 //左键放开
#define CV_EVENT_RBUTTONUP 5 //右键放开
#define CV_EVENT_MBUTTONUP 6 //中键放开
#define CV_EVENT_LBUTTONDBLCLK 7 //左键双击
#define CV_EVENT_RBUTTONDBLCLK 8 //右键双击
#define CV_EVENT_MBUTTONDBLCLK 9 //中键双击
);
flags: 返回组合键数字

代码示例:

import cv2
import numpy as np

#函数名可以随便写,参数必须是5#event表示鼠标事件,xy是鼠标坐标,flags是鼠标的组合按键
def mouse_callback(event, x, y, flags, userdata):
    print(event, x, y, flags, userdata)

#创建窗口,宽高640*360
cv2.namedWindow('mouse', cv2.WINDOW_NORMAL)
cv2.resizeWindow('mouse', 460, 360)

#设置鼠标回调函数,  qaq及传入数据
cv2.setMouseCallback('mouse', mouse_callback, 'qaq')


#生成全黑图片
img = np.zeros((360, 640, 3), np.uint8)
while True:
    cv2.imshow('mouse', img)
    if cv2.waitKey(1) == ord('q'):
        break

cv2.destroyAllWindows()

六、代码实战

根据按键,在黑色底板绘制不同形状(所见即所得)

代码示例:

import cv2
import numpy as np

#创建纯黑背景图
back = np.zeros((600,600,3), np.uint8)
preview = np.zeros((600,600,3), np.uint8)
#起点&当前形状curshape
starpos=(0, 0)
curshape=0
#鼠标状态,0默认,点击1,弹起2
mouseState=0

#监听鼠标行为
def mouse_callback(event, x, y, flags, userdata):
    global curshape, starpos, mouseState, preview, back
    if event == cv2.EVENT_LBUTTONDOWN:
        starpos = (x, y)
        mouseState = 1
    elif event == cv2.EVENT_LBUTTONUP:
        mouseState = 2
        if curshape == 0:#直线
            cv2.line(back, starpos, (x, y), (0, 0, 255), 3)
        elif curshape == 1:#矩形
            cv2.rectangle(back, starpos, (x, y), (0, 0, 255), 3)
        elif curshape == 2:#圆形
            a = abs(x - starpos[0])
            b = abs(y - starpos[1])
            r = int((a ** 2 + b ** 2) ** 0.5)
            cv2.circle(back, starpos, r, (0, 0, 255), 3)
        else: #其他按键
            print('暂无其他图形')
    elif mouseState == 1:#鼠标点击中
        preview = np.array(back.data)
        if curshape == 0:#直线
            cv2.line(preview, starpos, (x, y), (0, 0, 255), 3)
        elif curshape == 1:#矩形
            cv2.rectangle(preview, starpos, (x, y), (0, 0, 255), 3)
        elif curshape == 2:#圆形
            a = abs(x - starpos[0])
            b = abs(y - starpos[1])
            r = int((a ** 2 + b ** 2) ** 0.5)
            cv2.circle(preview, starpos, r, (0, 0, 255), 3)
        else: #其他按键
            print('暂无其他图形')

#创建窗口
cv2.namedWindow('drawshape', cv2.WINDOW_NORMAL)
#设置鼠标回调函数
cv2.setMouseCallback('drawshape', mouse_callback)


while True:
    if mouseState == 1:
        cv2.imshow('drawshape', preview)
    else:
        cv2.imshow('drawshape', back)
    #检测按键
    key = cv2.waitKey(10)
    #q键退出
    if key == ord('q'):
        break
    #l键画直线
    elif key == ord('l'):
        curshape = 0
    #r键矩形
    elif key == ord('r'):
        curshape = 1
    #c键画园
    elif key == ord('c'):
        curshape = 2
cv2.destroyAllWindows()

总结

本讲详细介绍了OpenCV的基础操作,主要包括以下内容:窗口操作函数,图像读写,视频流处理,图形绘制,鼠标事件处理,实战项目

后续学习建议
练习各种绘图函数,熟悉参数设置
尝试扩展实战项目,添加更多图形类型
探索OpenCV的其他基础功能,如图像滤波和变换
为下一讲图像处理算法做准备

常见问题解答
Q: 为什么我的图像加载失败? A: 检查路径是否正确,路径中不要有中文,确认文件存在

Q: 如何实现窗口自适应? A: 使用WINDOW_NORMAL标志创建窗口,然后可以调整大小

Q: 视频保存时如何选择最佳编解码器? A: 根据需求选择:跨平台用XVID,高压缩用H264,兼容旧系统用MJPG

本讲内容为OpenCV的基础操作,掌握这些知识将为后续更复杂的图像处理算法学习打下坚实基础。

Logo

「智能机器人开发者大赛」官方平台,致力于为开发者和参赛选手提供赛事技术指导、行业标准解读及团队实战案例解析;聚焦智能机器人开发全栈技术闭环,助力开发者攻克技术瓶颈,促进软硬件集成、场景应用及商业化落地的深度研讨。 加入智能机器人开发者社区iRobot Developer,与全球极客并肩突破技术边界,定义机器人开发的未来范式!

更多推荐