Python OpenCV学习第一天:环境搭建+NumPy核心基础

Python OpenCV学习第一天:环境搭建+NumPy核心基础

寒烟似雪
1天前发布

Python OpenCV学习第一天:环境搭到一半差点放弃

今天终于下定决心开始学OpenCV了!按照之前定的计划,第一天先搞环境和NumPy基础。本来以为半小时就能搞定环境,结果踩了两个大坑,折腾了快一个小时才弄好,真的服了。

今日目标完成情况

  • OpenCV环境搭建成功
  • NumPy核心操作过了一遍
  • 搞懂了为什么OpenCV离不开NumPy
  • 掌握OpenCV、NumPy基础语法,能看懂基础代码

一、环境搭建:别再只装opencv-python了!

真的要吐槽一下网上那些老教程,全都是让你pip install opencv-python,我装完之后才发现后面很多函数都用不了,查了半天才知道原来还有个完整版。而且我之前的python环境乱成狗屎,之前安装中断导致后续安装不上,折腾了好久才理顺。

正确安装方法

先把之前装的乱七八糟的版本全部卸载干净,不然会冲突(卸载时如果提示“跳过opencv-contrib-python,因为未安装”,属于正常情况,不用管,确保已安装的版本被卸载即可):

pip uninstall opencv-python opencv-contrib-python -y

mo5qcl22.png

然后直接装完整版,包含所有contrib模块,后面学特征检测、DNN什么的都不用再重新装了:

pip install opencv-contrib-python -i https://pypi.tuna.tsinghua.edu.cn/simple

mo5qfmkq.png

一定要加清华源!不加的话国外源慢到死,还经常超时(但是我加了也慢,又被校园网美式拦截了)。另外安装时还遇到了清华源网页访问失败的情况(疑似跑路),试了几次后才顺利下载,估计是临时网络波动,遇到这种情况多重试几次就好。

还有个小问题:安装时会提示“默认采用用户安装模式”,因为正常的site-packages目录没有写入权限,无需担心,不影响OpenCV和NumPy的正常使用,最终还是成功安装了opencv-contrib-python 4.13.0.92版本,NumPy也保持了适配的版本。

测试安装

新建个py文件,输入这几行,测试环境是否安装成功(代码含义后面语法板块会详细说):

import cv2
import numpy as np

print(f"OpenCV版本:{cv2.__version__}")
print(f"NumPy版本:{np.__version__}")

mo5r7t6a.png

我这里实际测试输出的是OpenCV 4.13.0和NumPy 2.2.6,之前写的版本是笔误,实际安装后一切正常。如果报错找不到模块,大概率是你的IDE解释器选错了,去设置里检查一下(比如PyCharm,打开设置→Project→Python Interpreter,选择自己的Python环境即可)。

二、基础语法板块(小白必看,逐行解析)

刚开始看代码肯定一脸懵,这里把今天用到的、后续常用的基础语法,逐行拆解,看不懂的地方对照着看,慢慢就能上手。

1. 模块导入语法(最基础,必须会)

Python中使用第三方库(比如OpenCV、NumPy),必须先“导入”,才能使用里面的功能,常用导入方式有2种:

# 方式1:导入整个模块,使用时需要加“模块名.功能”(推荐,不容易混淆)
import cv2  # 导入OpenCV库,简写为cv2(行业通用写法,固定这么写)
import numpy as np  # 导入NumPy库,简写为np(行业通用写法,固定这么写)

# 方式2:从模块中导入指定功能,使用时不用加模块名(不推荐,容易记混)
# from cv2 import *  # 导入OpenCV所有功能,不推荐,容易和其他库冲突
# from numpy import array  # 只导入NumPy的array功能(创建数组)

补充说明:cv2、np都是行业约定俗成的简写,所有人都这么写,记下来就好,不用纠结为什么叫这个。

2. 打印输出语法(调试必备)

用来打印变量、版本信息、结果等,方便我们查看是否正确,今天用到的是f-string格式化输出(最简洁好用):

# 基本格式:print(f"提示文字:{变量/功能}")
print(f"OpenCV版本:{cv2.__version__}")  # 打印OpenCV版本
print(f"NumPy版本:{np.__version__}")  # 打印NumPy版本

# 拆解说明:
# 1. print():打印函数,括号里放要打印的内容,必须加括号
# 2. f"":格式化字符串,前面加f,里面可以用 嵌入变量或功能
# 3. cv2.__version__:获取OpenCV的版本号,__version__是固定写法(两个下划线)
# 4. 示例:如果想打印数组,也可以用print(f"数组内容:{arr}")

3. NumPy核心语法(OpenCV必备,逐行解析)

