matlab数字图像处理——直方图均衡重现老照片

任务 在课堂上学习了直方图均衡化的处理手段,看到外国女子的脸部增亮,这是在空域中实现变换增强的方法之一。尝试在matlab中实现相关方法,并用网上的老照片进行实验,效果不错。 过程 得到灰度图的直方图 灰度图的获取可以参考博文matlab数字图像处理——RGB转灰度图,当然也可以直接调用系统函数rgb2gray() 直方图其实是统计不同灰度等级的像素点数目大小,并通过除以图像像素点总数目,得到归一化结果/概率。 得到累积直方图 因为需要对灰度等级进行映射——把某个阶段的灰度值对应到均衡的结果,那么我们需要取得中间变量:累积直方图。 得到映射关系 映射关系可以利用matlab的矩阵运算实现,直接将表达式中的变量用矩阵替换即可。分别表述这行代码中变量的含义: cRecord:上一部分得到的累积直方图 256:总共的灰度等级 -1是因为在matlab中,uint8的范围在0~255 mapValue: 索引值继承等号右边唯一的矩阵——cRecord的含义,是每个灰度等级 内部的值表示通过运算映射得到新的灰度等级 根据新的映射关系修改原图的灰度值 这一步的目的比较清晰,已经通过上一步得到了映射关系,只要将原图中的灰度等级修改为映射后对应的灰度等级即可。 问题与解决方法 残影 整个过程比较顺利,只是第一次显示直方图时有些奇怪: 结果图P5只能隐约看到lena的轮廓,通过显示该图像的变量类型找到答案,变量并非图像的uint8类型,而是double类型。问题出在初始化变量上,我利用zeros()函数,当我把赋值改为强制类型转换后,问题解决。 class(newImg) ans = ‘double’ 结果展示 参考资料 如何提取特定位置以后的字符串(出处: MATLAB中文论坛) MATLAB中画柱状图

matlab实现FFT(快速傅里叶变换)

任务 接上篇,尝试使用快速傅里叶变换实现空域到频域转换 过程 判定2的幂次 由算法可知,对于长度为2的幂次的序列可以进行变换,但对于大多数情况非2的幂次应该如何解决?答案是补零至2的幂次。 判定 简单的判定方法,利用2的幂次(M)在二进制中的独特性,首位为1,余位为0;且减1后(M-1)原首位为0,余位为1,则有M&M-1=0 matlab中的按位与函数为bitand(),与&不同  bitshift(num,n); num表示需要移位的数,十进制; n为正左移,负右移。 求大于一个数字的二进制的最高位 思路,通过移位,当非2次幂数的第i位移出使原数为0,则最高位为i。可以将2次幂数-1转换为相同情况。 函数实现 首先强制类型转换,转换为固定的uint8类型。 matlab没有三目运算符,则用if…else语句实现。将特殊情况0单独列出, 调用临近最高位的求取函数highestOneSite(M) 位的对换 算法实现需要将输入数据排列为满足算法需要的次序,可以推导发现,满足的映射规则为第x个数为x的二进制数颠倒后的结果。 a是0~255的整数 b=dec2bin(a,8);%b是8位’0′,’1’字符串 h=b(1:4); %高四位 l=b(5:8); %低四位 MATLAB中怎么将一个常数(0到255)转为8位二进制数–dukinkin  但在matlab中,由于数组下标从1开始,需要进行-1的操作进行映射 即F(abcd)《-》f(dcba) bottom-up实现 足足思索了几个小时,终于捋清x点变换的逻辑。 指数部分函数W表示 其中W可视为函数: matlab代码为: 首先从一维开始理解,由于需要变换的矩阵长度已经过判定2的幂次并补零至最邻近的2的幂次(N=2^n),则可通过不断奇偶二分,从原始的N点变换,分解为两个N/2点变换,再到N/4点变换、……、8点变换、4点变换、2点变换。最后的1点变换,因为公式(1)中u为0,则指数项为0,即1点变换视为原值。 上面的思路确定了如何从需要变换的函数得到分解因子,本次实现通过从因子逐层自底向上推出。重点在于清楚公式中的分子的表示,以及在存储矩阵中的位置。 二维实现 利用matlab实现DFT(离散傅里叶变换)与优化 的读取图像和灰度图转换,得到了灰度图像grayImg 再利用之前的频移函数showShiftImg(twoD)得到频移到中心点的图像。 matlab技巧——如何利用其他文件夹下的函数 addpath D:\Matlab即可使用路径D:\Matlab下的函数 结果展示 ans = 442 785 3 时间已过 17.532276 秒。 现在运行给定图像需要的时间实际为17.5s,相比于优化后的DFT的12s居然不降反升,所以要想达到更有效的应用,需要继续优化。 参考文章 《图像工程 (上)<图像处理和分析>》… Continue reading matlab实现FFT(快速傅里叶变换)

matlab实现DFT(离散傅里叶变换)与优化

