OpenCV与图像算法笔记

2023-11-07

本博客为《OpenCV算法精解:基于Python与C++》一书(参阅源代码链接)的阅读笔记,根据理解对书中绝大多数算法做了总结和描述,对Numpy较为熟悉,Python方面仅对与C++不同的注意事项做了标注。书作者整体按照冈萨雷斯的经典教材《数字图像处理(第三版)》和OpenCV知识脉络组织内容,每个算法均用Python和C++两种语言实现。除官方函数外本书给出了多数算法函数的自定义版本便于读者理解,以及部分官方未包含的算法(利于导向滤波、Marr-Hildreth边缘检测等)
源代码下载地址 www.broadview.com.cn/32495

文章目录

第二章: 图像的数字化

一. 创建一个Mat
1. Mat(行, 列, 类型)  
2. Mat(Size(列, 行), 类型)  
3. 对已声明Mat对象 m.create 格式同上
4. Mat::ones, Mat::zeros  
5. 直接初始化小型矩阵值 (Mat_<int>(2,3) << 1,2,3), 把int和后面元素换成Vec2f等可以直接初始化双通道矩阵  
6. Mat(vector<Point2f>)构造N行1列的双通道矩阵Mat  
7. 可以用Mat的reshape方法变换矩阵形状和通道  
二. Mat的基本成员变量和函数
rows, cols, size(), channels(), total(), dims, 转置t()等  
三. 访问Mat对象中的值
1. 成员函数at(最慢,最可读): m.at<float>(r,c), 可用Point对象: m.at<int>(Point(c,r)) 注:Point和Size对象先列再行   
2. 成员函数ptr可获取任意一行的行指针: const int * ptr = m.ptr<int>(r) 获取行指针后访问列 ptr[c]  
3. 成员函数isContinuous可获取矩阵每一行之间存储是否连续, 如果连续,则可:  
    int * ptr = m.ptr<int>(0) //获取矩阵首地址  
    ptr[r*m.rows+c] 访问(r,c)  
4. 成员函数step和data  
    step[0]获取矩阵每一行所占字节数, step[1]获取每一数值所占字节数, data为指向第一个数值的指针, 类型为uchar  
    *((int*) (m.data + r*m.step[0] + c*m.step[1])) //访问int类型矩阵的(r,c)  

注: 矩阵的同一行和一维数组一样存储必连续, 不同行可能连续可能不连续,对于连续的可用方法三访问  
    step[0]不仅可以得出连续矩阵每一行所占字节数, 若行间隔, 间隔字节数也被计入了step[0]内(若有间隔则间隔也是固定的)  
四. 列向量Vec
创建: Vec<Typename _Tp, int _cn> 
成员变量类似Mat, 有cols, rols等
用(), [] 访问
官方别名 typedef Vec<uchar, 3> Vec3b,
        typedef Vec<int, 2> Vec2i,
        typedef Vec<float, 4> Vec4f,
        typedef Vec<double, 3> Vec3d 等等
单通道Mat每一元素为一个数值, 多通道矩阵每一元素为一个Vec
五. 多通道矩阵
1. 元素为Vec, 同样连续存储
2. 访问方式同单通道的4种方式, 例如三通道对应的typename变为Vec3f, Vec3b等等
    例如第四种访问方式:
    Vec3f* ptr = (Vec3f*)(mm.data + r*mm.step[0] + c*mm.step[1]);
    之后取ptr值: *ptr
3. 通道分离
    使用函数split(mat, vector<Mat>)
    先创建一个元素为Mat的vector, 调用split函数把原多通道Mat分离为多个单通道Mat存到vector中
4. 通道合并
    函数原型一: void merge(const Mat * mv, size_t count, OutputArray dst)
        多个单通道矩阵初始化一个矩阵 Mat plane[] = {plane0, plane1, plane2}, 声明一个目标矩阵mat
        merge(plane, 3, mat)
    函数原型二: void merge(InputArrayOfArrays mv, OutputArray dst)
        将单通道矩阵放入mat的vector中, merge(plane, mat)