结合今天学的NumPy操作,把每个语法、每个参数都拆解开,看不懂就对照着看,多敲几遍就记住了。

(1)创建数组语法

import numpy as np  # 先导入NumPy,必写

# 1. 创建普通数组:np.array(数据, dtype=数据类型)
# 拆解:np.array() 是创建数组的核心函数,括号里放要创建的数据
gray = np.array([[1,2,3], [4,5,6], [7,8,9]], dtype=np.uint8)
# 逐行解析:
# gray:变量名,自己起(建议见名知意,gray=灰度图)
# np.array():创建数组的函数
# [[1,2,3], [4,5,6], [7,8,9]]:数组数据,二维数组(3行3列),对应灰度图的像素
# dtype=np.uint8:指定数据类型为uint8(重点!图像专用,范围0-255)

# 2. 创建全0数组:np.zeros(形状, dtype=数据类型)
# 拆解:np.zeros() 生成所有元素都是0的数组,适合创建全黑图像
color = np.zeros((100, 100, 3), dtype=np.uint8)
# 逐行解析:
# (100, 100, 3):数组形状(高, 宽, 通道数),100行100列,3个通道(对应彩色图)
# 其他参数和上面一致

# 3. 创建全1数组:np.ones(形状, dtype=数据类型)
white = np.ones((200, 200), dtype=np.uint8) * 255
# 逐行解析:
# np.ones() 生成所有元素都是1的数组,乘以255后,所有元素变成255(对应全白图像)
# (200, 200):二维数组(200行200列),对应灰度图

# 4. 创建随机数组:np.random.randint(最小值, 最大值, 形状, dtype=数据类型)
noise = np.random.randint(0, 256, (200, 200), dtype=np.uint8)
# 逐行解析:
# np.random.randint():生成随机整数的函数
# 0, 256:随机数范围是0~255(因为最大值256是开区间,不包含256)
# (200, 200):数组形状,二维数组,对应灰度图的随机噪声

(2)数组索引和切片语法(修改图像必备)

核心:数组索引是「行, 列」(y, x),和我们平时说的「x, y」相反,一定要记牢!

import numpy as np

# 先创建一个5x5的数组(方便演示)
arr = np.array([[1,2,3,4,5],
                [6,7,8,9,10],
                [11,12,13,14,15],
                [16,17,18,19,20],
                [21,22,23,24,25]])

# 1. 获取单个元素:数组名[行索引, 列索引](索引从0开始,不是从1开始!)
print(arr[2, 3])  # 输出14
# 解析:第3行(索引2)、第4列(索引3)的元素,就是14

# 2. 获取切片(一块区域):数组名[行范围, 列范围]
# 范围写法:start:end(包含start,不包含end),省略start表示从0开始,省略end表示到最后
print(arr[0:3, 0:3])  # 获取左上角3x3区域(行0-2,列0-2)
# 解析:行0到3(不包含3,即0、1、2行),列0到3(不包含3,即0、1、2列)

# 3. 修改切片区域:数组名[行范围, 列范围] = 目标值
arr[0:3, 0:3] = 0  # 把左上角3x3区域全部改成0
print(arr)  # 打印修改后的数组

(3)数组形状查看/变换语法

import numpy as np

arr = np.array([[1,2,3,4,5],
                [6,7,8,9,10],
                [11,12,13,14,15],
                [16,17,18,19,20],
                [21,22,23,24,25]])

# 1. 查看数组形状:数组名.shape(固定写法)
print(arr.shape)  # 输出(5, 5),表示5行5列的二维数组
# 补充:如果是彩色图数组,会输出(高, 宽, 3),比如(100, 100, 3)

# 2. 变换数组形状:数组名.reshape(新形状)
# 注意:变换后的元素总数,必须和原来的一致(5x5=25,所以可以改成25个元素的一维数组)
arr_flat = arr.reshape(25)  # 改成一维数组(25个元素)
print(arr_flat.shape)  # 输出(25,),逗号表示一维数组

4. 常见报错/警告语法解析(避坑必备)

今天遇到的警告,拆解一下,以后遇到就知道怎么回事了:

  • 警告1:WARNING: Skipping opencv-contrib-python as it is not installed.
    解析:提示“跳过opencv-contrib-python,因为未安装”,正常情况,说明之前没装过这个包,不用处理。
  • 警告2:Defaulting to user installation because normal site-packages is not writeable
    解析:提示“默认采用用户安装模式,因为正常的site-packages目录没有写入权限”,不用管,不影响使用,是系统权限问题,不是我们操作错了。
  • 报错:找不到cv2/np模块
    解析:要么是没安装成功,要么是IDE解释器选错了,去IDE设置里切换到自己的Python环境即可。

