Python 进行图像处理的最佳实践,如:
pillow:基础的数字图像处理,操作图像的功能强大,API 简单易用。opencv:Open Source Computer Vision Library,计算机视觉的图像处理经典专用库,广泛应用于工业与科研的图像处理、计算机视觉、模式识别。scikit-image:基于 scipy 的图像处理包imghdr:【标准库】推测图片类型pyzbar:二维码识别qrcode:二维码相关操作muggle-ocr:无脑级验证码识别。准确率还可以。tesseract:光学识别验证码,不太准,还需要安装各种语言包,OUT
pyexiv2:操作图片的元数据
概述
图像格式
jpg:
bmp:Windows Bitmap
psd:Adobe Photoshop
png:portable Networks graphics:png8:8 位索引色位图:最多只能展示 256 种颜色,常用于颜色较为单一的图像
png24:24 位索引色位图:最多可展示 1600 万 + 种颜色,图像颜色丰富、清晰,大小也会相应增加,比较适合像摄影作品之类颜色比较丰富的图片
- 能提供透明背景,是一种专为网页展示而发明的图片格式。一般用于需要背景透明显示或对图像质量要求较高的网页上。
gif:提供的颜色较少,用在对颜色要求不高的地方,如 logo、按钮、表情,主要应用是动图
元数据:metadata:中介数据:中继数据:描述数据的数据。如用来指示存储位置、历史版本等功能。
- EXIF:数据相机拍摄照时添加。如相机型号、镜头、曝光、图片尺寸等信息
- 拍摄信息
- 拍摄器材(机身、镜头、闪光灯等)
- 拍摄参数(快门速度、光圈 F 值、ISO 速度、焦距、测光模式等)
- 图像处理参数(锐化、对比度、饱和度、白平衡等)
- 图像描述及版权信息
- GPS 定位数据
- 缩略图
- IPTF:人工后期通过软件写入的数据。如图片标题、关键字、说明、作者、版权等信息
- XMP:一种元数据存储和管理的标准,可将 EXIF、IPTF 或其他的数据按 XMP 统一格式存放在图像文件中。
- 颜色复杂、不带透明的,用 JPG。
- 带透明的优先用 PNG。
- 分辨率不变,格式不变,将图像变小
图像色彩空间/颜色模型
RGB
RGB:Red、Green、Blue:红绿蓝:主动产生颜色光源(显示器)
- 黑色:0,白色 255:黑色没有光线,没有信息
CMYK
CMYK:Cyan、Magenta、Yellow、Black:青、品红、黄、黑:用于印刷、绘画等
HSI
HSI:Hue、Saturation、Intensity:色调、色饱和度、亮度:用于调整颜色分量
色彩空间 -BGR
色彩空间/颜色空间/颜色模型,如 RGB、HSV、YUV 等
RGB:Red+Green+Blue 颜色空间的三维垂直坐标系表示方法,RGB 三通道
BGR:相机设备厂商的主流表示方法,后来 RGB 成了主流和默认,但是这个底层的顺序却保留下来了,事实上 Windows 下的最常见格式之一 bmp,底层字节的存储顺序还是 BGR
RGB:人眼的感受光谱范围为:380~780nm。1931年国际照明委员会(CIE)规定将波长700nm、546.1 nm和435.8nm的单色光作为红绿蓝三原色,又称物理三基色
OpenCV 彩色图以 BGR 通道顺序存储的,灰度图只有一个通道
1
2
3
4# BGR 格式转为 RGB 格式
img_cv2_rgb=img_cv2_bgr[...,::-1]
# 沿 x 轴反转
img_flip=img_cv2[::-1,:,:]HSV:颜色空间的圆柱坐标系表示法,相比 RGB 能区分亮度等信息
OpenCV 与 PIL 的通道不同,对于推理时的结果可能有零点几个点的差别
色彩空间转换
三个分量(通道):色相(Hue)、饱和度(Saturation)、明度(Value),相比 RGB 能区分亮度等信息
- 色相:Hue,色调,角度度量,取值范围为 0° ~ 360°,从红色开始按逆时针方向计算,红色为 0°,绿色为 120°,蓝色为 240°。就是说,我用红色还是绿色还是粉色
有三个分量(通道): - 色调 H,用角度度量,取值范围为 0° ~ 360°,从红色开始按逆时针方向计算,红色为 0°,绿色为 120°,蓝色为 240°。就是说,我用红色还是绿色还是粉色
- 饱和度 S,饱和度高,颜色则深而艳。即,我要用淡粉还是 深粉(就是深一点的粉色)
- 明度 V,表示颜色明亮的程度,对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射情况或反射反射情况有关。就是说,屏幕是亮一点还是暗一点。
- 饱和度 S:色彩的纯度,饱和度越低则颜色越黯淡 ( 0<= S < 1),饱和度高,颜色则深而艳。即,我要用淡粉还是 深粉(就是深一点的粉色)
- 明度 V,即颜色的明暗程度。数值越高越接近白色,数值越低越接近黑色 ( 0 <= V < 1);表示颜色明亮的程度,对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射情况或反射反射情况有关。就是说,屏幕是亮一点还是暗一点
| 红 | 黄 | 绿 | 青色 | 蓝色 | 品红 | 红 |
|---|---|---|---|---|---|---|
| 0 | 60 | 120 | 180 | 240 | 300 | 360 |
图片元数据
Metadata:元数据,又称中介数据、中继数据,是描述数据的数据,图片元数据类似于文件属性
- 常见的几种标准有:
- EXIF(exchangeable image file format, 简称 Exif),是一种可交换图像文件的缩写,是专门为数码相机照片设定的可以记录数码照片的属性信息和拍摄数据。Exif 可以附加于 JPEG、TIFF 等文件中,为其增加有关数码相机拍摄信息的内容和索引图或图像处理软件的版本信息。
EXIF 最初是由图本电子工业发展协会在 1996 年制定版本为 1.0。1988 年升级到 2.1,增加了对音频文件的支持。2002 年 3 月发布 2.2 版。
Window7 操作系统具备对 Exif 的原生支持,通过鼠标右键点击图片 => 属性=> 详细信息标签即可查看 Exif 信息,注意 Exif 信息是可以被任意编辑因此 Exif 信息只能作为参考。
Exif 记录的元信息非常丰富,主要包含一下几类信息:- 拍摄信息
- 拍摄器材(机身、镜头、闪关灯等)
- 拍摄参数(快门速度、光圈 F 值、ISO 速度、焦距、测光模式等)
- 图像处理参数(锐化、对比度、饱和度、白平衡等)
- 图像描述以及版权信息
- GPS 定位数据
- 缩略图
EXIF:通常被数码相机在拍摄照片时自动添加,比如相机型号、镜头、曝光、图片尺寸等信息。
IPTC:比如图片标题、关键字、说明、作者、版权等信息。
XMP:由 Adobe 公司制定标准,以 XML 格式保存。用 PhotoShop 等 Adobe 公司的软件制作的图片通常会携带这种信息。
比较
- 读图:16384 x 16384 的大图,opencv 1.55s,PIL 1.1s,PIL 胜
- resize:16384 至 4096:opencv:7ms,transform:300ms
Pillow
pillow:基础的数字图像处理,操作图像的功能强大,API 简单易用。
- PIL(Python Imaging Library)仅支持到 Python 2.7,加上年久失修,所以诞生了 Pillow
1 | pip install Pillow |
基本操作
1 | from PIL import Image |
创建
1 | img = np.zeros((10, 10), np.uint8) |
模式转换
L = R * 299/1000 + G * 587/1000 + B * 114/1000, 将彩色图片转换为黑白图片. greyscale(‘L’), color(‘RGB’)
1 | img=Image.open('a.png').convert('L') |
像素操作
1 | im.getpixel((100,80)) #元组坐标取像素 |
通道操作
1 | img.split() # 以一个三元 tuple 将原图分裂为三个通道, |
写字
1 | from PIL import Image,ImageDraw, ImageFont |
滤镜 -filter
- BLUR
- DETAL
- SMOOTH
- SHARPEN
- EMBOSS
- ENHANCE
1 | from PIL import Image, ImageFilter |
旋转 -rotate-transpose
1 | # rotate:旋转,angle 为逆时针方向旋转的角度 |
裁剪
1 | box=(120,194,220,294) # left,upper,right,lower |
屏幕截图
1 | from PIL import ImageGrab |
裁剪与粘贴
1 | box = (120, 194, 220, 294) #定义裁剪区域 |
图像缩放
resize(): 修改图片的 size, resample 参数传入采样算法, 一般使用高质量缩放的 Image.LANCZOS 参数
1 | im = im.resize((100,100)) #参数表示图像的新尺寸,分别表示宽度和高度 |
根据代码和代码注释, 这两个函数都是对图片进行缩放, 两者的主要区别如下:
resize()函数会返回一个 Image 对象,thumbnail()函数返回 Noneresize()修改后的图片在返回的 Image 中, 而原图片没有被修改;thumbnail()直接对内存中的原图进行了修改, 但是修改需要保存resize()中的 size 参数直接设定了 resize 之后图片的规格, 而thumbnail()中的 size 参数则是设定了 x/y 上的最大值. 也就是说, 经过resize()处理的图片可能会被拉伸, 而经过thumbnail()处理的图片不会被拉伸thumbnail()函数内部调用了resize(), 可以认为thumbnail()是对resize()的一种封装
两个函数的基本调用方式如下:
1 | # 缩放到 50%: |
图像增强
1 | from PIL import Image |
put*(): 各种 put 函数, 用于修改当前图片的一些参数
图像通道分离与合并
1 | r, g, b = im.split() #将彩色图像分离为同样大小的红、绿、蓝三分量子图 |
获取文字的像素宽度
1 | from PIL import ImageFont |
OpenCV
opencv:Open Source Computer Vision Library,计算机视觉的图像处理经典专用库,广泛应用于工业与科研的图像处理、计算机视觉、模式识别。
- 具有 C++、Python 接口,Opencv-Python 调用了 C/C++,易用 + 运行效率兼得。
- 高效计算,多线程
- 可移植性,跨平台
- 开源,BSD 协议
- 运行速度:
- 加载一张本地图像约 10ms
常识
组成
从下至上
- OpenCV HAL 硬件加速层:SSE, NEON, IPP, OpenCL, CUDA, OpenCV4Tegra
- opencv_contrib:大多数高层级的函数功能
- 语言绑定和示例应用程序
- 与操作系统的交互
模块
1 | opencv2 |
Core:- 基本数据结构与基本操作、动态数据结构
- 绘图函数
- 数组操作相关函数
- 辅助功能与系统函数及宏
- 与 OpenGL 的互操作
Improc:Image+Processing 图像处理模块,基本的图像转换、滤波和卷积等操作- 线性和非线性的图像滤波
- 图像的几何变换
- 其它(Miscellaneous)图像转换
- 直方图相关
- 结构分析和形状描述
- 运动分析和对象跟踪
- 特征检测
- 目标检测等内容
HigGUI:显示图像及具有简单输入的用户交互函数,轻量级的 Windows UI 工具包- 也就是 high gui,高层 GUI 图形用户界面,包含媒体的 I / O 输入输出,视频捕捉、图像和视频的编码解码、图形交互界面的接口等内容
Video:读写视频流- 视频分析组件,该模块包括运动估计,背景分离,对象跟踪等视频处理相关内容。
Calib3d:Calibration+3D 校准单个、双目及多个相机的算法实现,多视角几何算法,单个立体摄像头标定,物体姿态估计,立体相似性算法,3D 信息的重建等等Feature2d:检测、描述及匹配特征点的算法- 特征检测和描述
特征检测器(Feature Detectors)通用接口
描述符提取器(Descriptor Extractors)通用接口
描述符匹配器(Descriptor Matchers)通用接口
通用描述符(Generic Descriptor)匹配器通用接口
关键点绘制函数和匹配功能绘制函数
- 特征检测和描述
Objdectect:特定目标检测,如人脸或行人Ml:机器学习算法模块,能与 OpenCV 的数据类型良好交互、- Machine Learning,机器学习模块, 基本上是统计模型和分类算法
Flann:最邻近搜索, Fast Library for Approximate Nearest Neighbors,高维的近似近邻快速搜索算法库GPU:由多个 cuda* 模块组成,实现 GPU 的加速stitching:图像拼接Contrib:opencv_contrib,扩展模块,一些新的、没有被集成到 OpnCV 库的东西Legacy:一些已经废弃的代码库,保留下来作为向下兼容Ocl:开放并行编程的 Khronos OpenCL 标准,目标是提供可以运行在任何 GPU 或其他可以搭载 Khronos 的并行设备。Dnn:深度神经网络Face:人脸识别Text:文本检测及识别,基于许多开源的 OCR 算法Rgbd:处理由 Kinect 或其他深度传感器获得的 RGB+ 深度图像Bioinspired:基于生物学启发的视觉技术ximgpro 和 xphoto:先进的图像处理以及计算摄影学方法Tacking:现代目标追踪算法
不用
Nonfree:专利保护或受限的算法如 SIFT 算法、SURF 算法,需进行特殊操作,才能进行商业使用- Cmake 编译时勾选“OPENCV_ENABLE_NONFREE”
- SIFT implementation.
The class implements SIFT algorithm by D. Lowe.
2,SURF implementation.
The class implements SURF algorithm by H. Bay et al.
- SIFT implementation.
- Cmake 编译时勾选“OPENCV_ENABLE_NONFREE”
基本操作
1 | pip install opencv-python |
对象属性
Attention:OpenCV 除涉及到 numpy 的,其他都是 (宽度,高度)的格式,因 numpy、pytorch 这种是由于本身张量或者矩阵形式的维度相关,先行后列,高度在前、宽度在后
1 |
|
读入 - 显示 - 保存
- Attention:即使图像路径错误,它不会引发任何错误,只是
img_cv2为 None
1 | img_cv2 = cv2.imread( # 图像矩阵,numpy 的 ndarray |
- 显示
1 | cv2.namedWindow( |
- 保存
1 | cv2.imwrite('test.png',img_output,[cv2.IMWRITE_PNG_COMPRESSION,0]) |
文件格式由 filename 参数的文件扩展名确定
- 推荐使用 PNG,无损压缩
- BMP 无损不压缩,很大
- JPEG 有损压缩会丢失信息
- params:
- JPEG:图像的质量,0-100,越大质量越高,文件越大,默认 95
- PNG:压缩级别,0-9,越大文件越小,压缩用时越长,默认为 3
- PPM,PGM 或 PBM:1 表示文件是以二进制,0 表示文件是以纯文本存储,默认为 1
像素操作
- 尽量使用 numpy 这一优化过的矩阵运算,而不是像素的循环。
1 |
|
通道处理
1 | r,g,b=cv2.split(img) # 拆分 |
解码
1 | # 慢慢慢,内存操作怎么会这么慢,查资料说它会先将内存数据写到临时文件再读取...laji 啊 |
裁剪
裁剪:考虑原图像的宽高干扰,常在将样本输入网络前统一大小,
blur
filter
contrast
填充
1 | cv2.copyMakeBorder(src, top, bottom, left, right, borderType[, dst[, value]]) |
src: 原图片top: 上方填充宽度bottom: 下方填充宽度left: 左边填充宽度right: 右边填充宽度borderType: 边界类型value: 边界填充值
缩放
缩放:向外缩放与向内缩放
1 |
|
INTER_NEAREST:最近邻插值INTER_LINEAR:双线性插值,默认使用INTER_AREA:使用像素区域关系进行重采样,图像缩小时优先使用INTER_CUBIC:4x4 的邻域上进行双立方插值,图像放大时优先使用
翻转与旋转
翻转:将图像进行镜像操作,包括水平镜像翻转、垂直镜像翻转、原点镜像翻转
旋转:沿画面的中心进行任意角度的变换,通过将原图像与仿射变换矩阵相乘实现。
1 | # 翻转 |
拼接
1 | img_new=cv2.hconcat([img_1,img_2,img_3]) # 水平拼接 |
裁剪
1 | new_img_cv2=img_gray_cv2[y1:y2,x1:x2] |
平移
1 | # 放射变换来平移 |
二值化 threshold
1 | cv2.threshold(src, thresh, maxval, type[, dst]) → retval, dst |
边缘检测
- canny 边缘检测:检测轮廓边界像素
1 | img_out = cv2.Canny(img, 30, 200) |
轮廓
轮廓:连续的点,边界像素合成轮廓曲线,常用于形状分析、物体检测与识别
轮廓查找
- 寻找轮廓是针对白色物体的,即需要物体是白色,背景是黑色。不然会找到图片最外面的一个框。
1 | # 灰度图 |
- mode
RETR_EXTERNAL:只检测最外层轮廓RETR_LIST:检索所有轮廓并保存到表 List 中,检测的轮廓不建立等级关系RETR_CCOMP检索所有轮廓组织成两层结构,一层为所有外边界,一层为孔的边界如果内孔内还有一个连通物体,这个物体的边界也在顶层。RETR_TREE检索所有轮廓,并建立等级树结构的轮廓。
- Method:为轮廓的近似办法
CHAIN_APPROX_NONE:将轮廓编码中的所有的点存储为轮廓点,相邻的两个点的像素位置差不超过 1,即 max(abs(x1-x2),abs(y2-y1))==1CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需 4 个点来保存轮廓信息CHAIN_APPROX_TC89_L1,CHAIN_APPROX_TC89_KCOS使用 teh-Chinl 链逼近算法,用于减少返回的点数
- Offset:表示代表轮廓点的偏移量,可以设置为任意值。
绘制轮廓
1 | # 绘制找到的轮廓 |
轮廓特征
1 | image,contours,hierarchy=cv2.findContours(thresh,1,2) |
Blob 分析
Blob 分析:Blob Analysis:对图像中相同像素的连通域进行分析,该连通域称为 Blob。常对二值化后的图像进行分析。
- 从背景分离目标,计算目标数量、位置、形状、方向、大小。
- 一般来说,基于块的分析比基于像素的分析快得多。
形态学操作
- 用处:
- 消除噪声;
- 分割出独立的图像元素,在图像中连接相邻的元素;
- 寻找图像中明显的极大值区域或极小值区域;
- 求出图像的梯度。
膨胀:dilate:卷积操作,将目标像素的值替换为卷积核覆盖区域的 “ 局部最大值”
- 作用:扩张明亮区域,填充凹面,发现连通分支 (“颜色”块)
腐蚀:erode:卷积操作,与膨胀相反,将目标像素的值替换为卷积核覆盖区域的“局部最小值”
- 作用:使边界向内部收缩,缩减明亮区域,消除小且无意义的特征,如突起、斑点状的噪声,
形态学:morphology:
开运算:MOP_OPN:Opening Operation:先腐蚀后膨胀
- 用来消除小物体、在纤细点处分离物体、平滑较大物体的边界的同时并不明显改变其面积.
闭运算:MOP_CLOSE:Closing Operation:先膨胀后腐蚀
- 用来填充物体内细小空洞、连接邻近物体、平滑其边界的同时并不明显改变其面积.
形态学梯度:MorphologicalGradient:图像的膨胀与腐蚀的差别
- dst=dilate(src,element)-erode(src,element)
- 标注明亮边缘
顶帽/礼帽:TopHat:原始图像与进行开运算之后得到的图像的差。
- dst=src-open(src,element)
- 原图像的减去开运算后的图,
- 突出了与邻域相比更亮的部分
- 与核的大小相关
黑帽/底帽:BlackHat:进行闭运算之后得到的图像与原始图像的差。
- dst=close(src,element)-src
- 闭运算 - 原图像
- 显示与邻域相比更暗的部分
- 分离比邻近点暗一些的斑块。
1 | # 读入图像: |
滤波
滤波:增强需要的特征或去除图像中不需要的干扰。
低通滤波器:LPF: 有助于消除噪声,模糊图像等.
高通滤波器:HPF:有助于找到边缘
均值滤波:用像素点周围像素的平均值代替像素值,在滤除噪声的同时也会滤掉图像的边缘信息
1 | img_mean = cv2.blur(img_cv2,(5,5)) |
高斯滤波:相比于均值滤波简单的取平均值,这里是求加权平均,距离越近的点权重越大,距离越远的点权重越小。
- 去除高斯噪声
1 | img_guassian = cv2.GaussianBlur(img_cv2,(5,5),0) |
中值滤波:像素周围邻域像素集中的中值代替原像素
- 用于去除椒盐噪声和斑块噪声
1 | img_median = cv2.medianBlur(img_cv2,5) |
双边滤波:
- 两个滤波器:
- 一个空间上的高斯滤波器:使临近的像素点被用于滤波
- 一个基于像素差的高斯滤波器:使与中间像素值相同的像素点被用于滤波
- 在滤波的同时能保证一定的边缘信息
1 | img_bilater=cv2.bilateralFilter(img,9,75,75) |
卷积
卷积:convolution:卷积核按步长对图像局部像素块进行加权求和的过程
核:kernel:实质上是一个固定大小的权重数组,该数组中的锚点通常位于中心。通常情况下,选取卷积核大小为 1x1,3x3,5x5,7x7 等
利用像素点和其邻域像素之前的空间关系,通过加权求和的操作,实现模糊(blurring),锐化(sharpening),边缘检测(edge detection)等功能
取奇数大小的目的是为了设置卷积核中心为锚点,方便卷积核和图像的对齐处理
设置卷积核大小对称的目的是为了在空间域中充分利用像素点和其领域像素间的关系。当然这不是必须的,如果需要针对某一轴进行处理,可以设置 1x3 或 3x1 大小。
检测拟合
圆检测
1 | # 单通道图内检测圆形物体 |
1 | # demo |
直线拟合
1 | cv2.HoughLines():二值图像中查找直线 |
距离类型
cv::DIST_L2:最小二乘法:cv::DIST_L1:cv::DIST_L12:cv::DIST_FAIR:cv::DIST_WELSCH:cv::DIST_HUBER:
绘制
1 | 1920*1080 的屏幕图 |
1 | # 生成空图像 |
1 | # 直线 |
视频读写
1 | # 读视频类:可从视频文件、摄像头中读取图像。 |
图像归一化
将矩阵的值变换到某个区间内
- 如 cv2.imshow 可以正常显示,但保存或显示到网页上为全黑的,是由于图像的格式在 float32 与 uint8 乱了,需要
1 | img = cv2.normalize(img, None, 0 , 255, cv2.NORM_MINMAX, cv2.CV_8U) |
- norm_type
- NORM_MINMAX:线性归一化,平移或缩放到一个指定的范围
- $dst(i,j)=\dfrac{[src(i,j)-min(src(x,y))]*(max-min)}{max(src(x,y)-min(src(x,y)))}+min$
- NORM_INF:L 无穷范数,即矩阵各元素绝对值的最大值(切比雪夫距离)
- 除以数组中绝对值最大值
- $dst(i,j)=\dfrac{src(i,j)}{Max|src(x,y)}$
- NORM_L1:L1 范数,即矩阵元素的绝对值之和(曼哈顿距离)
- 除以数组和的绝对值
- $dst(i,j)=\dfrac{src(i,j)}{|\sum src(x,y)|}$
- NORM_L2:分母为 L2- 范数,即矩阵各元素的欧几里德距离之和
- 除以数组平方和再开根号
- $dst(i,j)=\dfrac{src(i,j)}{\sqrt{\sum {src(x,y)^2}}}$
norm_type 有 NORM_INF, NORM_MINMAX,NORM_L1 和 NORM_L2 四种。
1、在 NORM_MINMAX 模式下,alpha 表示归一化后的最小值,beta 表示归一化后的最大值。
2、在 NORM_L1、NORM_L2、NORM_INF 模式下,alpha 表示执行相应归一化后矩阵的范数值,beta 不使用。
3、稀疏矩阵归一化仅支持非零像素
透视变换矩阵计算
1 |
|
1 | from cv2 import cv2 |
霍夫变换
霍夫变换:Hough Transform:图像处理中的一种特征提取技术,投票算法检测具有特定形状的物体
描述物体的位置与姿态
旋转矩阵:一个向量乘以旋转矩阵等价于向量以某种方式进行旋转。
旋转向量:
- 旋转向量的长度(模)表示绕轴逆时针旋转的角度(弧度)
- 便于计算机计算,
欧拉角: 任何一个旋转可以表示为依次绕着三个旋转轴旋三个角度的组合。这三个角度称为欧拉角。
- 便于用户操作,检查运算结果的正确性
四元数:
罗德里格斯(Rodrigues)变换进行转换
1 | R = np.zeros((3, 3), dtype=np.float64) |
aruco
- 一个 aruco marker 是一个二进制平方标记,它由一个宽的黑边和一个内部的二进制矩阵组成,内部的矩阵决定了它们的 id。黑色的边界有利于快速检测到图像,二进制编码可以验证 id,并且允许错误检测和矫正技术的应用。marker 的大小决定了内部矩阵的大小。例如,一个 4x4 的 marker 由 16bits 组成。
- 码占据图像百分比越高 + 图像越清晰 + 越靠近图像中心(畸变小)=效果越好
交互 - 回调函数
1 | import cv2 |
遇到的问题
- cv2 读写
.jpg图像时,仅读 + 写,得到的.jpg图像与原图不一样 - 因为每次 cv2 写.jpg 图像时都会进行有损压缩,建议保存为
.png无损压缩即可。
读中文路径
- 20200502, Linux, opencv-python v4.5.1,已可正常读写中文路径,Nice!
- but,后来发现 Windows 上还是不行 opencv-python v4.5.2.54,研究后基本确认是由于 windows 是 gbk 编码,改为 utf-8 编码又怕引发莫名的问题,暂时无解
1 | import cv2 |
TypeError: Argument given by name (‘thickness’) and position (4)
1 | cv2.rectangle(image, (left,top), (right , bottom), (255, 0, 0), thickness=2) |
- 由于左上角、或右下角的坐标不是 int
- 报错 DLL load failed while importing cv2: 找不到指定的模块。
https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/opencv-python/
看下对应版本的信息,比如这边的最新的 4.6.0.66 的版本是 cp38-abi3,貌似不太对,改为带有 cp38-cp38 的 opencv_python-4.5.4.60-cp38-cp38-win_amd64.whl 可以了
图像相减
- 需注意,opencv 图像相加或相减时,像素值超出 [0,255],(比如负数),会产生意想不到的结果
C++
曾在 C++ 的 OpenCV 中遇到这样的问题:
因 Size 与 Size2f 的数据类型同,得到的棋盘格大小不同,使结果产生偏差。
1 | cv::Size2f squareSize = cv::Size2f(22.5, 22.5); //测量得到的棋盘格的大小 |
编译
- opencv-3.4.0.zip
- opencv-3.4.0-vc14_vc15.exe
- opencv-4.1.0-vc14_vc15.exe
- opencv_contrib-4.5.0.zip
scikit-image
scikit-image:基于 scipy 的图像处理包
- 将图像作为 numpy 数组处理
- 常用功能:模糊、增强对比度、缩放等
- 前置包:numpy+matplotlib+scipy+scikit-image
- 组件:
- color 颜色空间变换
- data 提供一些测试图片和样本数据
- filters 图像增强,边缘检测,排序滤波器,自动阈值等
- draw 操作于 numpy 数组上的基本图形绘制,包括线条,矩阵,圆和文本等
- transform 几何变换和其他变换,如旋转,拉伸和 Radon(拉东) 变换等
- exposure 图像强度调整,例如,直方图均衡化等
- feature 特征检测和提取, 例如,纹理分析等
- graph 图论操作,例如,最短路径
- measure 图像属性测量,例如,相似度和轮廓
- morphology 形态学操作,如开闭运算,骨架提取等
- novice 简化的用于教学目的的接口
- restoration 修复算法,例如去卷积算法,去噪等
- segmentation 图像分割为多个区域
- util 通用工具
- viewer 简单图形用户界面用于可视
基本使用
- io 读取/保存/显示图片与视频
1 | from skimage import io |
1 | # data |
pyvips
pyvips:Python绑定到libvips的库,旨在提供高速度和低内存占用的图像处理解决方案
- Libvips:用于图像处理的高性能、小内存消耗的库,特别适合大量图像数据的批和凸显任务。
1 | pip install pyvips |
基本使用
1 | from pyvips import Image |
- 流式处理:pyvips 在处理大图像时优势非常明显,因为它不会将整个图像加载到内存中,而是采用流式处理,这意味着即使是几十 GB 的大图像也可以在内存消耗非常少的情况下进行处理。
1 | # 读取一张大图像 |
imghdr
imghdr:【标准库】推测图片类型
pyzbar
pyzbar:二维码识别
1 | import zbar |
python-qrcode
qrcode:二维码相关操作
1 | pip install python-qrcode |
1 | import qrcode |
muggle-ocr
muggle-ocr:无脑级验证码识别。准确率还可以。
tesseract:光学识别验证码,不太准,还需要安装各种语言包,OUT
1 | pip install muggle-ocr |
- 预置模型:
ModelType.OCR:识别普通印刷文本ModelType.Captcha:识别 4-6 位简单英数验证码
1 | # 导入包 |
pyexiv2
pyexiv2:操作图片的元数据
- 元数据的读取速度与元数据的数量成反比,不管图片的大小如何。
1 |
基本使用
1 | class Image: |
- 如果你尝试修改一个非标准的标签,则可能引发一个异常
- 某些特殊的标签不能被 pyexiv2 修改,如
img.modify_xmp({'Xmp.xmpMM.History': 'type="Seq"'}) - 修改元数据的速度与图片的大小成反比。
1 | # 读 |
