图像获取和基本运算
图像的基本类型:
二值图像(黑白)、灰度图像、索引图像、彩色图像。
图像的基本操作:
图像的读取:cv2.imread()
img=cv2.imread(filename,flags)
filename:完整路径名(相对或者绝对)
flags: 标志位, 表示读取数据的格式。
读取彩色:cv2.IMREAD_COLOR(flags=1),
读取灰度图像:cv2.IMREAD_GRAYSCALE(flags=0),
读取原始图像:cv2.IMREAD_UNCHANGED(flags=-1)。
图像的显示:cv2.imshow()
cv2.imread(winname,img)
winname:显示窗口名字,img需要显示的图像
namedWindow()创建指定窗口
waitKey(delay) 等待按键,ms为单位【不调用窗口会一闪而过】
destoryAllWindows()释放窗口
图像的保存:cv2.write()
cv2.write(filename,img,params)
params:类型参数 jpg表示质量(默认95,取值0-100),png表示压缩级别(默认3)
【如果需要读取文件夹中图像,需要调用os系统库。可以设置path_dir】
图像的属性:shape、size、dtype
题目1:读取pic文件中的所有图像,并保存到pics子目录中
python
import cv2
import os
path_dir="d:/pic"
for filename in os.listdir(path_dir):
image=cv2,imread(path_dir+"/"+filename)
cv2.imshow(filename,img)
cv2.waitKey(2)
cv2.imwrite("d:/pics"+"/"+filename,image)
cv2.destoryAllWindow()
视频图像
实时图像的获取:
打开摄像头:cv2.videoCapure()
读取摄像头的视频数据帧:read(),返回两个参数(ret,frame)。ret是bool类型,表示是否读取成功。
释放摄像头:release()
打开内置摄像头,实时显示视频图像,并将视频写入MYvideo.avi中。
python
import cv2 # 导入OpenCV库,用于计算机视觉任务
cap = cv2.VideoCapture(0) # 创建VideoCapture对象,参数0表示使用默认摄像头
fourcc = cv2.VideoWriter_fourcc(*'XVID') # 定义视频编码格式为XVID
out = cv2.VideoWriter('MYvideo.avi', fourcc, 20.0, (640, 480)) # 创建VideoWriter对象,设置输出文件名、编码、帧率和分辨率
while cap.isOpened(): # 循环检测摄像头是否成功打开
ret, frame = cap.read() # 读取摄像头画面,ret返回是否成功,frame保存图像数据
if ret: # 如果成功读取到帧
out.write(frame) # 将当前帧写入视频文件
cv2.imshow('Camera', frame) # 显示当前帧图像,窗口标题为'Camera'
if cv2.waitKey(1) & 0xFF == ord('q'): # 等待1ms,检测是否按下q键
break # 如果按下q键则退出循环
else:
break # 如果读取失败则退出循环
cap.release() # 释放摄像头资源
out.release() # 释放VideoWriter资源
cv2.destroyAllWindows() # 关闭所有OpenCV创建的窗口
【cv2.waitKey(1)内延迟时间不能写0,否则视频不连续】
图像运算
图像算术运算
图像算术运算主要涉及像素级的数学操作,常用的函数包括加法、减法、乘法、除法、位运算等。
-
加法运算
cv2.add(src1, src2):对两幅图像的像素值进行饱和加法(防止溢出)。应用场景:图像融合、多帧降噪、增强亮度。【opencv是一种饱和操作,numpy是取余】
-
加权加法
cv2.addWeighted(src1, alpha, src2, beta, gamma):实现两幅图像的线性混合。公式:
(
)
应用场景:图像渐变、水印叠加。
-
减法运算
cv2.subtract(src1, src2):计算两幅图像的差值。应用场景:运动检测、背景消除、医学图像分析。
-
乘法运算
cv2.multiply(src1, src2):逐像素乘法,常用于掩模操作。应用场景:区域增强、光照校正。
-
除法运算
cv2.divide(src1, src2):逐像素除法,用于归一化或比例调整。应用场景:图像标准化、色彩校正。
-
像素级操作:算术运算是基于像素值的直接计算,需注意数据类型(如uint8可能溢出)。
-
饱和与截断:OpenCV的加法默认饱和(超过255设为255),而NumPy的加法会模运算。
-
多通道处理:彩色图像的运算是按通道独立进行的。
-
归一化 :除法运算前常需归一化避免除以零或极端值。
pythonimport cv2 import numpy as np # 加法示例 img1 = cv2.imread('image1.jpg') img2 = cv2.imread('image2.jpg') result = cv2.addWeighted(img1, 0.7, img2, 0.3, 0) # 减法示例 diff = cv2.subtract(img1, img2) # 位运算示例 mask = cv2.bitwise_and(img1, img2)
图像逻辑计算
-
图像逻辑计算指对图像进行基于逻辑运算的处理,通常涉及像素级的与、或、非、异或等操作。常用于图像分割、掩模处理、特征提取等场景。(二值图像分析)
常见的逻辑运算类型
-
与运算(AND):两幅图像对应像素均为真时输出为真,常用于掩模叠加。
-
或运算(OR):任意一幅图像对应像素为真时输出为真,适用于区域合并。
-
非运算(NOT):对图像像素取反,用于背景反转。
-
异或运算(XOR):两幅图像对应像素不同时输出为真,适用于差异检测。
-
目标检测:通过掩模(AND运算)提取特定区域。
-
输入图像需为相同尺寸和数据类型(通常为8位无符号整型)。
-
对于灰度或彩色图像,逻辑运算按通道独立处理。
-
非二值图像需先阈值化处理,否则运算结果可能不符合预期。
-
位运算
cv2.bitwise_and/or/xor/not(src1, src2):基于二进制位的逻辑运算。应用场景:掩模生成、ROI提取、图像加密。
实现
将图片2放在在图片1的右上方
代码实现
python
import cv2
# 加载两幅图像
img1 = cv2.imread('d:/pics/grassland.png') # 背景图
img2 = cv2.imread('d:/pics/opencv-logo-white.png') # OpenCV Logo
# 把logo放在图像的右上角,创建ROI(感兴趣区域)
rows1, cols1, channels1 = img1.shape
rows, cols, channels = img2.shape
roi = img1[0:rows, (cols1 - cols):cols1] # 右上角区域
# 现在创建logo的掩码,并同时创建其相反掩码
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 240, 255, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)
# 现在将ROI中logo的区域涂黑
img1_bg = cv2.bitwise_and(roi, roi, mask=mask)
# 仅从logo图像中提取logo区域
img2_fg = cv2.bitwise_and(img2, img2, mask=mask_inv)
# 将logo放入ROI并修改主图像
dst = cv2.add(img1_bg, img2_fg)
img1[0:rows, (cols1 - cols):cols1] = dst
# 显示结果
cv2.imshow('Result', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
逻辑:
把一个带透明效果的 opencv-logo-white.png 完美贴到背景图 grassland.png 的右上角,让 Logo 看起来就像自然印在背景上一样。
- 准备工作:加载图像
- 读取背景图和 Logo 图,检查图片是否成功加载,避免程序崩溃
- 定位贴 Logo 的位置(ROI 区域)
-
ROI(Region of Interest):就是我们在背景图上准备贴 Logo 的那块区域
-
因为要贴在右上角,所以我们截取背景图右上角一块和 Logo 尺寸完全相同的区域
-
比如 Logo 是
rows × cols大小,那 ROI 就是背景图的[0:rows, (cols1-cols):cols1]
- 生成掩码:分离 Logo 和背景
-
先把彩色 Logo 转成灰度图
img2gray -
通过
threshold函数把灰度图变成黑白二值图:-
像素值 > 240 → 变成白色(255)
-
像素值 ≤ 240 → 变成黑色(0)
-
-
这样得到的
mask里,白色部分是 Logo 的背景,黑色部分是 Logo 本身 -
再用
bitwise_not生成反向掩码mask_inv:黑色变白色,白色变黑色
- 处理背景图的 ROI 区域
-
用
bitwise_and(roi, roi, mask=mask)把 ROI 里和mask白色对应的区域涂黑 -
这样就得到了
img1_bg:ROI 区域里,除了 Logo 要放的地方,其他都保留背景,Logo 位置变成黑色
- 提取 Logo 本身
-
用
bitwise_and(img2, img2, mask=mask_inv)把 Logo 图里和mask_inv白色对应的区域保留 -
这样就得到了
img2_fg:只有 Logo 本身的像素是彩色的,背景全是黑色
- 合并背景和 Logo
-
用
cv2.add(img1_bg, img2_fg)把处理好的 ROI 背景和 Logo 前景加在一起 -
黑色和任何颜色相加还是原来的颜色,所以 Logo 会完美覆盖在黑色区域上
-
得到的
dst就是叠加好的 ROI 区域
- 替换回背景图
-
把处理好的
dst放回背景图原来的 ROI 位置 -
这样背景图的右上角就被替换成了带有 Logo 的新图像
- 显示结果
-
用
cv2.imshow展示最终效果 -
按任意键关闭窗口