六. 获取矩阵某一区域的值
1. 某一行: m.row(r), 某一列: m.col(c)
2. 连续行: m.rolRange(start, end), m.rolRange(Range(start, end))
  连续列: m.colRange(start, end), m.colRange(Range(start, end)) 都是左闭右开区间
3. clone和copyTo
  clone: 2的方法仍然指向原矩阵, 末尾加.clone()创建并指向副本
  copyTo同理, matrix.rolRange(start, end).copyTo(r_range)
4. Rect类
  Rect(int_x, int_y, int_width, int_height); 
  Rect(int_x, int_y, Size(int_width, int_height)),  Rect(Point2i&pt1, Size(int_width, int_height)) //即坐标可以int x,y也可以Point, 宽高可以int width,height也可以Size
  Rect(Point2i&pt1, Point2i&pt2) //左上角右下角 注:实测不包括右下角,为左上角到右下角左上一个点的矩形roi,即也是左闭右开
七. 矩阵运算
1. 加法:  法一: OpenCV重载了+号, 适用两种情况, 第一是矩阵+矩阵, 要求同size同类型; 第二是矩阵加数值, 不要求同类型, 会把数值类型转换后加到矩阵每一个元素上
            注: 不会发生溢出情况, 会截断为类型最大值
                Python则不同, 缺点ndarray的加法不会截断, 而是溢出, 这点与C++接口区别
                             优点ndarray有强大的广播能力, 也适用于不同类型相加(取范围大的类型)
                             同时cv2.add函数接口同大部分OpenCV的Python函数一样, 不再在参数中有dst, 而是将dst返回
        法二: add(InputArray src1, InputArray src2, OutputArray dst, InputArray mask=noArray(), int dtype=-1)
            使用add而不是+时候矩阵类型可以不同, 输出类型可以由dtype参数自行指定, 默认参数-1仅适用于同类型时
2. 减法: 与加法同理, 用-或者subtract函数, 注意事项相同, C++截断Python溢出
3. 点乘:  法一: Mat成员函数mul, dst = src1.mul(src2)
        法二: multiply(InputArray src1, InputArray src2, OutputArray dst, double scale=1, int dtype=-1)
        scale为点乘结果基础上乘的系数, dtype同上指定类型, -1同类型
        注: Python的ndarray重载了*表示点乘, 用法同+, -, C++的OpenCV也重载了*但是表示矩阵乘法
4. 点除: OpenCV重载了/, 同时有函数divide, 用法同上
        注:Python的ndarray在uint8类型时除以0得0, 其他情况返回inf
5. 矩阵乘法
        法一: 重载了*, 要求符合矩阵乘法要求, 类型一致, *仅支持同为float或double, 两个双通道矩阵也可相乘, 两通道会被分别当成实部和虚部
        法二: gemm(InputArray src1, InputArray src2, double alpha, InputArray src3, double beta, OutputArray dst, int flags=0)
        alpha为相乘后的系数, beta为src3系数, flags控制了三个矩阵是否转置
        flags=0: alpha*src1*src2 + beta*src3
        flags=GEMM_1_T: alpha*src1的转置*src2 + beta*src3
        flags=GEMM_2_T: alpha*src1*src2的转置 + beta*src3
        flags=GEMM_3_T: alpha*src1*src2 + beta*src3的转置
        不需要src3时候可以用NULL, beta设为0, 即*等价于gemm(src1, src2, 1, NULL, 0, dst, 0)
        Python: np.dot(src1, src2)结果返回
6. 其他运算:
    指数函数exp, 对数函数log(以e为底)函数, 仅支持float和double
    Python的ndarray的exp和log支持任意数值类型,返回各种长度的float
    幂指数函数pow(Python为power), 开平方运算sqrt
    注意截断的问题 
八. 图像灰度化
1. 图像读取imread函数, 第一个参数为文件路径字符串, 第二个参数flags:
    0: IMREAD_GRAYSCALE 灰度图(若是读取的为彩色图会自动灰度化), 1: IMREAD_COLOR BGR图, 默认1, 更多可选参数参考imgcodecs.hpp
