机器视觉opencv总结
import cv2
a =cv2.imread('zzd01.png')
cv2.imshow('cc',a)
d = cv2.waitKey(5000)c = a.copy()
c[:,:,1] = 0
c[:,:,2] = 0
在 OpenCV 中,图像是以 NumPy 数组的形式存储的,对于彩色图像通常采用 BGR(蓝、绿、红)通道顺序(注意不是 RGB)。
代码中的c[:,:,1] = 0
和c[:,:,2] = 0
这两行的作用是:
c[:,:,1] = 0
:将图像中所有像素的绿色通道(G 通道,索引为 1)的值设置为 0c[:,:,2] = 0
:将图像中所有像素的红色通道(R 通道,索引为 2)的值设置为 0
执行这两行代码后,只剩下蓝色通道(B 通道,索引为 0)保留了原始图像的信息,所以最终得到的图像会是原图的蓝色分量单独显示的效果,看起来是一幅蓝色调的图像。
b,g,r =cv2.split(a)
hebing = cv2.merge((b,g,r))
cv2.imshow('cc2',hebing)
cv2.waitKey(5000)
- 使用
cv2.split()
函数将原始彩色图像a
按通道拆分 - 拆分后得到三个单通道图像:
b
:蓝色通道(B 通道)g
:绿色通道(G 通道)r
:红色通道(R 通道)
- 使用
hebing = cv2.merge((b, g, r))
:- 使用
cv2.merge()
函数将拆分后的三个单通道图像重新合并 - 这里按照
(b, g, r)
的顺序合并,与 OpenCV 默认的 BGR 格式一致
- 使用
import cv2b = cv2.imread("zzd01.png",0)
cv2.imshow('bb',b)
a = cv2.waitKey(2000)
# cv2.destroyWindow('bb')print(b.shape)
print(b.dtype)
print(b.size)
cv2.imwrite("gery.png",b)c = b[50:90,50:90]
cv2.imshow("cc",c)
d = cv2.waitKey(2000)
cv2.destroyAllWindows()
b = cv2.imread("zzd01.png",0)
:- 以灰度模式读取图像 "zzd01.png"(参数
0
表示将图像转为单通道灰度图) - 读取后的图像
b
是一个二维数组(单通道)
- 以灰度模式读取图像 "zzd01.png"(参数
print(b.shape)
:输出图像的尺寸(高度,宽度),例如(480, 640)
print(b.dtype)
:输出图像数据类型,通常是uint8
(8 位无符号整数)print(b.size)
:输出图像的总像素数(高度 × 宽度)
c = b[50:90,50:90]
:- 对图像进行裁剪,截取从坐标 (50,50) 到 (90,90) 的区域(行范围 50-90,列范围 50-90)
- 裁剪后的图像尺寸为 40×40 像素
import cv2a = cv2.VideoCapture('dqvedio.mp4')
if not a.isOpened():print("视频损坏,无法读取 ")exit()while True:ref,fream=a.read()if not ref:break# fream = cv2.cvtColor(fream,cv2.COLOR_BGR2RGB)cv2.imshow('Video',fream)if cv2.waitKey(6)==27:break
a.release()
cv2.destroyAllWindows()
a = cv2.VideoCapture('dqvedio.mp4')
:- 创建一个视频捕获对象,用于读取指定的视频文件 "dqvedio.mp4"
if not a.isOpened():
部分:- 检查视频文件是否成功打开
- 如果无法打开(如文件不存在、格式不支持等),则打印提示信息并退出程序
while True:
循环部分:- 这是视频播放的主循环,逐帧读取并显示视频
ref, fream = a.read()
:读取一帧视频,ref
是布尔值表示是否读取成功,fream
是读取到的帧图像if not ref: break
:如果读取失败(如已到视频末尾),则退出循环
视频显示部分:
- 注释掉的
fream = cv2.cvtColor(fream,cv2.COLOR_BGR2RGB)
表示可以将 BGR 格式转为 RGB 格式(OpenCV 默认读取为 BGR 格式) cv2.imshow('Video',fream)
:在名为 'Video' 的窗口中显示当前帧
- 注释掉的
退出控制:
if cv2.waitKey(6)==27: break
:等待 6 毫秒(控制播放速度),如果按下 ESC 键(ASCII 码 27)则退出循环
资源释放:
a.release()
:释放视频捕获对象cv2.destroyAllWindows()
:关闭所有显示窗口
import cv2
ys = cv2.imread("zzd02.png")top,bottom,left,right = 60,60,60,60constant = cv2.copyMakeBorder(ys,top,bottom,left,right,borderType=cv2.BORDER_CONSTANT,value=(60,60,60))
reflect = cv2.copyMakeBorder(ys,top,bottom,left,right,borderType=cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(ys,top,bottom,left,right,borderType=cv2.BORDER_REFLECT101)
replicate = cv2.copyMakeBorder(ys,top,bottom,left,right,borderType=cv2.BORDER_REPLICATE)
wrap =cv2.copyMakeBorder(ys,top,bottom,left,right,borderType=cv2.BORDER_WRAP)cv2.imshow("ys",ys)
cv2.waitKey(10000)
cv2.imshow("constant",constant)
cv2.waitKey(10000)
cv2.imshow("reflect",reflect)
cv2.waitKey(10000)
cv2.imshow("reflect101",reflect101)
cv2.waitKey(10000)
cv2.imshow("replicate",replicate)
cv2.waitKey(10000)
cv2.imshow("wrap",wrap)
cv2.waitKey(10000)
ys = cv2.imread("zzd02.png")
:- 读取原始图像 "zzd02.png",存储在变量
ys
中
- 读取原始图像 "zzd02.png",存储在变量
top,bottom,left,right = 60,60,60,60
:- 定义边框尺寸:上下左右各添加 60 像素的边框
生成不同类型的边框图像:
constant
:使用cv2.BORDER_CONSTANT
类型,添加纯色边框,颜色由value=(60,60,60)
指定(暗灰色)reflect
:使用cv2.BORDER_REFLECT
类型,边框为原图边缘像素的镜像反射(类似镜面效果,边缘像素会被重复)reflect101
:使用cv2.BORDER_REFLECT101
类型,也是镜像反射效果,但边缘像素不会被重复(更自然的反射)replicate
:使用cv2.BORDER_REPLICATE
类型,边框由原图边缘像素向外延伸复制(重复边缘像素)wrap
:使用cv2.BORDER_WRAP
类型,边框采用原图对侧内容填充(类似图像平铺环绕效果)
import numpy as np
import cv2
a = cv2.imread("zzd01.png")
b = cv2.imread("zzd02.png")
b1 = b.copy()
b1[250:450,250:450] = np.random.randint(0,256,(200,200,3))
cv2.imshow("b1",b1)
cv2.waitKey(5000)
使用
b.copy()
创建了图像b
的副本b1
(这样操作不会影响原始图像b
)。核心操作是
b1[250:450,250:450] = np.random.randint(0,256,(200,200,3))
:- 选取
b1
图像中从 (250,250) 到 (450,450) 的矩形区域(这是一个 200×200 像素的区域) - 使用
np.random.randint(0,256,(200,200,3))
生成一个 200×200×3 的随机数组,数组元素是 0-255 之间的整数(符合图像像素值范围)
- 选取
import cv2
from cv2 import imshowa = cv2.imread("zzd02.png")
b = cv2.imread("zzd03.png")c = a+50
cv2.imshow("a",a)
cv2.imshow("c",c)
cv2.waitKey(0)c = a[60:120,60:120]+b[60:120,60:120]
cv2.imshow("a+b",c)
cv2.waitKey(0)a1 = cv2.resize(a,(300,300))
b1 = cv2.resize(b,(300,300))
c = cv2.add(a1,b1)
cv2.imshow("a add b",c)
cv2.waitKey(0)# cv2.destroyAllWindows()c = cv2.addWeighted(a1,0.4,b1,0.6,10)
cv2.imshow("a addWeighted b",c)
cv2.waitKey(0)cv2.destroyAllWindows()
单图像像素 “简单加法”:整体提亮(但存在溢出风险)
c = a + 50
- 作用:给图像所有像素的 B、G、R 三个通道值都加 50,整体效果是图像变亮(类似调高亮度)。
- 注意(关键特性):
这是 NumPy 数组的 “模运算加法”,而非 OpenCV 的图像加法 —— 如果像素值加 50 后超过255
(比如原像素是 240),会自动对 256 取模(240+50=290 → 290-256=34),导致图像出现 “异常亮斑” 或色彩失真(比如白色像素加 50 后会变成低数值的异常颜色)。
两图像局部 “简单像素相加”:指定区域叠加
c = a[60:120, 60:120] + b[60:120, 60:120]
- 前提:图像 a 和 b 的尺寸必须一致(至少被截取的
60:120
区域存在),否则会报错。 - 作用:将两张图中 “60 行到 120 行、60 列到 120 列” 的局部区域(60×60 像素)的对应像素值相加,生成新的局部图像 c。
- 同样有溢出问题:若两图像对应像素值之和超过 255,仍会按 256 取模,导致局部色彩异常(比如两图该区域都是白色,相加后会变成黑色或低亮度颜色)。
两图像 “OpenCV 标准加法”:先 resize 再正常叠加
a1 = cv2.resize(a, (300, 300)) # 将a缩放为300×300像素
b1 = cv2.resize(b, (300, 300)) # 将b缩放为300×300像素(确保两图尺寸一致)
c = cv2.add(a1, b1)
- 关键步骤:cv2.resize ()
先将 a 和 b 都缩放为 300×300 像素 —— 因为cv2.add()
要求两输入图像的 尺寸、通道数完全一致,否则无法计算,这是与 “简单像素相加” 的第一个区别。 - 核心函数:cv2.add ()
这是 OpenCV 专门为图像设计的加法,解决了 “简单加法” 的溢出问题:
若两图像对应像素值之和超过 255,会直接将结果设为 255(即 “截断处理”,而非取模),符合人眼对图像亮度的认知(比如两白色像素相加后仍为白色,而非异常颜色)。 - 效果:两图整体叠加,亮度是对应像素的总和(但不超过 255),色彩是两图色彩的混合(比如 a 是红色、b 是绿色,叠加后该区域可能是黄色)。
两图像 “加权加法”:按比例混合(常用作图像融合)
c = cv2.addWeighted(a1, 0.4, b1, 0.6, 10)
- 核心函数:cv2.addWeighted ()
这是图像融合的常用函数,公式为:dst = src1×alpha + src2×beta + gamma
其中参数含义:a1
:第一张输入图像(src1)0.4
:a1 的权重(alpha)—— 表示 a1 在混合结果中占 40%b1
:第二张输入图像(src2)0.6
:b1 的权重(beta)—— 表示 b1 在混合结果中占 60%10
:亮度调节值(gamma)—— 给混合后的每个像素值加 10(可选,用于微调整体亮度)
- 作用:按比例混合两张图像,避免 “简单加法” 的生硬叠加,常用于 “水印添加”“图像合成”(比如将风景图和人物图按比例融合)。
- 优势:权重(alpha 和 beta)可灵活调整,gamma 可补偿亮度,混合效果自然,且同样会自动处理溢出(超过 255 则设为 255)。
import cv2
image = cv2.imread("zzd02.png",0)
ret ,binary = cv2.threshold(image,140,200,cv2.THRESH_BINARY)
ret1 ,binary1 = cv2.threshold(image,140,200,cv2.THRESH_BINARY_INV)
ret2 ,binary2 = cv2.threshold(image,140,200,cv2.THRESH_TRUNC)
ret3 ,binary3 = cv2.threshold(image,140,200,cv2.THRESH_TOZERO)
ret4 ,binary4 = cv2.threshold(image,140,200,cv2.THRESH_TOZERO_INV)cv2.imshow("binary",binary)
cv2.waitKey(0)
cv2.imshow("binary1",binary1)
cv2.waitKey(0)
cv2.imshow("binary2",binary2)
cv2.waitKey(0)
cv2.imshow("binary3",binary3)
cv2.waitKey(0)
cv2.imshow("binary4",binary4)
cv2.waitKey(0)
cv2.destroyAllWindows()
核心操作:不同类型的阈值化函数 cv2.threshold()
cv2.threshold()
是 OpenCV 的阈值化函数,语法为:
retval, dst = cv2.threshold(src, thresh, maxval, type)
参数含义:
src
:输入图像(必须是单通道灰度图)thresh
:阈值(这里设为 140)maxval
:最大值(当像素值超过 / 低于阈值时,被赋予的值,这里设为 200)type
:阈值化类型(决定像素值如何根据阈值处理)- 返回值:
retval
是使用的阈值(这里即 140),dst
是处理后的图像
cv2.THRESH_BINARY
(二进制阈值化)
- 规则:
像素值 > 阈值(140) → 设为maxval
(200)
像素值 ≤ 阈值(140) → 设为 0(黑色) - 效果:图像被分为两部分,亮区域(>140)变为 200 的灰度,暗区域(≤140)变为纯黑。
cv2.THRESH_BINARY_INV
(反二进制阈值化)
- 规则:与
THRESH_BINARY
相反
像素值 > 阈值(140) → 设为 0(黑色)
像素值 ≤ 阈值(140) → 设为maxval
(200) - 效果:亮区域(>140)变黑,暗区域(≤140)变为 200 的灰度,是
THRESH_BINARY
的反转
cv2.THRESH_TRUNC
(截断阈值化)
- 规则:
像素值 > 阈值(140) → 设为阈值(140)
像素值 ≤ 阈值(140) → 保持原始值不变 - 效果:亮于阈值的区域被 “截断” 为阈值亮度(140),暗区域保持原样,图像整体对比度降低。
cv2.THRESH_TOZERO
(零阈值化)
- 规则:
像素值 > 阈值(140) → 保持原始值不变
像素值 ≤ 阈值(140) → 设为 0(黑色) - 效果:暗于阈值的区域变黑,亮区域保持原样,突出图像中较亮的部分。
cv2.THRESH_TOZERO_INV
(反零阈值化)
- 规则:与
THRESH_TOZERO
相反
像素值 > 阈值(140) → 设为 0(黑色)
像素值 ≤ 阈值(140) → 保持原始值不变 - 效果:亮于阈值的区域变黑,暗区域保持原样,突出图像中较暗的部分。