三、NumPy:原来这才是OpenCV的本体

之前就听人说OpenCV学到最后其实是在学NumPy(豆包说的),今天算是有点体会了。原来OpenCV里的图像根本不是什么特殊的东西,就是个三维的NumPy数组而已!所有对图像的操作(比如修改颜色、裁剪、缩放),本质上都是对NumPy数组的操作。

数组和列表的区别(小白必懂)

很多人刚开始会把NumPy数组和Python列表搞混,这里用通俗的话讲清楚,不用记复杂概念:

  • 列表:什么类型都能放(比如数字、字符串、列表),比如[1, "a", [2,3]],但运算很慢,处理图像(大数据)会卡死。
  • 数组:只能放同一种类型(比如全是数字),运算速度比列表快几百倍,专门用来处理图像这种大数据。
  • 数组支持向量化运算:不用写一堆for循环,比如想把数组里所有元素加1,直接arr+1就行,列表则需要写for循环逐个修改。

今天必须记住的几个操作(结合语法,再巩固一遍)

这些都是后面天天要用的,结合上面的语法解析,边敲代码边理解,记起来更快。

1. 创建数组(图像基础)

import numpy as np

# 灰度图就是二维数组(高×宽)
gray = np.array([[1,2,3], [4,5,6], [7,8,9]], dtype=np.uint8)

# 彩色图是三维数组(高×宽×3通道)
color = np.zeros((100, 100, 3), dtype=np.uint8)

# 快速创建全黑、全白、随机噪声图
black = np.zeros((200, 200), dtype=np.uint8)
white = np.ones((200, 200), dtype=np.uint8) * 255
noise = np.random.randint(0, 256, (200, 200), dtype=np.uint8)

超级重要提醒:图像的数据类型一定要用np.uint8!范围是0-255,超出的话会溢出,显示出来的颜色会完全不对,这个坑我已经提前踩过了。

2. 索引和切片(修改图像必备)

# 创建一个5x5的数组
arr = np.array([[1,2,3,4,5],
                [6,7,8,9,10],
                [11,12,13,14,15],
                [16,17,18,19,20],
                [21,22,23,24,25]])

# 获取单个元素(行, 列)
print(arr[2, 3])  # 14

# 获取左上角3x3区域
print(arr[0:3, 0:3])

# 把左上角3x3区域全部改成0
arr[0:3, 0:3] = 0
print(arr)

3. 形状变换(图像缩放/调整必备)

# 查看数组形状
print(arr.shape)  # (5, 5)

# 改变形状(元素总数要一样)
arr_flat = arr.reshape(25)
print(arr_flat.shape)  # (25,)

四、今日总结

  1. 环境一定要装opencv-contrib-python,别装基础版!别装基础版!别装基础版!重要的事情说三遍,基础版缺少很多功能。
  2. 图像数据类型必须是np.uint8,0-255,超出范围会导致图像颜色异常。
  3. 数组索引是(行, 列),也就是(y, x),和我们平时说的(x, y)是反的,这个很容易搞混,多练几次就能记住。
  4. 清华源可能会出现网页访问失败的情况,遇到时多重试几次,大概率是临时网络波动导致的。
  5. 安装时可能会提示“默认采用用户安装模式”,因为正常的site-packages目录没有写入权限,无需担心,不影响使用。
  6. 卸载旧版本时,可能会提示“跳过opencv-contrib-python,因为未安装”,属于正常情况,只需确保已安装的版本被成功卸载即可。
  7. Python环境混乱会导致安装失败,遇到这种情况,先卸载相关包,再重新安装,实在不行就重新配置Python环境。
  8. 基础语法是重点,尤其是NumPy的数组创建、索引、形状变换,后续操作都要用到,一定要多敲代码练习。

五、明天要学的

  1. 图像的读取、显示和保存(结合今天学的语法,实操练习)
  2. OpenCV那个反人类的BGR颜色空间(为什么OpenCV读出来的颜色和实际不一样)
  3. 调用摄像头实时显示画面(简单实操,增加成就感)
  4. 写个最简单的图像查看器(综合运用今天学的知识)

今天学了大概一个半小时,感觉还可以。主要是环境浪费了点时间(python环境乱成狗屎,安装中断导致后续安装不上),中途遇到了清华源访问失败(疑似跑路)、权限不足导致的用户安装模式等小问题,慢慢排查后都解决了,后面学NumPy的时候边敲代码边理解,效率还挺高的。果然学编程不能只看视频,一定要自己动手敲,尤其是语法部分,多敲几遍自然就懂了。

© 版权声明
THE END
喜欢就支持一下吧
点赞 0 分享 收藏
评论 抢沙发
OωO
取消