任务 《数字图像处理》课程布置: 编写程序(建议Matlab )对某选定图像(自行转换为灰度图)展开傅里叶变换,提取傅里叶变换图像(将频率原点移至图像中心) , 并形成实验报告。 为与matlab中代码一致,便于理解,此处的公式我全部整理为数组从下标1开始。此外,增强特殊性,图像大小为NxM 基本知识 此前尝试用matlab实现傅里叶变换,用基本公式对方波函数进行傅氏变换。但其特点: 函数连续(在matlab进行抽样离散处理,绘制波形) 范围趋近无限(在matlab中把n取大值范围) 可见,对于模拟值用计算机进行傅氏变换需要首先进行离散处理,那么对于本身是离散值的数字图像,则直接利用离散傅里叶变换即可。 这里图像大小为NxM 前面括号内的系数其实可舍去,主要起到归一化的作用,因此形式不必纠结。 首先,将二重变换利用傅氏变换的性质可以分解为两次单重变换: 与公式相一致:本人代码先按行遍历,对列(y表示)变换;再按列遍历,对行(x表示)变换 过程 读取图像 测试图片选取经典上图,但大小是压缩的200×200,因此对于初次使用比较友好。 matlab中句末引号可选,不加则会输出左值结果至命令行窗口,如上述代码的size(Img) 转换为灰度图 通过在读取的图像信息判断是否为单通道,是则直接使用,否则将RGB图像通过转换函数rgb2gray()转换为灰度图。 三重循环实现 可以通过tic,toc放在代码前后进行时长测试 注意u和v的范围是从0开始取值 ans = 200 200 3 时间已过 12.674382 秒。 频移函数 这里直接显示经过处理后的傅氏变换的图像 核心是将原图四个角点移至中心位置,可以通过matlab中矩阵处理的语法便捷实现 由于非偶数会出现不能被2整除情况,因此需要做取整处理 优化 使用上述算法经过讨论,复杂度为O(N^3),并且在处理更大尺寸的图像(老师提供785×442)时,运行时间极长。 因为了解到matlab对矩阵运算具有高效快速优点,便把思考放在如何将算法通过矩阵运算实现。 思路同样是通过两个一维变换完成,因此只以分析按行遍历,对列(y)展开为例,对思路进行陈述。 观察到公式中的基函数部分其实已经固定,因此直接通过相乘获得某个频率分量(Vn)对应的不同y值得出(某个频率分量)所有计算需要的指数部分,如下所示: 共N列 下一步将图像信息与对应的分量对应相乘,得到,那么加和则是对每行相加——每一行的x保持不变。最终得到一维转换后的结果: 具体代码 时间已过 16.837070 秒。 此用时与分钟相比下降很多,但比较系统中的fft(),用时约为0.1s,因此下一步可以思考如何进行快速傅里叶变换的使用。 参考资料 Matlab-结构体数组的索引 matlab里的图像处理函数

Matlab计算传感器静态特征参数

任务 对于《传感器检测与技术》中第二章的数据计算题目,需要对系列数据进行处理,可以利用Matlab中的矩阵运算和相关函数快速实现。下面以一道例题进行分析,并最后附上最小二乘法求取拟合直线的相关代码。 题目 设有压力传感器的校准数据列于下表,试求 (1)端基拟合直线; (2)端基线性度; (3)滞环误差; (4)重复性误差(λ=3); (5)准确度。 解答 端基拟合直线 端基拟合是求取传感器线性度的拟合直线中一种,顾名思义,是直接连接输入/输出曲线两端点以得到拟合直线。 但由于题目中提供测量的多组数据,故需要取平均值: 输出: 则两端点分别为(0.0,0.0031)与(5.0,0.9995),相应得出拟合直线Y=A0+KX中的参数值: A0=0.0031 K=(0.9995-0.0031)/(5.0-0.0) 端基线性度 线性度则是通过定义公式进行求取,即实际输入/输出曲线与拟合直线的最大偏差ΔYm与满刻度输出值Yfs的比值,由于题目仅提供散点,则只需选取散点的最大偏差进行计算。 滞环误差 计算正、反行程差距最大偏差与最大输出与满刻度输出值之比 重复性误差 通过贝塞尔公式求取标准差,可以通过matlab中的std()函数实现。 准确度 将上述得到的线性度σL、滞环误差σH与重复性误差σR代入公式即可。 最小二乘法 参考资料 MATLAB中矩阵各列求和,各行求和,所有元素求和 概率统计:MATLAB计算标准差和方差 std 贝塞尔公式与标准偏差

Django-发送邮件找回密码

