OpenCV入门:第一章 图像的基本操作

在计算机眼里,图像不是我们看到的彩色画面,而是由一个个像素组成的网格

每个彩色像素会被拆成红 (R)、绿 (G)、蓝 (B) 三个独立的亮度分量,每个分量用 0-255 的数字表示亮度,最终整幅图就是3 组二维数字矩阵(三维张量),所有图像处理本质都是对这些数字做数学运算。如果这个图片的h是500,w是500,使用矩阵表示[500,500,3]。3表示3个通道。

一、图像的基本操作

1.数据读取-图像

cv2.IMREAD_COLOR 彩色图像

cv2.IMREAD_GRAYSCALE 灰色头像

处理图像时,第一步操作是将图像给计算机读取

输出这里,中括号有3个,所以是3个维度的图像,使用[h,w,c]来表示图像的shape。每一个都是像素点。注意:opencv读取的是BGR格式。

2.显示图像

上图,运行后会显示一张图像。waitKey(0)是指按任意键终止。如果是waitKey(1000),图片会显示一段时间就会消失。

为了方便,我们可以将显示一张图片封装成一个函数,img.shape就是图片的形状[h,w,c]。

3.将彩色图转换成灰度图

cv2.IMREAD_GRAYSCALE 灰色头像

上面的操作,是将一张彩色图片显示成灰度图。后面会将彩色图转换成灰度图,对图像进行预处理。为了减少计算量。

4.保存图像

完整代码:

python 复制代码
import cv2 #opencv读取的格式是BGR
import matplotlib.pyplot as plt
import numpy as np

img = cv2.imread('D:\\openCV files\\data\\1\\cat.jpg')
print(img)

#图像的显示,也可以创建多个窗口
cv2.imshow('image',img)  #窗口名字叫image
#等待时间,毫秒级,0表示任意键终止
cv2.waitKey(0) #随便一个键,窗口关闭
#cv2.waitKey(1000)  #显示1000ms,再关闭
cv2.destroyAllWindows() #触发关闭,所有窗口关闭

#写成一个函数
def cv2_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

print(img.shape)

img = cv2.imread('D:\\openCV files\\data\\1\\cat.jpg',cv2.IMREAD_GRAYSCALE)   #读取灰度图
print(img)
print(img.shape)

cv2_show('image_gray',img)  #显示灰色图像

#保存
cv2.imwrite('D:\\openCV files\\data\\1\\mycat.png',img)

print(type(img))

print(img.size)#像素点的个数

print(img.dtype)

二、视频的基本操作

视频是由一帧一帧的图像组成的。

· cv2.VideoCapture可以捕获摄像头,用数字来控制不同的设备,例如0,1。

·如果是视频文件直接指定好路径即可。

1.读取视频的每一帧

这段代码基于 Python 的cv2(OpenCV 库),实现了读取本地 MP4 视频文件、逐帧播放、转为灰度图展示,并支持按 ESC 键退出的基础视频播放功能。

运行结果:

2.截取部分图像数据

就是获取图片中你感兴趣的区域(ROI区域)

  • 功能:对图像数组进行NumPy 切片,实现图像裁剪。
  • 切片规则:img[行范围, 列范围],对应[y轴范围, x轴范围]
    • 0:200(行):截取图像纵向(高度)0~199 行(左闭右开,不包含 200);
    • 0:200(列):截取图像横向(宽度)0~199 列
    • 最终得到一张200×200 像素 的裁剪后图像,赋值给变量cat

运行结果:

3.颜色通道截取

下面的代码就是颜色截取。在三个通道中,截取其中一个颜色通道。

上面就是,将bgr三个颜色通道合成。还原成原来的三通道颜色。

3.1 只显示红色图像

通过将图像数组的 G、B 通道置 0 仅保留 R 通道并展示最终效果。

运行结果:

3.2 只显示绿色图像

3.3 只显示蓝色图像

三、边界填充

python 复制代码
#边界填充
top_size,bottom_size,left_size,right_size = (50,50,50,50)  #上下左右填充的大小

replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_CONSTANT, value=0)  #以0的常数值来填充

plt.subplot(231), plt.imshow(img,'gray'),plt.title('ORIGINAL')
plt.subplot(232), plt.imshow(replicate,'gray'),plt.title('REPLICATE')
plt.subplot(233), plt.imshow(reflect,'gray'),plt.title('REFLECT')
plt.subplot(234), plt.imshow(reflect101,'gray'),plt.title('REFLECT_101')
plt.subplot(235), plt.imshow(wrap,'gray'),plt.title('WRAP')
plt.subplot(236), plt.imshow(constant,'gray'),plt.title('CONSTANT')

plt.show()

cv2.copyMakeBorder() 核心函数这是 OpenCV 的图像扩边函数,参数格式为:

cv2.copyMakeBorder(src, top, bottom, left, right, borderType, value)

  • src:原图像img
  • top/bottom/left/right:上下左右扩边尺寸
  • borderType:填充类型
  • value:仅BORDER_CONSTANT时生效,指定填充值

|--------------------------------|-------------------------------------------------|
| 填充类型 | 效果说明 |
| BORDER_REPLICATE(复制边缘) | 直接复制原图像最边缘的像素值填充新边界 |
| BORDER_REFLECT(镜像反射) | 以边缘为轴做镜像翻转填充(如abcba,边缘像素不重复) |
| BORDER_REFLECT_101(镜像反射 101) | 以边缘像素为轴翻转(如abcba,边缘像素作为轴,不重复),是 OpenCV 默认填充方式 |
| BORDER_WRAP(环绕填充) | 把图像另一边的像素循环拼接过来,类似 "无缝贴图" 效果 |
| BORDER_CONSTANT(常量填充) | 用指定的固定值填充,这里value=0即填充纯黑 |

