ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

OpenCV Python 图像基本操作详解:像素访问、图像属性、ROI、通道拆合与 copyMakeBorder 边界填充

OpenCV Python 图像基本操作详解:像素访问、图像属性、ROI、通道拆合与 copyMakeBorder 边界填充 OpenCV Python 图像基本操作详解像素访问、图像属性、ROI、通道拆合与 copyMakeBorder 边界填充【免费下载链接】opencvOpen Source Computer Vision Library项目地址: https://gitcode.com/GitHub_Trending/opencv31/opencv本文以 OpenCV 官方 Python 教程“Basic Operations on Images”为主体系统讲解图像像素的读写、图像属性shape/size/dtype的读取、感兴趣区域ROI的选取、BGR 通道的拆分与合并以及cv.copyMakeBorder()的五种边界类型。读完后你将能够熟练使用 NumPy 索引与 OpenCV API 完成日常图像处理的基本操作并理解这些操作在 OpenCV C 源码中的真实实现依据。教程目标与前提该教程py_basic_ops.markdown要求读者学会四件事访问并修改像素值Access pixel values and modify them访问图像属性Access image properties设置感兴趣区域 ROIRegion of Interest拆分与合并图像通道Split and merge images教程明确指出本节几乎所有操作本质上都是 NumPy 数组操作而非 OpenCV 专属功能。“Almost all the operations in this section are mainly related to Numpy rather than OpenCV. A good knowledge of Numpy is required to write better optimized code with OpenCV.”——扎实的 NumPy 功底是写出高效 OpenCV Python 代码的前提。示例均以 Python 交互终端单行命令形式给出。访问与修改像素值先加载一张彩色图像 import numpy as np import cv2 as cv img cv.imread(messi5.jpg) assert img is not None, file could not be read, check with os.path.exists()cv.imread()读取成功后图像就是一个 NumPy 数组。可以用行列坐标直接访问像素值对 BGR 彩色图像返回一个包含蓝、绿、红三个分量的一维数组对灰度图像则只返回对应的灰度强度值 px img[100,100] print( px ) [157 166 200] # accessing only blue pixel blue img[100,100,0] print( blue ) 157注意 OpenCV 与 NumPy 的索引顺序是img[行, 列, 通道]即[y, x, c]这与某些库的[x, y, c]习惯不同。img[100,100,0]取的是第 100 行、第 100 列像素的蓝色分量BGR 顺序中第 0 通道。以完全相同的方式可以修改像素值 img[100,100] [255,255,255] print( img[100,100] ) [255 255 255]性能警告原文强调NumPy 是面向快速数组运算优化的库逐像素地访问和修改每个像素会非常慢教程明确不推荐very slow and it is discouraged。批量操作应使用切片、广播等向量化手段见下文 ROI 与通道处理部分。访问图像属性图像属性包括行数、列数、通道数、数据类型、总像素数等。shapeimg.shape返回一个元组(行数, 列数, 通道数)通道数仅在彩色图像时出现 print( img.shape ) (342, 548, 3)注如果图像是灰度图返回的元组只有行数和列数两项如(342, 548)。因此shape的维度数是判断图像是灰度还是彩色的简便方法。size总像素数通过img.size获得行 × 列 × 通道 print( img.size ) 562248dtype图像数据类型通过img.dtype获得 print( img.dtype ) uint8注img.dtype在调试中非常重要——OpenCV-Python 代码中出现的大量错误源于数据类型无效例如把 float 型矩阵传给了只接受uint8的函数。图像 ROI感兴趣区域实际应用中经常需要只处理图像的某个区域。典型场景是人脸/眼睛检测先对整幅图做人脸检测得到人脸后只选取人脸区域在其中搜索眼睛而不用搜索整幅图。这既提高了准确率眼睛总是在脸上也提升了性能搜索范围更小。ROI 同样通过 NumPy 索引获得。下面的示例选取图中的“足球”区域并把它复制到图像中的另一个位置先切片取出再赋值过去 ball img[280:340, 330:390] img[273:333, 100:160] ball第一行用切片img[280:340, 330:390]取出 60×60 的球区域第二行将其赋值到img[273:333, 100:160]指定的目标区域完成一次“区域复制”。从底层看这种切片赋值依赖 NumPy 视图view语义ball与原图共享内存对它的修改会反映到img上——这既是方便之处也意味着赋值方向img[...] ball与预期一致时才能安全使用。拆分与合并图像通道有时需要单独处理 B、G、R 中的某一个通道例如只操作红色此时需要将 BGR 图像拆分成单通道反之也常需要把独立通道合并回 BGR 图像。方式一使用 OpenCV 的 split / merge b,g,r cv.split(img) img cv.merge((b,g,r))方式二直接使用 NumPy 索引取单通道 b img[:,:,0]性能提示如果你的目标只是修改某一个通道根本不需要先拆分。例如要把所有红色像素置零直接用 NumPy 索引更快 img[:,:,2] 0警告原文强调cv.split()是耗时操作仅在确实需要独立通道对象例如对单个通道做滤波、统计时才使用否则优先用 NumPy 索引。为图像创建边界cv.copyMakeBorder()若要给图像加一圈“相框”式的边界可以使用cv.copyMakeBorder()。但它在工程中有更广泛的应用卷积操作的边界扩展、零填充zero padding等——从源码结构看它本身就是 OpenCV 内部许多算法的基础设施例如模板匹配在补齐模板块时调用它templmatch.cpp 第 201 行附近CLAHE 用BORDER_REFLECT_101扩展图像到 tile 边界clahe.cpp 第 381 行warpAffine用BORDER_WRAP处理角点imgwarp.cpp 第 3130 行轮廓检测与泛洪填充则用BORDER_CONSTANT | BORDER_ISOLATED隔离 ROI 边界contours_new.cpp 第 703 行、floodfill.cpp 第 510 行。函数参数copyMakeBorder()的完整签名见 core.hppvoid copyMakeBorder(InputArray src, OutputArray dst, int top, int bottom, int left, int right, int borderType, const Scalar value Scalar() );参数说明src— 输入图像top, bottom, left, right— 上、下、左、右四个方向各扩展的像素数borderType— 边界类型标志value— 当 borderType 为cv.BORDER_CONSTANT时的边界颜色输出图像dst的尺寸为Size(src.colsleftright, src.rowstopbottom)与 src 类型相同。边界类型 BorderTypes教程中列出的五种边界类型与 OpenCV 源码中的枚举定义一一对应枚举及各类型的 ASCII 示意图在 base.hppenum BorderTypes { BORDER_CONSTANT 0, //! iiiiii|abcdefgh|iiiiiii with some specified i BORDER_REPLICATE 1, //! aaaaaa|abcdefgh|hhhhhhh BORDER_REFLECT 2, //! fedcba|abcdefgh|hgfedcb BORDER_WRAP 3, //! cdefgh|abcdefgh|abcdefg BORDER_REFLECT_101 4, //! gfedcb|abcdefgh|gfedcba ... BORDER_DEFAULT BORDER_REFLECT_101 };各类型含义|为原图边界cv.BORDER_CONSTANT— 用指定常量色填充边界颜色由value参数给出形如iiiiii|abcdefgh|iiiiiiicv.BORDER_REPLICATE— 沿边缘无限复制最后一个像素形如aaaaaa|abcdefgh|hhhhhhhcv.BORDER_REFLECT— 边界元素的镜面反射形如fedcba|abcdefgh|hgfedcbcv.BORDER_REFLECT_101即cv.BORDER_DEFAULT默认值— 与 REFLECT 类似但略有不同形如gfedcb|abcdefgh|gfedcbacv.BORDER_WRAP— 环绕式边界形如cdefgh|abcdefgh|abcdefg另外源码枚举中还定义了BORDER_TRANSPARENT视越界像素为透明形如uvwxyz|abcdefgh|ijklmno和BORDER_ISOLATED标志位 16插值/外推被限制在 ROI 边界内——即上文的 note当 src 本身是更大图像的一个 ROI 时copyMakeBorder默认会尝试利用 ROI 外部的真实像素来构造边界加上BORDER_ISOLATED可禁用该行为。完整示例代码下面示例对同一图像分别生成五种类型的边界并用 matplotlib 展示边界宽度均为 10 像素import cv2 as cv import numpy as np from matplotlib import pyplot as plt BLUE [255,0,0] img1 cv.imread(opencv-logo.png) assert img1 is not None, file could not be read, check with os.path.exists() replicate cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REPLICATE) reflect cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT) reflect101 cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT_101) wrap cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_WRAP) constant cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_CONSTANT,valueBLUE) plt.subplot(231),plt.imshow(img1,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()注意两点示例中valueBLUE即[255,0,0]——因为 OpenCV 读取的图像是 BGR 顺序[255,0,0]表示的是蓝色虽然变量名沿用教程习惯。结果图由 matplotlib 显示matplotlib 使用 RGB 顺序因此红色与蓝色通道会互换直接imshowBGR 图像时颜色可能“看起来反了”。小结与工程建议结合本教程与源码可以归纳出以下实践准则优先 NumPy 索引慎用 cv.split/cv.merge单通道读取img[:,:,0]、单通道写入img[:,:,2]0都更快cv.split()开销大仅在需要独立通道对象时使用。避免 Python 级逐像素循环像素读写用切片/广播完成性能差异显著。shape 三元组判断彩色/灰度(rows, cols)为灰度(rows, cols, 3)为彩色。dtype 是首要调试对象OpenCV-Python 大量异常源于数据类型不匹配报错时先检查img.dtype。copyMakeBorder 是通用垫底工具边界宽度四参数 五种及以上borderType既可用作视觉“相框”也是卷积、模板匹配、CLAHE 等算法内部零填充/边界外推的标准手段需要隔离 ROI 外部像素时记得BORDER_ISOLATED。延伸阅读同系列教程中的图像算术运算 py_image_arithmetics.markdown 与优化 py_optimization.markdown以及borderInterpolatecopyMakeBorder文档中的sa关联函数用于单像素边界外推在 core.hpp 中的声明。【免费下载链接】opencvOpen Source Computer Vision Library项目地址: https://gitcode.com/GitHub_Trending/opencv31/opencv创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表