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与图像算法笔记 的相关文章

  • 如何在 Windows 窗体中运行屏幕保护程序作为其背景?

    如何在 Windows 窗体中运行屏幕保护程序作为其背景 用户还可以在屏幕保护程序运行时与表单控件进行交互 为什么这个 我们有一个案例 需要在用户时运行 Windows Bubbles 屏幕保护程序 可以继续与表单控件交互吗 您可以使用以下
  • F10键没被抓住

    I have a Windows Form and there overriden ProcessCmdKey However this works with all of the F Keys except for F10 I am tr
  • 将成员函数作为参数传递/c++

    我想用 C 实现一个类b可以通过封装该迭代器类型的成员集进行某种迭代 喜欢 b object for each x do function f so 函数 f会得到每个人的x成员并做任何事情 比方说 void function f x me
  • 特定设备的不同字体大小

    我目前正在开发通用应用程序 我需要分别处理移动设备和桌面的文本框字体大小 我找到了一些方法 但都不能解决问题 使用 VisualStateManager 和 StateTrigger 为例
  • 如何使用泛型类型的 DataContractSerializer 编写自定义序列化器?

    我想编写一个自定义序列化器 用于将会话状态存储到Azure 缓存 预览版 这意味着这个自定义序列化器必须实现IDataCacheObjectSerializer 如果我错了 请告诉我 我需要编写这个自定义序列化程序的原因是我需要序列化一些包
  • 如何从邻接表高效创建稀疏邻接矩阵?

    我正在与last fm http labrosa ee columbia edu millionsong lastfm数据集来自百万歌曲数据集 http labrosa ee columbia edu millionsong 数据以一组 j
  • 将 Django 中的所有视图限制为经过身份验证的用户

    我是 Django 新手 我正在开发一个项目 该项目有一个登录页面作为其索引和一个注册页面 其余页面都必须仅限于登录用户 如果未经身份验证的用户尝试访问这些页面 则必须将他 她重定向到登录页面 我看到 login required装饰器会将
  • C# 中处理 SQL 死锁的模式?

    我正在用 C 编写一个访问 SQL Server 2005 数据库的应用程序 该应用程序是数据库密集型的 即使我尝试优化所有访问 设置适当的索引等 我预计迟早会遇到死锁 我知道为什么会发生数据库死锁 但我怀疑我能否在某个时候发布不发生死锁的
  • 从包含大量文件的目录中检索文件

    我的目录包含近 14 000 000 个 wav 格式的音频样本 所有普通存储 没有子目录 我想循环浏览文件 但是当我使用DirectoryInfo GetFiles 在该文件夹上 整个应用程序冻结了几分钟 可以用另一种方式完成吗 也许读取
  • 类返回语句不打印任何输出

    我正在学习课程 但遇到了问题return语句 它是语句吗 我希望如此 程序什么也没有打印出来 它只是结束而不做任何事情 class className def createName self name self name name def
  • 如何不在类中实现接口的功能?

    面试时面试官问了我以下问题 但我不知道这个问题的答案是什么 请帮忙 如果我不想 我必须做什么 在我的类中实现一个函数 在接口中声明为 由我班实施 Edited 我正在使用 NET 和 C 如果有人可以提供 C 示例代码示例 那就太好了 Th
  • 从给定的项目列表创建子列表

    我首先要说的是以下问题不是为了家庭作业目的即使因为我几个月前就完成了软件工程师的工作 无论如何 今天我正在工作 一位朋友向我询问了这个奇怪的排序问题 我有一个包含 1000 行的列表 每行代表一个数字 我想创建 10 个子列表 每个子列表都
  • AWS 将 MQTT 消息存储到 DynamoDB

    我构建了一个定期发送 MQTT 消息的 python 脚本 这是发送到后端的 JSON 字符串 Id 1234 Ut 1488395951 Temp 22 86 Rh 48 24 在后端 我想将 MQTT 消息存储到 DynamoDB 表中
  • Dynamics Crm:获取状态代码/状态代码映射的元数据

    在 Dynamics CRM 2011 中 在事件实体上 状态原因 选项集 也称为状态代码 与 状态 选项集 也称为状态代码 相关 例如看这个截图 当我使用 API 检索状态原因选项集时 如下所示 RetrieveAttributeRequ
  • 将 bignum 类型结构转换为人类可读字符串的有效方法是什么?

    我有一点问题 为了增长我的 C 知识 我决定尝试实现一个基本的 bigint 库 bigint 结构的核心将是一个 32 位整数数组 选择它们是因为它们适合寄存器 这将允许我在数字之间进行操作 这些操作将在 64 位整数中溢出 这也将适合寄
  • 为什么C语言中可以使用多个分号?

    在 C 中我可以执行以下操作 int main printf HELLO WORLD 它有效 这是为什么 我个人的想法 分号是一个 NO OPERATION 来自维基百科 指示符 拥有一大串分号与拥有一个分号并告诉 C 语句已结束具有相同的
  • 在 SQL Server 上执行分页的最佳方式是什么?

    我有一个数据库超过200万记录 我需要执行分页以在我的 Web 应用程序上显示 该应用程序每页必须有 10 条记录DataGrid 我已经尝试使用ROW NUMBER 但是这种方式会选择所有 200 万条记录 然后只得到 10 条记录 我也
  • 为什么 C# 接口名称前面加上“I”

    这种命名约定背后的基本原理是什么 我没有看到任何好处 额外的前缀只会污染 API 我的想法与康拉德一致response https stackoverflow com a 222502 9898与此相关的question https sta
  • 正在获取“未终止 [] 设置”。 C# 中的错误

    我正在 C 中使用以下正则表达式 Regex find new Regex url
  • 在何处将 CFLAG(例如 -std=gnu99)添加到 (Eclipse CDT) 自动工具项目中

    我有一个简单的 Autotools C 项目 不是 C 其框架是由 Eclipse CDT Juno 为我创建的 CFLAG 通过检查 似乎是 g O2 我希望所有生成的 make 文件也具有 std gnu99附加到 CFLAG 因为我使

随机推荐

  • 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 不同的注意事项做了标注 书作者整体按照冈萨雷斯的经典教材 数字