运行结果:

BORDER_REPLICATE 复制法,也就是复制最边缘像素

BORDER_REFLECT 反射法,对感兴趣的图像中的像素在两边进行复制,例如fedcba|abcdefgh|hgfedcb

BORDER_REFLECT_101 反射法,也就是以最边缘像素为轴,对称 gfedcb|abcdefgh|gfedcba

BORDER_WRAP 外包装法 cdefgh|abcdefgh|abcdefg

BORDER_CONSTANT 常量法,常数值填充

下面是图像处理的基本操作所有代码:

python 复制代码
import cv2 #opencv读取的格式是BGR
import matplotlib.pyplot as plt
import numpy as np

img = cv2.imread('D:\\openCV files\\data\\1\\cat.jpg')
print(img)

#图像的显示,也可以创建多个窗口
cv2.imshow('image',img)  #窗口名字叫image
#等待时间,毫秒级,0表示任意键终止
cv2.waitKey(0) #随便一个键,窗口关闭
#cv2.waitKey(1000)  #显示1000ms,再关闭
cv2.destroyAllWindows() #触发关闭,所有窗口关闭

#写成一个函数
def cv2_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

print(img.shape)

img = cv2.imread('D:\\openCV files\\data\\1\\cat.jpg',cv2.IMREAD_GRAYSCALE)   #读取灰度图
print(img)
print(img.shape)

cv2_show('image_gray',img)  #显示灰色图像

#保存
cv2.imwrite('D:\\openCV files\\data\\1\\mycat.png',img)

print(type(img))

print(img.size)#像素点的个数

print(img.dtype)

#截取部分图像数据
img = cv2.imread('D:\\openCV files\\data\\1\\cat.jpg')
cat = img[0:200,0:200]
cv2_show('cat',cat)

#颜色通道提取
b,g,r = cv2.split(img)
print(b)
print(b.shape)

#再把三个通道组合在一起
img = cv2.merge((b,g,r))
print(img.shape)

# 只保留R
cur_img = img.copy()
cur_img[:,:,0] = 0
cur_img[:,:,1] = 0
cv2_show('R',cur_img)

# 只保留G
cur_img = img.copy()
cur_img[:,:,0] = 0
cur_img[:,:,2] = 0
cv2_show('G',cur_img)

# 只保留B
cur_img = img.copy()
cur_img[:,:,1] = 0
cur_img[:,:,2] = 0
cv2_show('B',cur_img)

#边界填充
top_size,bottom_size,left_size,right_size = (50,50,50,50)  #上下左右填充的大小

replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_CONSTANT, value=0)  #以0的常数值来填充

plt.subplot(231), plt.imshow(img,'gray'),plt.title('ORIGINAL')
plt.subplot(232), plt.imshow(replicate,'gray'),plt.title('REPLICATE')
plt.subplot(233), plt.imshow(reflect,'gray'),plt.title('REFLECT')
plt.subplot(234), plt.imshow(reflect101,'gray'),plt.title('REFLECT_101')
plt.subplot(235), plt.imshow(wrap,'gray'),plt.title('WRAP')
plt.subplot(236), plt.imshow(constant,'gray'),plt.title('CONSTANT')

plt.show()

四、数值计算

1.像素加一个常数

先给加载两张图片,分别是猫和狗。给猫的图像加10,就是将猫的所有像素点加10。

2.两张图片像素相加

如果要将两张图片相加,必须保证两张图片的大小要保持一致。

(1)、两张图片直接使用加号

像素的范围是0~255,当两张图片相加时,当像素超过255时,相当于%256。

(2)、两张图片相加(使用add函数)

当其像素值超过255时,就取最大值255。

五、图像融合

图像融合就是将两张图片融合在一起。融合的条件就是形状要相等。

上述代码报错的原因是两张图片的大小不一样导致报错。

(1)、将图片的形状设置成同一大小

需要使用resize函数。

(2)、两张图片相加(有权重)

由于狗的权重是0.6比猫的权重大。所以图像显示狗多点。

(3)、resize函数

cv2.resize() 是 OpenCV 中最常用的图像缩放函数,我们逐个参数解释:

相关推荐
Chef_Chen2 小时前
Agent学习--LLM--推理熵
人工智能·学习·机器学习
小鹿软件办公2 小时前
OpenAI 面向高频用户推出全新 100 美元档 ChatGPT Pro 套餐
人工智能·chatgpt
ECT-OS-JiuHuaShan2 小时前
科学的本来意义,是基于规范的共识逻辑,而非共识方法
人工智能·科技·学习·算法·生活
CoderJia程序员甲2 小时前
GitHub 热榜项目 - 日榜(2026-04-09)
人工智能·ai·大模型·github·ai教程
chaofan9802 小时前
从文字响应到动态沙盒:深度解析 Gemini 交互模拟 API 的技术实现与集成
人工智能·交互·api
hay_lee2 小时前
匿名屠榜,阿里认领:HappyHorse 1.0 如何重写AI视频生成规则?
人工智能·音视频
无忧智库2 小时前
某新区“十五五”智慧城市数字底座与数字孪生城市建设全栈技术深度解析(WORD)
人工智能·物联网·智慧城市
kishu_iOS&AI2 小时前
机器学习 —— 线性回归(实例)
人工智能·python·机器学习·线性回归
天天进步20152 小时前
[架构篇] 解构项目蓝图:Toonflow 的模块化设计与 AI 管道流转
人工智能·架构