任务 完善登录模块,提供找回密码的途径。 具体逻辑为: 输入用户名和注册邮箱 数据库比对一致后,随机生成验证码 利用Django的邮件发送模块发送验证码 验证码通过后,能够重置密码 用户名和注册邮箱 关键在于利用标签id筛选到输入内容,并且需要加入{% csrf_token %}生成密钥,传入ajax作为参数,否则会出现403无法响应。 访问网址:https://paas-class.bktencent.com/t/demoli/mechat/find_pwd/ 前端发送输入用户名与邮箱 得到输入框中内容 如用户名部分为: 选择器为: 按钮事件触发 需要实现通过点击按钮发送验证码向填写的邮箱地址发送邮件,对按钮部分添加get_verify属性,一直监听按钮按下,并引入倒计时: 当按钮按下,且按钮文字为获取验证码时,此时点击按钮则会触发js中的submit_verify()函数 同步检验输入有效性 为了得到Ajax请求验证有效性函数的返回值,需要通过同步ajax实现,声明async: false, 利用POST请求将用户名与邮件地址传送至后端进行处理,其中的请求路径url利用相对路径格式书写,便于之后上传服务器。 后端检验用户名和邮箱有效性 在url.py中新增路由映射关系 在views.py中新增处理模块submit_verify() 取出POST中数据:username=request.POST.get(‘username’) 查询表baseUser一对一的表User中是否存在输入的用户名:usernameF = baseUser.objects.filter(user__username=username) 验证通过 发送邮件,开始倒计时,传入后端进行验证码生成与邮件的发送,并显示输入验证码框 异步发送验证邮件 但发送邮件是消耗时间的活动,因此一定要用异步Ajax实现,验证通过时调用函数send_verify() 随机生成验证码 后端发送验证邮件 在url.py中新增路由映射关系 在views.py中新增处理模块send_verify() 生成验证码 generateVcode(request) 前端处理返回数据res 完善send_verify()异步请求 在输入框下面加上span成员,如下 将错误信息打印到相应位置 清除错误信息 利用Django的邮件发送模块发送验证码 首先参考博文Django——发送邮件的步骤通过QQ邮箱完成测试,下面介绍类比如何通过学校邮箱进行发送: 首先在网页中搜索关键词华科邮箱+SMTP,找到相关说明 二、客户端设置 使用Outlook、Foxmail等桌面邮件客户端软件或手机邮件客户端软件设置学校电子邮箱时按如下配置信息设置: SMTP服务器:mail.hust.edu.cn POP3服务器:mail.hust.edu.cn IMAP服务器:mail.hust.edu.cn 在settings.py文件中加入设定: 同样需要配置路由映射到函数send_mail():… Continue reading Django-发送邮件找回密码

Django-登录

计划完成一款帮助学习计划管理的小程序,实现其中的登录功能
难点:由于采用蓝鲸的开发平台,其中的登录模块已经经过设定,需要进行重建。

Published
Categorized as SaaS Tagged

SLAM学习-应用齐次坐标实现矩形平移

任务 了解齐次坐标在三维空间的优势,以及在计算机图形学中的应用后,进行实战练习:利用键盘读取方向输入,控制矩形平移,其中矩形的坐标以齐次坐标形式表达. 齐次坐标 优势 便于表达某点是否在直线上 表达直线和直线交点,平面和平面交线 区分向量和点 能表示无穷远 欧式变换中的旋转和平移:由加法到乘法 注意问题 旋转和平移先后顺序有区别 经过了坐标变换之后: 缩放变换不改变坐标轴的走向,也不改变原点的位置,所以两个坐标系仍然重合。 旋转变换改变坐标轴的走向,但不改变原点的位置,所以两个坐标系坐标轴不再处于相同走向。 平移变换不改变坐标轴走向,但改变原点位置,两个坐标系原点不再重合。 坐标变换的顺序必须是: 缩放->旋转->平移 实际演练 完整代码 实现效果 参考文章 从零开始一起学习SLAM | 为什么要用齐次坐标? 齐次坐标的理解 2D Translation in Computer Graphics | Definition | Examples Eigen学习(六)高级初始化 【OpenCv】cvWaitKey获取键盘值 OpenCV doc of waitKey()

SLAM学习-C++新特性

任务 请使用C++新特性改写以下函数。该函数功能:将一组无序的坐标按照“Z”字形排序,并输出。 本程序学习目标:熟悉C++新特性(简化循环、自动类型推导、列表初始化、lambda函数) 题目来源: 从零开始一起学习SLAM | C++新特性要不要学? sort()函数 定义在 algorithm 头文件中的函数模板 sort() 默认会将元素段排成升序 对[first,second)之间的元素进行排序,需要能提供随机访问迭代器的容器如vector,array, deque等.如果提供comp比较器函数,便可根据该函数的要求排序. comp/cmp 可以直接通过<algorithm>中提供的equal_to<Type>、not_equal_to<Type>、greater<Type>、greater_equal<Type>、less<Type>、less_equal<Type>库函数实现不同方式 的排序. 也可以通过自定义cmp()实现非基本数据类型的比较方式定义,如下面例子所示,实现: 首先比较第一位大小,小者在前 若第一位相同,再比较第二位 完整代码 结果展示 优化 参考博文C++排序函数中cmp()比较函数详解 思考:int 和const int&有什么区别呢?原来:作为函数参数:int这种写法是值传递,const int&则是引用传递。“值传递”——由于函数将自动产生临时变量用于复制该参数,效率较低。“引用传递”仅借用一下参数的别名而已,不需要产生临时对象。效率较高。tips:“引用传递”有可能改变参数,const修饰可以解决这个问题。 可以在cmp()的定义处采用引用传递,即: 参考文章 C++ sort(STL sort)排序算法详解 sort-C++ reference c++sort函数的使用总结 C++排序函数中cmp()比较函数详解