Windows下Anaconda安装OpenCV以及OpenCV入门

目录

[Windows 下使用 Anaconda 安装 OpenCV](#Windows 下使用 Anaconda 安装 OpenCV)

一、为什么一定要使用虚拟环境?

[二、创建 OpenCV 专用虚拟环境](#二、创建 OpenCV 专用虚拟环境)

[三、安装 OpenCV(推荐 opencv-contrib-python)](#三、安装 OpenCV(推荐 opencv-contrib-python))

[四、安装必要的依赖库(numpy + matplotlib)](#四、安装必要的依赖库(numpy + matplotlib))

五、如何在pycharm使用这个虚拟环境?

[六、解决 Terminal 进入 base 环境的问题(可选)](#六、解决 Terminal 进入 base 环境的问题(可选))

[在 Terminal 手动激活:](#在 Terminal 手动激活:)

OpenCV入门------读取图像,显示图像

一、计算机眼中的"图像"是什么?

[1️⃣ 像素(Pixel)是什么?](#1️⃣ 像素(Pixel)是什么?)

[2️⃣ 灰度图 vs 彩色图(本质区别)](#2️⃣ 灰度图 vs 彩色图(本质区别))

灰度图

彩色图

[二、使用 OpenCV 读取图像](#二、使用 OpenCV 读取图像)

[1️⃣ 基本代码](#1️⃣ 基本代码)

[此时 img 到底是什么?](#此时 img 到底是什么?)

第一层:一个像素

第二层:一整行像素

第三层:所有行组成整张图

[2️⃣ 如何读取灰度图片?](#2️⃣ 如何读取灰度图片?)

图像的基本属性

[1️⃣ shape(结构 / 尺寸)](#1️⃣ shape(结构 / 尺寸))

[2️⃣ ndim(维度数)](#2️⃣ ndim(维度数))

[3️⃣ dtype(数据类型)](#3️⃣ dtype(数据类型))

[4️⃣ size(像素总数)](#4️⃣ size(像素总数))

图像的基本操作

读取图像

显示图像

访问像素

修改像素

图像裁剪(切片)

复制图像(避免误操作)

[彩色 → 灰度](#彩色 → 灰度)

颜色提取通道

合并

改变图像大小

保存图像

边界填充

[什么是边界填充(Border Padding)](#什么是边界填充(Border Padding))

为什么要进行边界填充

[OpenCV 中的边界填充函数](#OpenCV 中的边界填充函数)

常见边界填充方式(重点)

[1️⃣ BORDER_REPLICATE(复制法)](#1️⃣ BORDER_REPLICATE(复制法))

[2️⃣ BORDER_REFLECT(反射法)](#2️⃣ BORDER_REFLECT(反射法))

[3️⃣ BORDER_REFLECT_101(反射 101)](#3️⃣ BORDER_REFLECT_101(反射 101))

[4️⃣ BORDER_WRAP(环绕法)](#4️⃣ BORDER_WRAP(环绕法))

[5️⃣ BORDER_CONSTANT(常量填充)](#5️⃣ BORDER_CONSTANT(常量填充))

数值计算

两种加法机制

[NumPy 数值运算(取模运算)](#NumPy 数值运算(取模运算))

[OpenCV 数值运算(饱和运算)](#OpenCV 数值运算(饱和运算))

常见数值运算类型

三、使用OpenCV读取视频

[视频在 OpenCV 里是什么?](#视频在 OpenCV 里是什么?)

[读取视频文件并转灰度显示(ESC 退出)](#读取视频文件并转灰度显示(ESC 退出))

核心对象:cv2.VideoCapture

[1️⃣ 作用](#1️⃣ 作用)

[2️⃣ 判断视频是否成功打开](#2️⃣ 判断视频是否成功打开)

循环读取视频帧(最核心部分)

判断是否读到视频末尾


Windows 下使用 Anaconda 安装 OpenCV

OpenCV 是计算机视觉中最常用的图像处理库,而在 Windows 下正确安装 OpenCV 对初学者来说往往容易踩坑:版本不兼容、环境混乱、PyCharm 找不到库等。本教程将从零开始,带你用 Anaconda + 虚拟环境 安装 OpenCV,并最终在 PyCharm 中成功运行代码。

教程适用于:

  • Windows 系统

  • 使用 Anaconda 管理 Python

  • PyCharm 或任意 IDE

  • 初学者 & 想避免环境混乱的人

一、为什么一定要使用虚拟环境?

很多同学直接在 base 环境装包,导致:

  • Python 版本冲突

  • 多个项目共享同一环境,容易"互相污染"

  • 升级 / 回退库版本困难

  • OpenCV、matplotlib、numpy 冲突概率大

因此推荐使用:

一个项目一个环境

环境独立、干净、可随时删除重建

二、创建 OpenCV 专用虚拟环境

打开 Anaconda Prompt,创建一个名为 opencv4 的环境:

bash 复制代码
conda create -n opencv4 python=3.10

激活环境:

bash 复制代码
conda activate opencv4

看到前缀变成:(opencv4) 说明虚拟环境已激活成功。

三、安装 OpenCV(推荐 opencv-contrib-python)

OpenCV 有两种常见安装包:

包名 内容
opencv-python 基础功能(图像读写、滤波、边缘检测)
opencv-contrib-python(推荐) 包含基础功能 + SIFT/SURF/ORB/Tracking 等扩展算法

推荐安装完整版本:

bash 复制代码
pip install opencv-contrib-python

四、安装必要的依赖库(numpy + matplotlib)

OpenCV 常用 numpy 和 matplotlib:

bash 复制代码
pip install numpy matplotlib

五、如何在pycharm使用这个虚拟环境?

六、解决 Terminal 进入 base 环境的问题(可选)

PyCharm 自带 Terminal 默认不会自动进入当前解释器对应的 conda 环境,导致 pip 装包装到 base。

解决方法:

在 Terminal 手动激活:

bash 复制代码
conda activate opencv4

OpenCV入门------读取图像,显示图像

一、计算机眼中的"图像"是什么?

在我们人类眼中,图像是有颜色、有形状的画面;

但在计算机眼中,图像本质上只有一件事

图像 = 数字组成的矩阵(数组)

计算机并不"看"图像,它只处理 数字

1️⃣ 像素(Pixel)是什么?

图像是由很多个像素点组成的。

  • 一个像素 = 图像中最小的点

  • 每个像素用数字表示颜色或亮度


2️⃣ 灰度图 vs 彩色图(本质区别)

灰度图
  • 每个像素只有 一个数字

  • 范围:0 ~ 255

    • 0:黑

    • 255:白

bash 复制代码
123 124 125
120 121 122
118 119 120
彩色图
  • 每个像素由 三个数字组成

  • 分别表示三种颜色强度

在 OpenCV 中顺序是:

bash 复制代码
[B, G, R]  → 蓝、绿、红

例如:

bash 复制代码
[104, 78, 62]

二、使用 OpenCV 读取图像

1️⃣ 基本代码

python 复制代码
# 读取图片
img = cv2.imread('head.jpg')
# 打印图片
print( img)
# 显示图片
cv2.imshow('image',img)
cv2.waitKey(0) # 0表示等待时间,0表示一直等待
cv2.destroyAllWindows()
此时 img 到底是什么?

img的结构是:

bash 复制代码
[[[104  78  62]
  [104  78  62]
  [104  78  62]
  ...
 ]]
第一层:一个像素
bash 复制代码
[104  78  62]

表示一个像素

含义:

  • 104:蓝色强度

  • 78 :绿色强度

  • 62 :红色强度

如果是灰度图片,那么一个数字表示一个像素

第二层:一整行像素
bash 复制代码
[[104  78  62]
  [104  78  62]
  [104  78  62]
  ...
  [143 147 148]
  [143 147 148]
  [143 147 148]]

 [[106  80  64]
  [106  80  64]
  [106  80  64]
  ...
  [150 154 155]
  [150 154 155]
  [150 154 155]]

含义:

  • 每一行是一个像素

  • 这一整块表示:图片中的一行

第三层:所有行组成整张图
bash 复制代码
[
  第 0 行像素,
  第 1 行像素,
  第 2 行像素,
  ...
]

含义:

👉 多行像素堆叠在一起 = 一张完整的图片

2️⃣ 如何读取灰度图片?

python 复制代码
img2 = cv2.imread('head.jpg',cv2.IMREAD_GRAYSCALE)
print( img2)
cv2.imshow('image',img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

其中 76 表示一个像素

76 76 76 ... 147 147 147\] 表示一行 \[\[ 76 76 76 ... 147 147 147

...

217 217 217 ... 90 89 88\]\] 表示整张图片

图像的基本属性

1️⃣ shape(结构 / 尺寸)
python 复制代码
img.shape

含义

  • 灰度图:(H, W)

  • 彩色图:(H, W, 3)

  • 透明图:(H, W, 4)

👉 描述:有多少行、多少列、多少通道

OpenCV 使用 img.shape 来获取图像在数组中的结构信息。

对于彩色图像,图像以三维数组形式存储,
img.shape 返回 (高度, 宽度, 通道数),其中通道数通常为 3(B、G、R)。

对于灰度图像,图像以二维数组形式存储,

每个像素本身就是一个数值,因此不再单独保留通道这一维,
img.shape 只返回 (高度, 宽度)

2️⃣ ndim(维度数)
python 复制代码
img.ndim
  • 灰度图 → 2

  • 彩色图 → 3

👉 数组有几层中括号

3️⃣ dtype(数据类型)
python 复制代码
img.dtype

常见结果: uint8

含义

  • 每个像素是 8 位无符号整数

  • 范围:0 ~ 255

⚠️ 这是为什么像素不能随便加到 300 的原因

4️⃣ size(像素总数)
python 复制代码
img.size

表示:H × W × 通道数

👉 数组中一共有多少个数字

图像的基本操作

读取图像

python 复制代码
img = cv2.imread('head.jpg')
gray = cv2.imread('head.jpg', cv2.IMREAD_GRAYSCALE) #灰色图像

显示图像

python 复制代码
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

访问像素

python 复制代码
pixel = img[100, 200]        # [B G R]
b = img[100, 200, 0]
g = img[100, 200, 1]
r = img[100, 200, 2]

灰度图:

python 复制代码
value = gray[100, 200]

修改像素

python 复制代码
img[100, 200] = [0, 0, 255]  # 改成红色

图像裁剪(切片)

python 复制代码
roi = img[100:300, 200:400]

含义:

  • 行:100 ~ 299

  • 列:200 ~ 399

👉 裁剪本质是 数组切片

复制图像(避免误操作)

python 复制代码
img2 = img.copy()

⚠️ 直接 img2 = img 只是引用

彩色 → 灰度

python 复制代码
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

颜色提取通道

python 复制代码
# 颜色通道提取
b,g,r = cv2.split(img)
print( "b",b)
  • 每个通道都是一张灰度图

合并

python 复制代码
img = cv2.merge([b, g, r])

改变图像大小

指定目标尺寸

python 复制代码
resized = cv2.resize(img, (300, 300))

用缩放因子(写 fx / fy)

python 复制代码
res = cv2.resize(img, (0, 0), fx=3, fy=1)

fx 控制"横向缩放倍数",fy 控制"纵向缩放倍数"

  • fx = 3宽度变为原来的 3 倍

  • fy = 1高度保持不变

所以你看到的结果是:

图片被横向拉长了,但上下没有变

保存图像

python 复制代码
cv2.imwrite('out.jpg', img)

边界填充

什么是边界填充(Border Padding)

一句话定义:

边界填充,就是在图像的四周"人为加一圈像素"。

从数组角度看:

  • 原图:(H, W)(H, W, 3)

  • 填充后:(H + 上 + 下, W + 左 + 右[, 3])

也就是说:

👉 shape 会变大

为什么要进行边界填充

在图像处理中,很多操作(如卷积、滤波、边缘检测)需要访问像素周围的邻域。

  • 图像中间像素:邻域完整

  • 图像边缘像素:邻域不完整

👉 边界填充用来解决"边缘像素邻域不足"的问题,避免信息丢失或计算异常。

OpenCV 中的边界填充函数
python 复制代码
cv2.copyMakeBorder()

基本形式

python 复制代码
dst = cv2.copyMakeBorder(
    src,
    top, bottom, left, right,
    borderType,
    value=...
)
常见边界填充方式(重点)

1️⃣ BORDER_REPLICATE(复制法)

原理:

复制最外层像素向外扩展。

特点:

  • 实现简单

  • 边缘连续

  • 使用非常广泛


2️⃣ BORDER_REFLECT(反射法)

原理:

以边界为轴,对图像内容进行镜像反射(包含边界像素)。

特点:

  • 边缘过渡自然

  • 常用于图像滤波


3️⃣ BORDER_REFLECT_101(反射 101)

原理:

反射填充,但不重复边界像素本身。

特点:

  • REFLECT 更自然

  • OpenCV 滤波的默认方式


4️⃣ BORDER_WRAP(环绕法)

原理:

从图像对侧"接过来"进行填充。

特点:

  • 类似周期拼接

  • 不适合自然图像

  • 多用于纹理或周期信号


5️⃣ BORDER_CONSTANT(常量填充)

原理:

使用固定值填充边界。

特点:

  • 边界明显

  • 常用于调试或显示

  • 可指定填充值(黑边、白边、彩边)

数值计算
两种加法机制
NumPy 数值运算(取模运算)
bash 复制代码
img3 = img1 + img2

运算规则

结果对 256 取模

数学形式:

bash 复制代码
result = (a + b) % 256
OpenCV 数值运算(饱和运算)
bash 复制代码
img3 = cv2.add(img1, img2)

运算规则

超过 255 的值直接截断为 255

数学形式:

bash 复制代码
result = min(a + b, 255)
常见数值运算类型

1️⃣ 加法(亮度增强 / 图像叠加)

cv2.add(img, value)

cv2.add(img1, img2)

cv2.add(img1, img2) 要求两个输入图像:

形状(shape)必须完全一致。


2️⃣ 减法(亮度降低 / 差分)

cv2.subtract(img1, img2)

  • 小于 0 的值 → 0

3️⃣ 乘法(对比度调节)

cv2.multiply(img, factor)

  • 超过 255 → 255

4️⃣ 除法(归一化 / 比例调整)

cv2.divide(img, divisor)

图像融合

python 复制代码
cv2.addWeighted(img1, α, img2, β, γ)

数学形式:

bash 复制代码
result = img1 * α + img2 * β + γ

例如:

python 复制代码
cv2.addWeighted(img1, 0.7, img2, 0.3, 0)

三、使用OpenCV读取视频

视频在 OpenCV 里是什么?

在 OpenCV 中:

  • 视频 = 一帧一帧的图片

  • 视频处理的本质:
    循环读取 → 处理当前帧 → 显示 → 读取下一帧

读取视频文件并转灰度显示(ESC 退出)

python 复制代码
import cv2

# 1. 打开视频文件(也可以写 0 打开摄像头)
vc = cv2.VideoCapture('test.mp4')

# 2. 检查是否打开成功
if vc.isOpened():
    open, frame = vc.read()
else:
    open = False

# 3. 循环读取视频帧
while open:
    ret, frame = vc.read()

    # 视频读完 / 读取失败
    if frame is None:
        break

    if ret is True:
        # 4. 图像处理:BGR 转 灰度
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # 5. 显示当前帧
        cv2.imshow('result', gray)

        # 6. 控制播放速度 & 按 ESC 退出
        if cv2.waitKey(100) & 0xFF == 27:
            break

# 7. 释放资源
vc.release()
cv2.destroyAllWindows()

核心对象:cv2.VideoCapture

python 复制代码
vc = cv2.VideoCapture('test.mp4')
1️⃣ 作用

VideoCapture 用来打开视频源,可以是:

参数 含义
0 默认摄像头
1 第二个摄像头
'test.mp4' 视频文件路径
2️⃣ 判断视频是否成功打开
python 复制代码
if vc.isOpened():
    open, frame = vc.read()
else:
    open = False

关键点解释

  • isOpened()

    判断视频是否成功加载

  • vc.read()

    返回两个值:

python 复制代码
ret    → 是否成功读取(True / False)
frame  → 当前帧图像(numpy 数组)

循环读取视频帧(最核心部分)

python 复制代码
while open:
    ret, frame = vc.read()

为什么要用 while

  • 视频是由很多帧组成的

  • 一次 read() 只能读一帧

  • 所以必须 循环读取

判断是否读到视频末尾

python 复制代码
if frame is None:
    break

为什么要判断?

  • 视频结束后:

    • ret = False

    • frame = None

  • 不判断会 死循环或报错

相关推荐
码农进厂打螺丝2 小时前
Stable Diffusion 3.5 FP8:量化优化与部署实践
人工智能·计算机视觉·stable diffusion
Niuguangshuo2 小时前
DeepDream:窥视神经网络内部世界的梦幻之窗
人工智能·深度学习·神经网络
美狐美颜SDK开放平台2 小时前
实时直播场景下,美颜sdk美型功能开发的技术难点与解决思路
人工智能·美颜sdk·直播美颜sdk·美颜api·美狐美颜sdk
不爱学英文的码字机器2 小时前
基于昇腾 NPU 部署 Llama-3-8B 实战教程:从环境搭建到构建昇腾问答智能体
人工智能·pytorch·llama
小程故事多_802 小时前
LangGraph破局指南,打造具备长期记忆与人工可控的高阶AI智能体
人工智能
week_泽2 小时前
1、OpenCV 特征检测入门笔记
人工智能·笔记·opencv
ergevv2 小时前
RK3588 上 OpenCV ROI 拷贝性能差异的根本原因与优化方案
opencv·计算机视觉·图像·image·clone·拷贝
车队老哥记录生活2 小时前
强化学习 RL 基础 3:随机近似方法 | 梯度下降
人工智能·算法·机器学习·强化学习