2. 显示imshow函数, 第一个参数字符串的窗口名, 第二个要显示的Mat对象
  namedWindow(窗口名, 模式) 可预先创建窗口, imshow同时创建的窗口为不可调的
  模式0: WINDOW_NORMAL大小可调
     1: WINDOW_AUTOSIZE(默认)按图像大小, 不可调
  imshow图像需要配上waitKey(等待毫秒数)才能被观察, 最少1, 0为等待任意键按下
  destroyAllWindows()关闭所有窗口
  OpenCV的彩色转灰度公式 gray = 0.114B + 0.587G + 0.299R

第三章 几何变换

一.仿射变换
仿射变换 = 线性变换 + 平移
非齐次形式 x' = Ax + b 
齐次形式 x' = Ax A(3x3矩阵)左上角为一个二维的线性变换, 最右列上两个元素为平移量, 最下行为(0, 0, 1)
基本仿射变换包括: 平移, 缩放, 旋转
1.平移: 单位阵基础上带两个平移量, 方向同正负
2.放缩: 以原点为中心缩放, 平移量为0, 主对角前两个量分别表x, y轴的放缩, 绝对值大于1放大, 小于1缩小
       以任一点(x0, y0)为中心缩放相当于先将(x0, y0)平移到原点, 再按原点缩放, 再向相反方向平移第一步相同的量, 即三个平移, 原点放缩, 平移矩阵相乘得到变换矩阵
       公式(x', y') = (x0 + Sx(x-x0), y0 + Sy(y-y0))
3.旋转: 以原点为中心的二维齐次旋转阵仅有左上角四个量, 右下角为1, 其余为0; 基本旋转阵是对称阵, 其逆矩阵就是他的转置
       同放缩变换, 以任一点(x0, y0)为中心旋转相当于先将(x0, y0)平移到原点, 再按原点旋转, 再向相反方向平移第一步相同的量, 即三个平移, 原点旋转, 平移矩阵相乘得到变换矩阵
以上可知由基本变换:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCV与图像算法笔记 的相关文章

随机推荐

  • C/C++访问MySQL数据库

    C C 访问MySQL数据库 VS2019配置 打开mysql的安装目录 默认安装目录如下 C Program Files MySQL MySQL Server 8 0 确认 lib 目录和include 目录是否存在 打开VS2019 新
  • 如何将自己的项目jar包打包成docker 镜像

    首先将自己的项目打包成jar 并在自己本地先用java jar xxx jar启动下 看是否可以启动 随后将自己的jar包同级目录创建一个Dockerfile文件 并用notepad打开 文件无后缀 FROM kdvolder jdk8 V
  • linux下手动安装编译的通用步骤

    手动安装编译的通用步骤 在自己的下载目录中 1 在官网下载压缩包 wget xxx 2 解压文件 tar zxf xxx 3 开始编译安装 查看解压的目录下的文件 是config还是autogen之类的 来决定使用 autogen sh还是
  • 如何使用memset函数

    如何使用memset函数 memset用处 memset使用方法 memset用处 memset函数是主要用于初始化字符串的一个函数 也可以用于初始化自定义类型数组 结构体数组和其他类型数组 memset使用方法 memset函数原型如下
  • 机器学习19:反卷积算法

    机器学习19 反卷积算法 转载和整理 在整理全卷积网络的过程中 被反卷积的概念困扰很久 于是将反卷积算法单独整理为一篇博客 本文主要转载和整理自知乎问题如何通俗易懂地解释反卷积 中的高票答案 1 反卷积概述 应用在计算机视觉的深度学习领域
  • java将本地图片复制添加水印并导出到本地

    模板信息 package com example demo ChartGraphics import com sun image codec jpeg JPEGCodec import com sun image codec jpeg JP
  • Mybatis动态公用sql

  • 文件夹自动同步工具

    这是我之前开发的文件夹自动同步工具 主要实现开发机和服务器之间的文件夹同步 项目地址 https github com mike zhang autoSync 问题描述 在windows下修改代码 到服务器上去编译 但每次都要通过winsc
  • JAR 文件揭密

    JAR 文件揭密 探索 JAR 文件格式的强大功能 转载 原文地址 http www ibm com developerworks cn java j jar 简介 大多数 Java 程序员都熟悉对 JAR 文件的基本操作 但是只有少数程序
  • 【c++ 之 多态】

    目录 前言 多态 认识多态 多态的定义与实现 构成多态的条件 虚函数 1 协变 基类与派生类虚函数返回值不同 2 析构函数的重写 c 11 两个虚函数修饰关键字 final override 重载 重写 重定义再理解 抽象类 抽象类的概念
  • 飞书“蒙冤”,还是舆论有噪声?

    飞书遭微信大范围屏蔽 添加好友 共享文档等功能遭禁 初次看到这个消息的时候并没有过于惊讶 毕竟头条系和腾讯的 摩擦 早已是公关圈老生常谈的话题 双方的较量从2017年底至今 已是3年持久战 这次的较量又有些不同 有人大肆渲染飞书在帮助中小企
  • python绘制三维图

    作者 桂 时间 2017 04 27 23 24 55 链接 http www cnblogs com xingshansi p 6777945 html 本文仅仅梳理最基本的绘图方法 一 初始化 假设已经安装了matplotlib工具包
  • Hadoop集群的9870页面,DataNode启动不了的解决办法

    原因 多次格式化hdfs namenode format的操作 配置文件错误或者说修改过master配置没有进行格式化后续操作
  • Android平台GB28181设备接入端如何实时更新经纬度实现国标平台侧电子地图位置标注

    技术背景 我们在做GB28181设备接入端的时候 其中有个功能 不难但非常重要 那就是GB28181实时位置的订阅 mobileposition subscribe 和上报 notify 特别是执法记录仪 智能安全帽 车载终端等场景下 现场
  • mysql show variables sql_mode_MySQL的三种常见sql_mode

    MySQL数据库的中有一个环境变量sql mode 定义了mysql应该支持的sql语法 数据校验等 我们可以通过以下方式查看当前数据库使用的sql mode mysql gt select sql mode sql mode STRICT
  • 投稿指南【NO.12_8】【极易投中】核心期刊投稿(组合机床与自动化加工技术)

    近期有不少同学咨询投稿期刊的问题 大部分院校的研究生都有发学术论文的要求 少部分要求高的甚至需要SCI或者多篇核心期刊论文才可以毕业 但是核心期刊要求论文质量高且审稿周期长 所以本博客梳理一些计算机特别是人工智能相关的期刊 供大家参考投稿
  • 可视化笔记3--matplotlib 常见图形绘制3

    可视化笔记3 matplotlib 常见图形绘制3 接着上一篇博文 继续简单学习了下matplotlib绘图功能 基本包括 图片保存及工具栏使用 区域填充 形状绘制 图形美化 绘制极坐标 绘制积分函数 散点和条形图综合案例 相应学习笔记分享
  • 什么是HIS,以及HIS的作用,特点,组成部分

    什么叫HIS HIS系统定制开发服务 HIS系统作用 HIS系统开发价格 HIS系统的主要组成部分 HIS系统的基本概述 HIS 即Hospital Information System 直译为中文就是医院信息系统利用计算机软硬件技术 网络
  • VSCode搭建STM32开发环境

    废话不多说 直接步入正题 所需软件如下 GNU Arm Embedded Toolchain Mingw w64 make openocd STM32CubeMx VSCode 一 环境篇 1 GNU Arm Embedded Toolch
  • OpenCV与图像算法笔记

    本博客为 OpenCV算法精解 基于Python与C 一书 参阅源代码链接 的阅读笔记 根据理解对书中绝大多数算法做了总结和描述 对Numpy较为熟悉 Python方面仅对与C 不同的注意事项做了标注 书作者整体按照冈萨雷斯的经典教材 数字