H.264,同时也是 MPEG-4 第十部分,是由ITU-T 视频编码专家组(VCEG)和ISO/IEC动态图像专家组(MPEG)联合组成的联合视频组(JVT,Joint Video Team)提出的高度压缩数字视频编解码器标准。这个标准通常被称之为H.264/AVC(或者AVC/H.264或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC)而明确的说明它两方面的开发者。H.264是在MPEG-4技术的基础之上建立起来的,其编解码流程主要包括5个部分:帧间和 帧内预测 (Estimation)、变换(Transform)和反变换、量化(Quantization)和反量化、环路滤波(Loop Filter)、 熵编码 (Entropy Coding)。
更高的编码效率:同H.263等标准的特率效率相比,能够平均节省大于50%的码率。
高质量的视频画面:H.264能够在低码率情况下提供高质量的视频图像,在较低带宽上提供高质量的图像传输是H.264的应用亮点。
提高网络适应能力:H.264可以工作在实时通信应用(如视频会议)低延时模式下,也可以工作在没有延时的视频存储或视频流服务器中。
采用混合编码结构:同H.263相同,H.264也使用采用DCT变换编码加DPCM的差分编码的混合编码结构,还增加了如多模式运动估计、帧内预测、多帧预测、基于内容的变长编码、4x4二维整数变换等新的编码方式,提高了编码效率。
H.264的编码选项较少:在H.263中编码时往往需要设置相当多选项,增加了编码的难度,而H.264做到了力求简洁的“回归基本”,降低了编码时复杂度。
H.264可以应用在不同场合:H.264可以根据不同的环境使用不同的传输和播放速率,并且提供了丰富的错误处理工具,可以很好的控制或消除丢包和误码。
错误恢复功能:H.264提供了解决网络传输包丢失的问题的工具,适用于在高误码率传输的无线网络中传输视频数据。
较高的复杂度:264性能的改进是以增加复杂性为代价而获得的。据估计,H.264编码的计算复杂度大约相当于H.263的3倍,解码复杂度大约相当于H.263的2倍。
H264功能分为两层:VCL(视频编码层)和 NAL(网络提取层)。
VCL数据传输或者存储之前,会被映射到一个NALU中,H264数据包含一个个NALU。如下图:
一个NALU = 一组对应于视频编码的NALU头部信息 + 一个原始字节序列负荷(RBSP,Raw Byte Sequence Payload)。
一个原始的NALU单元结构如下 [StartCode][NALU Header][NALU Payload]三部分。
StartCode,是一个NALU单元开始,必须是00 00 00 01 或者00 00 01。
头信息协议如上图。
例如: 1 00 00 00 01 06: SEI信息
2 00 00 00 01 67: 0x67&0x1f = 0x07 :SPS
3 00 00 00 01 68: 0x68&0x1f = 0x08 :PPS
4 00 00 00 01 65: 0x65&0x1f = 0x05: IDR Slice
下面是RBSP序列的描述:
H264压缩技术主要采用了以下几种方法对视频数据进行压缩。包括:
帧内预测压缩,解决的是空域数据冗余问题。
帧间预测压缩(运动估计与补偿),解决的是时域数据冗徐问题。
下面我们就来详细描述一下H264压缩技术。
H264的基本原理其实非常简单,下我们就简单的描述一下H264压缩数据的过程。通过摄像头采集到的视频帧(按每秒 30 帧算),被送到 H264 编码器的缓冲区中。编码器先要为每一幅图片划分宏块。 以下面这张图为例:
H264默认是使用 16X16 大小的区域作为一个宏块,也可以划分成 8X8 大小。
划分好宏块后,计算宏块的象素值。
以此类推,计算一幅图像中每个宏块的像素值,所有宏块都处理完后如下面的样子。
H264对比较平坦的图像使用 16X16 大小的宏块。但为了更高的压缩率,还可以在 16X16 的宏块上更划分出更小的子块。子块的大小可以是 8X16、 16X8、 8X8、 4X8、 8X4、 4X4非常的灵活。
上幅图中,红框内的 16X16 宏块中大部分是蓝色背景,而三只鹰的部分图像被划在了该宏块内,为了更好的处理三只鹰的部分图像,H264就在 16X16 的宏块内又划分出了多个子块。
这样再经过帧内压缩,可以得到更高效的数据。下图是分别使用mpeg-2和H264对上面宏块进行压缩后的结果。其中左半部分为MPEG-2子块划分后压缩的结果,右半部分为H264的子块划压缩后的结果,可以看出H264的划分方法更具优势。
宏块划分好后,就可以对H264编码器缓存中的所有图片进行分组了。
对于视频数据主要有两类数据冗余,一类是时间上的数据冗余,另一类是空间上的数据冗余。其中时间上的数据冗余是最大的。下面我们就先来说说视频数据时间上的冗余问题。
为什么说时间上的冗余是最大的呢?假设摄像头每秒抓取30帧,这30帧的数据大部分情况下都是相关联的。也有可能不止30帧的的数据,可能几十帧,上百帧的数据都是关联特别密切的。
对于这些关联特别密切的帧,其实我们只需要保存一帧的数据,其它帧都可以通过这一帧再按某种规则预测出来,所以说视频数据在时间上的冗余是最多的。
为了达到相关帧通过预测的方法来压缩数据,就需要将视频帧进行分组。那么如何判定某些帧关系密切,可以划为一组呢?我们来看一下例子,下面是捕获的一组运动的台球的视频帧,台球从右上角滚到了左下角。
H264编码器会按顺序,每次取出两幅相邻的帧进行宏块比较,计算两帧的相似度。如下图:
通过宏块扫描与宏块搜索可以发现这两个帧的关联度是非常高的。进而发现这一组帧的关联度都是非常高的。因此,上面这几帧就可以划分为一组。其算法是:在相邻几幅图像画面中,一般有差别的像素只有10%以内的点,亮度差值变化不超过2%,而色度差值的变化只有1%以内,我们认为这样的图可以分到一组。
在这样一组帧中,经过编码后,我们只保留第一帖的完整数据,其它帧都通过参考上一帧计算出来。我们称第一帧为IDR/I帧,其它帧我们称为P/B帧,这样编码后的数据帧组我们称为GOP。
在H264编码器中将帧分组后,就要计算帧组内物体的运动矢量了。还以上面运动的台球视频帧为例,我们来看一下它是如何计算运动矢量的。 H264编码器首先按顺序从缓冲区头部取出两帧视频数据,然后进行宏块扫描。当发现其中一幅图片中有物体时,就在另一幅图的邻近位置(搜索窗口中)进行搜索。如果此时在另一幅图中找到该物体,那么就可以计算出物体的运动矢量了。下面这幅图就是搜索后的台球移动的位置。
通过上图中台球位置相差,就可以计算出台图运行的方向和距离。H264依次把每一帧中球移动的距离和方向都记录下来就成了下面的样子。
运动矢量计算出来后,将相同部分(也就是绿色部分)减去,就得到了补偿数据。我们最终只需要将补偿数据进行压缩保存,以后在解码时就可以恢复原图了。压缩补偿后的数据只需要记录很少的一点数据。如下所示:
我们把运动矢量与补偿称为帧间压缩技术,它解决的是视频帧在时间上的数据冗余。除了帧间压缩,帧内也要进行数据压缩,帧内数据压缩解决的是空间上的数据冗余。下面我们就来介绍一下帧内压缩技术。
人眼对图象都有一个识别度,对低频的亮度很敏感,对高频的亮度不太敏感。所以基于一些研究,可以将一幅图像中人眼不敏感的数据去除掉。这样就提出了帧内预测技术。
H264的帧内压缩与JPEG很相似。一幅图像被划分好宏块后,对每个宏块可以进行 9 种模式的预测。找出与原图最接近的一种预测模式。
下面这幅图是对整幅图中的每个宏块进行预测的过程。
帧内预测后的图像与原始图像的对比如下:
然后,将原始图像与帧内预测后的图像相减得残差值。
再将我们之前得到的预测模式信息一起保存起来,这样我们就可以在解码时恢复原图了。效果如下:
经过帧内与帧间的压缩后,虽然数据有大幅减少,但还有优化的空间。
可以将残差数据做整数离散余弦变换,去掉数据的相关性,进一步压缩数据。如下图所示,左侧为原数据的宏块,右侧为计算出的残差数据的宏块。
将残差数据宏块数字化后如下图所示:
将残差数据宏块进行 DCT 转换。
去掉相关联的数据后,我们可以看出数据被进一步压缩了。
做完 DCT 后,还不够,还要进行 CABAC 进行无损压缩。
上面的帧内压缩是属于有损压缩技术。也就是说图像被压缩后,无法完全复原。而CABAC属于无损压缩技术。
无损压缩技术大家最熟悉的可能就是哈夫曼编码了,给高频的词一个短码,给低频词一个长码从而达到数据压缩的目的。MPEG-2中使用的VLC就是这种算法,我们以 A-Z 作为例子,A属于高频数据,Z属于低频数据。看看它是如何做的。
CABAC也是给高频数据短码,给低频数据长码。同时还会根据上下文相关性进行压缩,这种方式又比VLC高效很多。其效果如下:
现在将 A-Z 换成视频帧,它就成了下面的样子。
从上面这张图中明显可以看出采用 CACBA 的无损压缩方案要比 VLC 高效的多。
@本地磁盘姬
ohayou.aimo.moe
微博:@本地磁盘姬碟酱
Twitter:本地磁盘姬改二
知乎:本地磁盘姬
2021年10月12日
]]>Qt得益于信号和槽的抽象概念,使得在此利用OpenCV实现图像处理并不困难。只需要简单的初始化,就可以使用它了。
首先在Qt项目的.pro文件下添加语句导入OpenCV库:
1 2 3 4 5 |
|
接着声明三个基本槽:
1 2 3 |
|
最后编写基本代码段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
至此就可以开始编写你程序的其它功能了。
https://github.com/MoeDisk/OpenCV_Qt_Learn/tree/master/Pic_Contrast_Brightness
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
imgSrc.convertTo(imgDst,-1,con,bri);:
OpenCV增强图片使用的是点算子,即用常数对每个像素点执行乘法和加法的复合运算:g(i,j)=af(i,j)+b。
式中,f(i,j)代表一个原图的像素点;a是增益参数,控制图片对比度;b是偏值参数,控制图片亮度;而g(i,j)则表示经处理后的对应像素点。这两个参数分别对应程序中的变量con和bri,执行时将它们的值传入OpenCV的convertTo()方法,在其内部就会对图片上的每个点均匀用上式的算法进行处理变换。
https://github.com/MoeDisk/OpenCV_Qt_Learn/tree/master/Pic_Blur_Gaussian_Median_Bilateral_1
均值滤波:
1 2 3 |
|
高斯滤波:
1 2 3 |
|
中值滤波:
1 2 3 |
|
双边滤波:
1 2 3 |
|
https://github.com/MoeDisk/OpenCV_Qt_Learn/tree/master/Pic_Zoom_Rotate_1
1 2 3 4 5 6 7 8 9 10 11 12 |
|
该方法接收两个参数,皆为单精度实型,ang表示旋转角度(正为顺时针、负为逆时针),sca表示缩放率(大于1为放大、小于1为缩小)。
imgRot=getRotationMatrix2D(centerPoint,ang,sca);:
OpenCV内部用仿射变换算法来实现图片的旋转缩放。它需要三个参数:
(1)旋转图片所要围绕的中心;
(2)旋转的角度,在OpenCV中逆时针角度为正值,反之为负值;
(3)缩放因子(可选),在本例中分别对应centerPoint、ang和sca参数值。
任何一个仿射变换都能表示为向量乘以一个矩阵(线性变换)再加上另一个向量(平移),研究表明,不论是对图片的旋转还是缩放操作,本质上都是对其每个像素施加了某种线性变换,如果不考虑平移,实际上也就是一个仿射变换。因此,变换的关键在于求出变换矩阵,这个矩阵实际上代表了变换前后两张图片之间的关系。这里用OpenCV的getRotationMatrix2D()方法来获得旋转矩阵,然后通过warpAffine()方法将获得的矩阵用到对图片的旋转缩放操作中。
https://github.com/MoeDisk/OpenCV_Qt_Learn/tree/master/Pic_FaceRecognition_1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
eyes_detector.load(eDetectorPath);:
load()方法用于加载一个XML分类器文件,OpenCV既支持Haar特征算法也支持LBP特征算法的分类器。
]]>libmpv功能强大使用简单灵活,因为这个项目涵盖惹目前一般播放器的所有优点(内置ffmpeg解码器、支援ass字幕、支援本地和在线资源解码、支援硬件解码等..),基于它二次开发你只需要封装它的通用处理接口,就能轻松实现使用这些功能,并且还是跨平台的。
这是一些基于libmpv开发的播放器:https://github.com/mpv-player/mpv/wiki/Applications-using-mpv%E3%80%82
mpv官方提供惹一个基于qt的demo,但官方的例子是将界面和类封装在一起惹,可供参考:https://github.com/confidentFeng/QtAppProject/tree/mpvDemo%E3%80%82
->mpv_create,创建实例。
->mpv_set_option,设置播放句柄。
->mpv_set_property,设置属性。
->mpv_set_option,设置参数。
->mpv_initialize,初始化实例。
->mpv_command_async,拉流。
->mpv_terminate_destroy,释放实例。
你可以基于如下官方提供的手册来为它添加其他功能。
@本地磁盘姬
ohayou.aimo.moe
微博:@本地磁盘姬碟酱
Twitter:本地磁盘姬
知乎:本地磁盘姬
2020年09月28日
]]>
函数类别和名称 |
描述 |
节号 |
图像显示和探索 |
|
|
ice(DIPUM) |
交互彩色编辑器 |
5.4 |
immovie |
由多帧图像组成的电影 |
|
implay |
播放电影、视频或图像序列 |
6.6.1 |
imshow |
以处理图形的方式显示图像 |
|
imtool |
以图像工具的方式显示图像 |
|
montage |
以矩形蒙太奇显示多帧图像 |
6.6.1 |
Rgbcube(DIPUM) |
在MATLAB桌面上显示一个RGB立方体 |
5.1.1 |
subimage |
以单幅图形方式显示多幅图像 |
|
warp |
像纹理映射表面那样显示图像 |
|
图像文件I/O |
|
|
Analyze75info |
从MayoAnalyze7.5数据集的头文件中读取元数据 |
|
Analyze75read |
从MayoAnalyze7.5数据集的头文件中读取图像文件 |
|
dicomanon |
匿名DICOM文件 |
|
dicomdict |
得到或设置激活的DICOM数据字典 |
|
dicominfo |
从DICOM消息中读取元数据 |
|
dicomlookup |
在DICOM数据字典中查找属性 |
|
dicomread |
读取DICOM图像 |
|
dicomuid |
生成DICOM唯一标识符 |
|
dicomwrite |
将图像文件写为DICOM文件 |
|
hdrread |
读取RadianceHDR图像 |
|
hdrwrite |
写RadianceHDR图像 |
|
makehdr |
创建高动态范围图像 |
|
interfileinfo |
从归档文件中读取元数据 |
|
interfileread |
从归档文件中读取图像 |
|
isnitf |
检查文件是否是NITF |
|
Movie2tifs(DIPUM) |
从MATLAB电影创建一个多帧TIFF文件 |
6.6.1 |
nitfinfo |
从NITF文件中读取元数据 |
|
nitfread |
读取NITF文件 |
|
Seq2tifs(DIPUM) |
从MATLAB序列创建一个多帧TIFF文件 |
6.6.1 |
Tifs2movie(DIPUM) |
从多帧TIFF文件中创建一部MATLAB电影 |
6.6.1 |
Tifs2seq(DIPUM) |
从多帧TIFF文件中创建一个MATLAB序列 |
6.6.1 |
图像算数 |
|
|
imabsdiff |
两幅图像的绝对差 |
|
imcomplement |
图像求补 |
5.2.5 |
imlincomb |
图像的线性组合 |
|
ippl |
检查IntelPerformacePrimitivesLibrary(IPPL)是否存在 |
|
几何变换 |
|
|
checkerboard |
创建棋盘图像 |
4.5 |
findbounds |
为空间变换寻找输出边界 |
|
fliptform |
转换TFORM结构的输入和输出 |
|
imcrop |
裁剪图像 |
|
impyramid |
以金字塔形时所建和扩展图像 |
|
imresize |
调整图像大小 |
|
imrotate |
旋转图像 |
8.4.3 |
imtransform |
对图像施以二维空间变换 |
|
Imtransform2(DIPUM) |
固定输出位置的二维图像变换 |
8.4.3 |
makeresampler |
创建重取样结构 |
|
maketform |
创建空间变换结构(TFORM) |
|
Pixeldup(DIPUM) |
在两个方向复制图像像素 |
4.5 |
Pointgrid(DIPUN) |
排列在网格上的点 |
|
Reprotate(DIPUN) |
重复旋转图像 |
|
tformarray |
对N维阵列施以空间变换 |
|
tformfwd |
应用正向空间变换 |
|
tforminv |
应用反向空间变换 |
|
Vistform(DIPUN) |
点集的可视化变换效果 |
|
图像配准 |
|
|
Cpstruct2pairs |
把CPSTRUCT转换为控制点对 |
|
Cp2tform |
由控制点对推断空间变换 |
|
cpcorr |
用互相关调整控制点位置 |
|
cpselect |
控制点选取工具 |
|
Normxcorr2 |
归一化二维互相关 |
|
Visreg(DIPUM) |
视觉上配准图像 |
|
像素值和统计 |
|
|
Corr2 |
二维相关系数 |
|
imcontour |
创建图像数据的轮廓图 |
|
imhist |
显示图像数据的直方图 |
2.3.1 |
impixel |
像素彩色值 |
|
improfile |
沿着线段剖面的像素值 |
|
Localmean(DIPUM) |
计算局部均值数组 |
2.3.6 |
Mean2 |
矩阵元素的平均或均值 |
2.2.4 |
regionprops |
度量图像区域(团块分析) |
7.3.6 |
Statmoments(DIPUM) |
计算图像直方图的统计中心矩 |
4.2.4 |
Std2 |
矩阵元素的标准差 |
|
图像分析 |
|
|
Bound2eight(DIPUM) |
把4连接边界转换为8连接边界 |
8.1.3 |
Bound2four(DIPUM) |
把8连接边界转换为4连接边界 |
8.1.3 |
Bound2im(DIPUM) |
把一个边界转换为一幅图像 |
8.1.1 |
Bound2samp(DIPUM) |
对边界进行子采样 |
8.1.3 |
Bwboundaries(DIPUM) |
追踪二值图像中的区域边界 |
8.1.1 |
Bwtraceboundary |
追踪二值图像中的物体 |
|
Colorgrad(DIPUM) |
计算RGB图像的向量梯度 |
5.6.1 |
Colorseg(DIPUM) |
执行彩色图像的分割 |
5.6.2 |
Connectpoly(DIPUM) |
连接多边形顶点 |
8.1.3 |
cornermetric |
由图像创建拐角度量矩阵 |
8.3.5 |
Cornerprocess(DIPUM) |
处理函数cornermetric的输出 |
8.3.1 |
Diameter(DIPUM) |
度量图像区域的直径和相关属性 |
7.1.3 |
edge |
寻找灰度图像的边缘 |
7.1.3 |
Fchcode(DIPUM) |
计算边界的弗雷曼链码 |
8.3.3 |
Frdescp(DIPUM) |
计算傅里叶描绘子 |
8.3.3 |
Ifredscp(DIPUM) |
计算反傅里叶描绘子 |
8.3.3 |
Im2minperpoly(DIPUM) |
最小周长多边形 |
8.2.2 |
Imstack2vectors(DIPUM) |
从图像堆栈提取向量 |
8.5 |
Invmoments(DIPUM) |
计算图像的不变矩 |
8.4.3 |
hough |
霍夫变换 |
7.2.2 |
houghlines |
基于霍夫变换的线段提取 |
7.2.2 |
houghpeaks |
识别霍夫曼变换的峰值 |
7.2.2 |
Localthresh(DIPUM) |
局部阈值处理 |
7.3.6 |
Mahalanobis(DIPUM) |
计算Mahalanobis距离 |
5.6.2 |
Movingthresh(DIPUM) |
使用移动平均阈值的图像分割 |
7.3.7 |
Otsuthresh(DIPUM) |
给定直方图的Otsu最佳阈值 |
7.3.3 |
Principalcomps(DIPUM) |
主分量向量和相关量 |
8.5 |
qtdecomp |
4叉树分解 |
7.4.3 |
qtgetblk |
得到4叉树分解中的块值 |
7.4.3 |
qtsetblk |
设置4叉树分解中的块值 |
|
Regiongrow(DIPUM) |
用区域生长方法实现分割 |
7.4.2 |
Signature(DIPUM) |
计算边界的标记 |
8.2.3 |
Specxture(DIPUM) |
计算图像的频谱纹理 |
8.4.2 |
Splitmerge(DIPUM) |
用分离与聚合算法分割图像 |
7.4.3 |
Statxture(DIPUM) |
计算一幅图像中纹理的统计测度 |
8.4.2 |
X2majoraxis(DIPUM) |
将坐标x与区域的长轴对齐 |
8.3.3 |
图像压缩 |
|
|
Compare(DIPUM) |
计算和显示两个矩阵的误差 |
6.1 |
Cv2tifs(DIPUM) |
对TIFS2CV压缩图像序列解码 |
6.6.2 |
Huff2mat(DIPUM) |
对霍夫曼编码矩阵解码 |
6.2.3 |
Huffman(DIPUM) |
对一个符号源建立变长霍夫曼编码 |
6.2.1 |
Im2jpeg(DIPUM) |
用JPEG近似压缩一幅图像 |
6.5.1 |
Im2jpeg2k(DIPUM) |
用JPEG2000近似压缩一幅图像 |
6.5.2 |
Imratio(DIPUM) |
计算两幅图像/变量的字节比率 |
6.1 |
Jpeg2im(DIPUM) |
对IM2JPEG压缩图像编码 |
6.5.1 |
Jpeg2k2im(DIPUM) |
对IM2JPEG2K压缩编码图像 |
6.5.2 |
1pc2mat(DIPUM) |
解压缩无损预测编码矩阵 |
6.3 |
Mat2huff(DIPUM) |
对一个矩阵进行霍夫曼编码 |
6.2.2 |
Mat21pc(DIPUM) |
用一维有损预测编码压缩一个矩阵 |
6.3 |
Ntrop(DIPUM) |
计算矩阵的熵的一阶估计 |
6.2 |
Quantize(DIPUM) |
量化uint8类矩阵的元素 |
6.4 |
Showmo(DIPUM) |
显示一个压缩图像的运动向量 |
6.6.2 |
Tifs2cv(DIPUM) |
压缩多帧TIFF图像序列 |
6.6.2 |
Unravel(DIPUM) |
对一个边长比特流解码 |
6.2.3 |
图像去模糊 |
|
|
deconvblind |
用盲去卷积对图像去模糊 |
4.8 |
deconvlucy |
用Lucy-Richardson方法对图像去模糊 |
|
deconvreg |
用正则滤波器对图像去模糊 |
|
deconvwnr |
用维纳滤波器对图像去模糊 |
4.7 |
edgetaper |
用点扩散函数渐变边缘 |
4.7 |
Otf2psf |
把光传递函数转换为点扩散函数 |
|
Psf2otf |
把点扩散函数转换为光传递函数 |
|
图像增强 |
|
|
adapthisteq |
有限对比度的自适应直方图均衡(CLAHE) |
2.3.4 |
Adpmedian(DIPUM) |
直性子适应中值滤波 |
4.3.2 |
decorrstretch |
用去相关拉伸多通道图像 |
|
Gscale(DIPUM) |
标定输入图像的灰度 |
2.2.4 |
histeq |
用直方图均衡增强对比度 |
2.3.2 |
imadjust |
调整图像灰度值或彩色图 |
2.2.1 |
Medfilt2 |
二维中值滤波 |
|
Ordfilt2 |
二位统计排序滤波 |
2.5.2 |
stretchlim |
寻找对比度拉伸一幅图像的极限 |
2.2.2 |
intlut |
用查找表转换整数值 |
|
Intrans(DIPUM) |
执行灰度(灰度级)变换 |
2.2.4 |
Wiener2 |
二位自适应去噪滤波 |
|
图像噪声 |
|
|
imnoise |
对图像添加噪声 |
4.2.1 |
Imnoise2(DIPUM) |
用指定的PDF生成一个随机数阵列 |
4.2.2 |
Imnoise3(DIPUM) |
产生周期噪声 |
4.2.3 |
线性滤波 |
|
|
Convmtx2 |
二维卷积矩阵 |
|
Dftfilt(DIPUM) |
执行频率域滤波 |
3.3.3 |
fspecial |
创建预定义的二维滤波器 |
2.5 |
imfilter |
多维图像的N维滤波 |
2.4.1 |
Spfilt(DIPUM) |
执行线性和非线性空间滤波 |
4.3 |
线性二维滤波器设计 |
|
|
Bandfilter(DIPUM) |
计算频率域带通滤波器 |
3.6.2 |
Cnotch(DIPUM) |
产生循环对称馅波滤波器 |
|
Freqz2 |
二维频率响应 |
3.4 |
Fsamp2 |
使用频率取样的二维FIR滤波器 |
|
Ftrans2 |
使用频率变换的二维FIR滤波器 |
|
Fwind1 |
使用一维开窗方法的二维FIR滤波器 |
|
Fwind2 |
使用二维开窗方法的二维FIR滤波器 |
|
Hpfilter(DIPUM) |
计算频率域高通滤波器 |
3.6.1 |
Lpfilter(DIPUM) |
计算频率域低通滤波器 |
4.2.3,5.3.2 |
Recnotch(DIPUM) |
产生矩形馅波(轴)滤波器 |
|
模糊逻辑 |
|
|
Aggfcn(DIPUM) |
模糊系统的归并函数 |
|
Approxfcn(DIPUM) |
近似函数 |
|
Bellmf(DIPUM) |
钟形隶属度函数 |
|
Defuzzify(DIPUM) |
模糊系统的输出 |
|
Fuzzfilt(DIPUM) |
模糊边缘检测器 |
|
Fuzzysysfcn(DIPUM) |
模糊系统函数 |
|
Implfcns(DIPUM) |
模糊系统的隐含函数 |
|
Lambdafcns(DIPUM) |
模糊规则集的Lambda函数 |
|
Makrefuzzyedgesys(DIPUM) |
生成FUZZYFILT所用MAT文件的脚本 |
|
Onemf(DIPUM) |
常数隶属度函数(1) |
|
Sigmamf(DIPUM) |
Sigma隶属度函数 |
|
Smf(DIPUM) |
S形隶属度函数 |
|
Trapezmf(DIPUM) |
梯形隶属度函数 |
|
Triangmf(DIPUM) |
三角形隶属度函数 |
|
Truncgaussmf(DIPUM) |
高斯截短的隶属度函数 |
|
Zeromf(DIPUM) |
常用隶属度函数 |
|
图像变换 |
|
|
Dct2 |
二维离散余弦变换 |
|
dctmtx |
离散余弦变换矩阵 |
|
Fan2para |
把扇形射束投影转换为平行射束 |
4.8.8 |
fanbeam |
扇形射束变换 |
4.8.8 |
Idct2 |
二维离散余弦反变换 |
|
ifanbeam |
反扇形射束变换 |
4.8.8 |
iradon |
反雷登变换 |
4.8.7 |
Para2fan |
把平行射束投影转换为扇形射束 |
4.8.8 |
phantom |
创建头部幻影图像 |
4.8.6 |
radon |
雷登变换 |
4.8.6 |
邻域和块处理 |
|
|
bestblk |
块处理的最佳尺寸 |
|
blkproc |
对图像的不同块处理 |
6.5.1 |
Col2im |
把矩阵列重拍为块 |
6.5.1 |
clofilt |
逐列邻域操作 |
2.4.2 |
Im2cool |
把图像块重排为列 |
6.5.1 |
nlfilter |
普通邻域滑动操作 |
|
形态学操作(灰度和二值图像) |
|
|
conndef |
默认的连接性数组 |
|
imbothat |
底帽滤波 |
|
imclearborder |
抑制连接到图像边框的明亮结构 |
|
imclose |
形态学图像闭操作 |
|
imdilate |
膨胀图像 |
|
imerode |
腐蚀图像 |
|
imextendedmax |
最大扩展变换 |
|
imextendmin |
最小扩展变换 |
|
imfill |
填充图像区域和孔洞 |
7.5.3 |
imhmax |
最大H变换 |
8.1.2 |
imhmin |
最小H变换 |
|
imimposemin |
强迫最小 |
7.5.3 |
imopen |
形态学图像开操作 |
|
imreconstruct |
形态学重建 |
|
imregionalmax |
区域最大 |
|
imregionalmin |
区域最小 |
7.5.3 |
imtophat |
顶帽滤波 |
|
watershed |
分水岭变换 |
7.5.1 |
形态学图像(二值图像) |
|
|
applylut |
用查找表的邻域操作 |
|
bwarea |
二值图像的的物体的面积 |
|
bwareaopen |
二值图像的形态学开操作(删除小物体) |
7.5.1 |
bwdist |
二值图像的距离变换 |
|
bweuler |
二值图像的欧拉数 |
|
bwhitmiss |
二值击中-击不中操作 |
|
bwlabel |
在二维二值图像中标记连接分量 |
|
bwlabeln |
在N维二值图像中标记连接分量 |
|
bwmorph |
对二值图像上的形态学操作 |
|
bwpack |
打包二值图像 |
8.1.1 |
bwperim |
求二值图像中物体的周长 |
|
bwselect |
选取二值图像中的物体 |
|
bwulterode |
最终腐蚀 |
|
bwunpack |
拆包二值图像 |
|
Endpoints(DIPUM) |
计算二值图像的端点 |
|
makelut |
创建APPLYUT所用的查找表 |
|
结构元(STREL)创建和操作 |
|
|
getheight |
得到STREL的高度 |
|
getneighbords |
得到STREL邻居的偏移位置和高度 |
|
getnhood |
得到STREL的邻域 |
|
getsequence |
得到分解的STREL的序列 |
|
isflat |
对平坦的STREL为真 |
|
reflect |
关于其中心反射STREL |
|
strel |
创建形态学结构元(STREL) |
|
translate |
平移STREL |
|
纹理分析 |
|
|
entropy |
灰度图像的熵 |
|
entropyfilt |
灰度图像的局部熵 |
|
graycomatrix |
创建灰度级共生矩阵 |
8.4.2 |
graycoprops |
灰度级共生矩阵的特性 |
8.4.2 |
rangefilt |
图像的局部范围 |
|
Specxture(DIPUM) |
计算图像的谱原理 |
8.4.2 |
Statxture(DIPUM) |
计算图像中的纹理统计测度 |
8.4.2 |
stdfilt |
图像的局部标准差 |
7.3.6 |
基于区域的处理 |
|
|
Histroi(DIPUM) |
计算一幅图像中ROI(感兴趣区域)的直方图 |
4.2.4 |
Poly2mask |
把感兴趣区域多边形转换为模板 |
|
roicolor |
基于颜色选取感兴趣区域 |
|
roifill |
填充灰度图像中的指定区域 |
|
Roifill2 |
对感兴趣区域滤波 |
|
roipoly |
选择感兴趣多边形区域 |
4.2.4 |
小波 |
|
|
Appcoef2 |
提取二维近似系数 |
|
Detcoef2 |
提取二维细节系数 |
|
dwtmode |
离散小波变换扩展模式 |
|
Waveback(DIPUM) |
计算多级分解的反快速小波变换 |
|
Wavecopy(DIPUM) |
提取小波分解结构的系数 |
|
Wavecut(DIPUM) |
小波分解结构的迫零系数 |
|
Wavedec2 |
多级二维小波分解 |
|
Wavedisplay(DIPUM) |
显示小波分解系数 |
|
Wavefast(DIPUM) |
计算"三维扩展的"二维数组的快速小波变换 |
|
Wavefilter(DIPUM) |
创建小波分解和重建滤波器 |
|
wavefun |
一维小波和尺度函数 |
|
waveinfo |
小波信息 |
|
Waverec2 |
多级二维小波重建 |
|
Wavework(DIPUM) |
用于编辑小波分解的结构 |
|
Wavezero(DIPUM) |
小波变换的迫零细节系数 |
|
wfilters |
小波滤波器 |
|
Wthcoef2 |
二维小波系数阈值处理 |
|
颜色映射操作 |
|
|
cmpermute |
在颜色映射中重新安排颜色 |
|
cmunique |
在索引图像的颜色映射中去除不需要的颜色 |
|
imapprox |
用较少颜色的一种图像来近似索引图像 |
5.1.2 |
彩色空间转换 |
|
|
applycform |
应用设备无关彩色空间变换 |
5.2.6 |
Hsi2rgb(DIPUM) |
把HSI图像转换为RGB图像 |
5.2.5 |
iccfind |
使用描述搜索ICC剖面 |
|
iccread |
读取ICC彩色剖面 |
5.2.6 |
iccroot |
寻找系统ICC剖面容器 |
|
iccwrite |
写ICC彩色剖面 |
|
isicc |
对完整的剖面结构为真 |
|
Lab2double |
把Lab彩色值转换为double型 |
|
Lab2uint16 |
把Lab彩色值转换为uint16型 |
|
Lab2uint8 |
把Lab彩色值转换为uint8型 |
|
makecform |
创建设备无关彩色空间变换结构(CFORM) |
5.2.6 |
Ntsc2rgb |
把NTSC彩色值转换到RGB彩色空间 |
5.2.2 |
Rgb2hsi(DIPUM) |
把RGB图像转换为HSI图像 |
5.2.5 |
Rgb2ntsc |
把RGB彩色值转换到NTSC彩色空间 |
5.2.2 |
Rgb2ycbcr |
把RGB彩色值转换到YCbCr彩色空间 |
5.2.2 |
whitepoint |
标准照明的XYZ彩色值 |
|
Xyz2double |
把XYZ彩色值转换为double型 |
|
Xyz2uint16 |
把XYZ彩色值转换为uint16型 |
|
Ycbcr2rgb |
把YCbCr彩色值转换到rgb彩色空间 |
5.2.2 |
阵列操作 |
|
|
Dftuv(DIPUM) |
计算网络频率矩阵 |
3.5.1 |
padarray |
填充数组 |
2.4.2 |
Paddedsize(DIPUM) |
针对基于FFT的滤波计算填充的有效尺寸 |
3.3.1 |
图像类型和类型转换 |
|
|
demosaic |
把Bayer模式的编码图像转换为真彩色图像 |
|
dither |
用抖动转换图像 |
5.1.3 |
Gray2ind |
把灰度图像转换为索引图像 |
5.1.3 |
grayslice |
通过阈值处理从灰度图像创建索引图像 |
5.1.3 |
graythresh |
使用Otsu方法的全局图像阈值处理 |
7.3.3 |
Im2bw |
通过阈值处理把图像转换为二值图像 |
|
Im2double |
把图像转换为双精度 |
|
Im2int16 |
把图像转换为16比特带符号整数 |
|
Im2java2d |
把图像转换为java缓存图像 |
|
Im2single |
把图像转换为单精度 |
|
Im2uint8 |
把图像转换为8比特无符号整数 |
|
Im2uint16 |
把图像转换为16比特无符号整数 |
|
Ind2gray |
把索引图像转换为灰度图像 |
5.1.3 |
Label2rgb |
把标记矩阵转换为RGB图像 |
|
Mat2gray |
把矩阵转换为灰度图像 |
|
Rgb2gray |
把RGB图像或彩色图转换为灰度图像 |
5.1.3 |
Rgb2ind |
把RGB图像转换为索引图像 |
5.1.3 |
Tofloat(DIPUM) |
把图像转换为浮点数 |
|
tonemap |
为观看目的渲染高动态范围图像 |
|
工具箱优先权 |
|
|
iptgetpref |
得到图像处理工具箱优先权 |
|
iptsetpref |
设置图像处理工具箱优先权 |
|
工具箱实用函数 |
|
|
getrangefromclass |
得到基于图像类的图像动态范围 |
|
intline |
绘制整数坐标线 |
8.2.1 |
iptcheckconn |
检查连接性参数的有效性 |
|
iptcheckinput |
检查数组的有效性 |
|
iptcheckmap |
检查颜色映射的有效性 |
|
iptchecknargin |
检查输入参量的数量 |
|
iptcheckstrs |
检查文本字符串的有效性 |
|
Iptnum2ordinal |
把正整数转换为序数字符串 |
|
组件式的交互工具 |
|
|
imageinfo |
图像信息工具 |
|
imcontrast |
调整对比度的工具 |
|
imdisplayrange |
显示范围的工具 |
|
imdistline |
可拖动的距离工具 |
|
imgetfile |
打开图像对话框 |
|
impixelinfo |
像素信息工具 |
|
impixelinfoval |
无文本标记的图像信息工具 |
|
impixelregion |
像素区域工具 |
|
impixelregionpanel |
像素区域工具面板 |
|
imputfile |
保存图像对话框 |
|
imsave |
保存图像工具 |
|
图像滚动面板的导航工具 |
|
|
imscrollpanel |
用于交互式图像导航的滚动面板 |
|
immagbox |
滚动面板的放大框 |
|
imoverview |
在滚动面板中显示图像的纵览工具 |
|
imoverviewpanel |
在滚动面板中显示图像的纵览工具面板 |
|
针对交互式工具的实用函数 |
|
|
Axes2pix |
把轴坐标转换为像素坐标 |
|
getimage |
从轴得到图像数据 |
|
getimagemodel |
从图像目标的得到图像模型目标 |
|
imagemodel |
图像模型目标 |
|
imattributes |
关于图像属性的信息 |
|
imhandles |
得到所有图像的句柄 |
|
imgca |
得到包含图像的当前轴句柄 |
|
imgcf |
得到包含图像的当前图形的句柄 |
|
imellipse |
创建可拖动、可调尺寸的椭圆 |
|
imfreehand |
创建可拖动的手绘区域 |
|
imline |
创建可拖动、可调尺寸的直线 |
|
impoint |
创建可拖动的点 |
|
impoly |
创建可拖动、可调尺寸的多变形 |
|
imrect |
创建可拖动、可调尺寸的矩形 |
|
iptaddcallback |
将函数句柄添加到回调列表 |
|
iptcheckhandle |
检查句柄的有效性 |
|
iptgetapi |
得到句柄的应用程序接口 |
|
iptGetPointerBehavior |
在HG对象中恢复指针行为 |
|
ipticondir |
包含IPT和MATLAB图标的目录 |
|
iptPointerManager |
在图形中安装鼠标指针管理器 |
|
iptremovecallback |
从回调列表中删除函数句柄 |
|
iptSetPointerBehavior |
在HG对象中存储指针行为 |
|
iptwindowalign |
对齐图形窗口 |
|
makeConstrainToRectFcn |
创建矩形游街位置约束函数 |
|
truesize |
调整图像的显示尺寸 |
|
交互式鼠标实用函数 |
|
|
getline |
用鼠标选择折线 |
|
getpts |
用鼠标选择点 |
|
getrect |
用鼠标选择矩形 |
|
辅助函数 |
|
|
Conwaylaws(DIPUM) |
对单个像素应用Conway遗传法则 |
|
I2percentitle(DIPUM) |
计算给定灰度值的百分数 |
7.3.5 |
Iseven(DIPUM) |
确定阵列中哪些元素是偶数 |
|
Isodd(DIPUM) |
确定阵列中哪些元素是奇数 |
|
Manualhist(DIPUM) |
交互式地产生双模式直方图 |
2.3.3 |
Timeit(DIPUM) |
度量运行函数所需的时间 |
|
Percentile2i(DIPUM) |
计算给定百分位的灰度值 |
7.3.5 |
Tofloat(DIPUM) |
把输入转换为单精度浮点数 |
|
Twomodegauss(DIPUM) |
生成一个双模式高斯函数 |
2.3.3 |
@本地磁盘姬
ohayou.aimo.moe
微博:@本地磁盘姬碟酱
Twitter:本地磁盘姬改二
知乎:本地磁盘姬
2020年09月28日
]]>本篇(1)为大家介绍:vector、set、string、map、queue。
容器(Containers):
用来管理某一类对象的集合。C++ 提供了各种不同类型的容器,比如 deque、list、vector、map 等。
算法(Algorithms):
算法是作用于容器的。它们提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作。
迭代器(iterators):
用于遍历对象集合的元素。这些集合可能是容器,也可能是容器的子集。
vector是可变长数组,顾名思义,它是那种长度可以根据需要而自动改变的数组。它可以避免普通数组可能会超内存的问题,而且它还可以用来以邻接表方式存储图,免去惹使用指针实现邻接表比较麻烦的烦恼。
1 2 |
|
1 2 |
|
和一维数组一样,这里的typename可以是任何基本类型(如int、double、char、结构体等),也可以是STL的标准容器(如vector、set、queue等)。不过需要注意的是,如果是STL标准容器的话定义的时候要记得在>>符号之间加上空格。因为一些使用C++11之前标准的编译器会把它视为移位操作。例如:
1 2 3 4 |
|
1 2 |
|
(1)通过下标访问: 和访问普通数组一样,例如:
1 2 |
|
下标为从0到vi.size()-1。
(2)通过迭代器访问:
迭代器可以理解为一种类似指针的东西:
1
|
|
这样it就是一个迭代器变量,typename就是定义vector时填写的类型:
1
|
|
这样就得到了迭代器it,并且可以通过*it来访问vector里的数组。 例如有这样一个vector容器:
1 2 3 |
|
可以通过类似下标和指针访问数组的方式来访问容器内的元素:
1 2 3 4 |
|
输出结果:1 2 3 4 5 从这里看出vi[i]和*(vi.begin()+i)是等价的。
begin()函数的作用是去vi首元素的地址,end()函数是取尾元素地址的下一个地址。end()作为迭代器末尾标准,不存储任何元素。
除此之外,迭代器还实现了两种自加自减操作:
1 2 |
|
于是有了另一种遍历vector中元素的写法:
1 2 3 |
|
最后需要指出,在常用STL容器中,只有在vector和string中,才允许使用vi.begin()+3这种迭代器加上整数的写法。
(1)push_back(): 顾名思义,push_back(x)就是在vector后面添加一个元素x,时间复杂度为O(1)。
1
|
|
(2)pop_back(): pop_back()用以删除vector的尾元素,时间复杂度为O(1)。
1
|
|
(3)size(): size()用来获得vector中元素的数组,时间复杂度为O(1)。size()返回的是unsigned类型,不过一般来说用%d不会出很大的问题,这一点对所有STL容器都是一样的。
1
|
|
(4)clear(): clear()用来清空vector中的所有数组,时间复杂度为O(N),其中N为vector中元素的个数。
1
|
|
(5)insert(): insert(it,x)用来向vector的任意迭代器it处插入一个元素x,时间复杂度O(N)。
1
|
|
(6)erase(): erase()有两种用法:删除单个元素、删除一个区间内所有有元素。时间复杂度为O(N)。
1 2 |
|
1 2 |
|
set是一个内部自动有序且不含重复元素的容器。加入set后可以实现去掉重复元素,还可以用set来保留元素本身而不考虑它的个数。所谓关联容器就是通过键(key)来读取和修改元素。与map关联容器不同,它只是单纯键的集合。
1 2 |
|
1 2 |
|
1 2 3 4 5 |
|
1 2 3 4 5 6 7 8 9 10 |
|
(1)insert(): insert(x)可将x插入set容器中,并自动递增排序和去重,时间复杂度O(logN),其中N为set内的元素个数。
(2)find(): find(value)返回set中对应值为value的迭代器,时间复杂度O(logN),N为set内的元素个数。
1
|
|
(3)eraser():
1 2 3 4 |
|
1 2 3 |
|
(4)size(): size()用来获得set内元素个数,时间复杂度O(1)。
1
|
|
(5)clear: clear()用来清空set内所有元素,复杂度O(N)。
1
|
|
C++相对于C在STL中加入惹string类型,对字符串常用的需求功能进行了封装,是的操作起来更方便,且不易出错。
1 2 |
|
1 2 |
|
(1)通过下标访问:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
(2)通过迭代器访问:
1 2 3 4 5 6 7 |
|
(1)operator+=: 这是string的加法,可以讲两个string拼接起来。
1 2 3 |
|
(2)computer operation: 两个string类型可以直接用==、!=、<、<=、>、>=比较大小,比较规则是字典序。
1 2 3 |
|
(3)length()/size(): length()返回string长度,即存放字符数,时间复杂度O(1)。size()与length()基本相同。
1 2 |
|
(4)insert():
1 2 3 4 5 |
|
(5)eraser:
1 2 3 |
|
1 2 3 4 5 6 |
|
(6)clear: clear()用以清空string中的数据,时间复杂度一般为O(1)。
1
|
|
(7)substr(): substr(pos,len)返回从pos号位开始、长度为len的字串,时间复杂度为O(len)。
1 2 3 |
|
(8)string::npos: string::npos是一个常数,其本身的值为-1,但由于是unsigned_int类型,因此实际上也可以认为是unsigned_int类型的最大值。string::npos用以作为find函数失配时的返回值。
1 2 3 4 5 6 |
|
(9)find: str.find(str2),当str2是str的子串时,返回其在str中第一次出现的位置;如果str2不是str的子串,那么返回string::npos。
str.find(str2,pos),从str2的pos号位开始匹配str2,返回值与上相同。时间复杂度为O(nm)。
1 2 3 |
|
(10)replace(): str.replace(pos,len,str2)把str从pos号位开始、长度为len的子串替换为str2。 str.replace(it1,it2,str2)把str的迭代器[it1,it2)范围的子串替换为str2。时间复杂度O(str.length())。
1
|
|
map翻译为映射。在定义数组时,其实是定义了一个从int型到int型的映射。一个double型数组则是将int型映射到double型。无论是什么类型,它总是将int型映射到其他类型。当需要以其它类型作为关键字来做映射时,会显得不太方便。但通过map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器),也就可以建立string型到int型的映射。
1 2 |
|
1 2 3 4 |
|
(1)通过下标访问:
1 2 |
|
(2)通过迭代器访问:
1 2 3 4 5 |
|
map会以键从小到大的顺序自动排序,这是由于map内部是使用红黑树实现的(set也是)。
(1)find(); find(key)返回键为key的映射的迭代器,时间复杂度为O(logN)。
1 2 |
|
(2)eraser():
1 2 3 4 5 |
|
1 2 3 4 5 |
|
(3)size(): size()用来获得map中映射的对数,时间复杂度为O(1)。
1 2 |
|
(4)clear(): clear()用来清空map中所有的元素,复杂度为O(N)。
1 2 |
|
queue翻译为队列,是一个先进先出的容器。
1 2 |
|
1 2 |
|
由于queue是一种先进先出的限制性数据结构,因此在STL中只能通过front()访问队首元素,或通过back()访问队尾元素:
1 2 3 4 5 |
|
(1)push: push(x)将x进行入队,时间复杂度为O(1)。
1
|
|
(2)front()、back(): 两者可以分别获得队首元素和队尾元素,时间复杂度为O(1)。
1
|
|
(3)pop(): pop()令队首元素出队,时间复杂度为O(1)。
1 2 3 |
|
(4)empty(): empty()检测queue是否为空,返回true则空,返回false则非空。时间复杂度为O(1)。
1 2 3 4 |
|
(5)size: size()返回queue内元素的个数,时间复杂度为O(1)。
1
|
|
@本地磁盘姬
ohayou.aimo.moe
微博:@本地磁盘姬碟酱
Twitter:本地磁盘姬改二
知乎:本地磁盘姬
2020年07月13日
]]>1
|
|
档案选择对话框(uigetfile):
1 2 |
|
1 2 3 4 |
|
路径选择对话框(uigetdir):
1 2 |
|
错误对话框(errordlg):
1
|
|
警告对话框(warndlg):
1
|
|
提问选择对话框(questdlg):
1 2 3 4 5 6 7 8 9 10 |
|
1 2 3 4 |
|
输入对话框(inputdlg):
1
|
|
@本地磁盘姬
ohayou.aimo.moe
微博:@本地磁盘姬碟酱
Twitter:本地磁盘姬碟酱
知乎:本地磁盘姬
2020年04月27日
]]>一个失败移动操作系统的前世今生,别了FirefoxOS:https://www.sohu.com/a/128781438_355140
FFOS设备使用和开发网站推荐
比较推荐Mozilla官方的MDN:
B2G OS - Archive of obsolete content(中)
https://developer.mozilla.org/zh-CN/docs/Archive/B2G_OS
Firefox OS架构 - Archive of obsolete content | MDN(中)
B2G OS - Archive of obsolete content | MDN(英)
https://developer.mozilla.org/en-US/docs/Archive/B2G_OS
关于应用开发比较推荐CSDN上一些老文章。刷机的话请移步XDA社区的FireFoxOS板块。
如果你正在使用它,推荐可以搜索下Mini123这个网站,上面的应用或站点均基于Web,并且基本上FFOS都可以用。
后面有时间的话我也会写一些文章什么的。比如架构解析、应用开发、还有适配FFOS的Web应用之类的。
关于ZTE的OpenC开发:https://konstakang.com/devices/kis3/
LG的Fx0粉丝站:http://fx0.hellco.net/
How to install packaged apps in Firefox OS:https://hacks.mozilla.org/2013/03/how-to-install-packaged-apps-in-firefox-os-options-and-tools/
通过NodeJS调试安装FirefoxOS的APPS:https://soledadpenades.com/posts/2015/install-to-adb-installing-packaged-firefox-os-apps-to-usb-connected-phones-using-adb/
目前FFOS的应用商店已经完全关张了,您也可以尝试自己写应用或者下载别人的源码编译安装到系统。
开发环境搭建
FFOS的开发环境是内置于大概Firefox的30-50这区间的版本的(正好是12年到16年的浏览器版本),也就是说它的开发环境是完全基于firefox浏览器的。因此您可以在Windows、Linux或Mac上进行FFOS应用开发。您可以搜索firefox的官方ftp上找到nightly版本下载。我是基于较老的37.0版本进行开发的。
Directory Listing: /pub/firefox/nightly/
http://ftp.mozilla.org/pub/firefox/nightly/
1)首先选择一个版本,下载解压并打开。
2)如果您需要虚拟机的话,可以安装一个浏览器插件,这个插件包含了FFOS的虚拟机,您可以随时启动它调试您的程序。
Firefox OS模拟器(Firefox OS Simulator)下载 v2.1官方正式版–pc6下载站
http://www.pc6.com/softview/SoftView_110007.html
3)在安装插件之前,您最好关闭插件签名:
打开firefox,在地址栏中输入about:config并回车;
找到xpinstall.signatures.required,并右击选择“切换”,改成false即可;
4)安装好插件后,地址栏输入about:app-manger,再将开发工具中的WebIDE打开,即可进入FFOS的IDE。
在此,您需要在浏览器下方找到虚拟管理,启动插件实例或者下载一个实例。
注意:ADB Helper是必须的,请务必安装。
联动实体设备或虚拟机
虚拟机比较方便,默认端口应该是9000,直接启动实例就会自动完成连接。
在WebIDE上书写程序。您可以新建项目,里面会有HelloWorld的模板,直接编译后运行即可测试看看。
FFOS的软件布局相当简单,基本上是基于web网页的应用,可以动手试一试。
FFOS的调试是基于ADB(就是安卓adb)的,如何安装ADB这里就不赘述了。
请将FFOS设备中开发者设置中的远程调试打开。通过USB或同一网wifi连接后,驱动可以直接使用android的adb驱动。和传统安卓操作一样,您可以直接命令adb devices查看到您的ffos设备,或adb shell等直接远程命令调试。
连接成功后,方可通过firefox的webide等进行连接。选择远程调试即可,端口号就是你adb连接的端口号。
FFOS的设备在锁屏状态下调试会自动关闭,建议保持设备一直不会被锁定。
你开发后的应用下放到FFOS里会被下放到Gaia层安装到系统中。
更多有趣的玩法等我网课结束后有时间玩B2G再和大家分享//
@本地磁盘姬
ohayou.aimo.moe
微博:@本地磁盘姬碟酱
Twitter:本地磁盘姬碟酱
知乎:本地磁盘姬
2020年02月27日
]]>原来因为一直挺喜欢网易的慕课网所以就一直有在留意。
关于绘画的话,一直很喜欢这个课程。
前年的时候发现的,做惹一堆笔记随时练习,但最近图床比较蛋疼..
漫画入门东北大学中国大学MOOC(慕课)
https://www.icourse163.org/course/NEU-1002922017
建议有素描基础的朋友看一下w。它是把人物或场景等细化,然后再讲细化后各部分的技巧和基本知识。
比如头部,常见头部形状比例、找发际线位置、三庭五眼、转头画法等等讲的比较详细。
是业余人员福利!
人体-透视-色彩 加油。
@本地磁盘姬
ohayou.aimo.moe
微博:@本地磁盘姬碟酱
Twitter:本地磁盘姬碟酱
知乎:本地磁盘姬
2020年02月13日
]]>OpenCV
安装OpenCV4环境:
1
|
|
官方源的OpenCV一直在保持更新!当然你也可以自己找源码makeinstall下。
查询OpenCV4环境位置:
1
|
|
在Qt的pro文件中引用OpenCV4库:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
|
FFmpeg
官网下载源码解压,然后make下:
1 2 3 |
|
查询ffmpeg位置:
1
|
|
在Qt的pro文件中引用ffmpeg库:
1 2 3 4 5 6 7 8 9 10 |
|
SDL
安装SDL环境:
1
|
|
查询SDL环境位置:
1
|
|
在Qt的pro文件中引用ffmpeg库:
1 2 3 4 5 |
|
新建Qt控制台,写好引用,测试下都能跑就好惹。
详细配置可以自己酌情动态调整!!
@本地磁盘姬
ohayou.aimo.moe
微博:@本地磁盘姬碟酱
Twitter:本地磁盘姬碟酱
知乎:本地磁盘姬
2020年02月13日
]]>https://www.cnblogs.com/god-of-death/p/7852394.html
此微博,引发了朋友们的大量讨论:赞同者有之;批评者有之;当然,更多的朋友,是希望我能更详细的解读C/C++ Volatile关键词,来佐证我的微博观点。而这,正是我写这篇博文的初衷:本文,将详细分析C/C++ Volatile关键词的功能 (有多种功能)、Volatile关键词在多线程编程中存在的问题、Volatile关键词与编译器/CPU的关系、C/C++ Volatile与Java Volatile的区别,以及Volatile关键词的起源,希望对大家更好的理解、使用C/C++ Volatile,有所帮助。
Volatile,词典上的解释为:易失的;易变的;易挥发的。那么用这个关键词修饰的C/C++变量,应该也能够体现出”易变”的特征。大部分人认识Volatile,也是从这个特征出发,而这也是本文揭秘的C/C++ Volatile的第一个特征。
Volatile:易变的
在介绍C/C++ Volatile关键词的”易变”性前,先让我们看看以下的两个代码片段,以及他们对应的汇编指令 (以下用例的汇编代码,均为VS 2008编译出来的Release版本):
测试用例一:非Volatile变量
b = a + 1;这条语句,对应的汇编指令是:lea ecx, [eax + 1]。由于变量a,在前一条语句a = fn©执行时,被缓存在了寄存器eax中,因此b = a + 1;语句,可以直接使用仍旧在寄存器eax中的a,来进行计算,对应的也就是汇编:[eax + 1]。
测试用例二:Volatile变量
与测试用例一唯一的不同之处,是变量a被设置为volatile属性,一个小小的变化,带来的是汇编代码上很大的变化。a = fn©执行后,寄存器ecx中的a,被写回内存:mov dword ptr [esp+0Ch], ecx。然后,在执行b = a + 1;语句时,变量a有重新被从内存中读取出来:mov eax, dword ptr [esp + 0Ch],而不再直接使用寄存器ecx中的内容。
小结
从以上的两个用例,就可以看出C/C++ Volatile关键词的第一个特性:易变性。所谓的易变性,在汇编层面反映出来,就是两条语句,下一条语句不会直接使用上一条语句对应的volatile变量的寄存器内容,而是重新从内存中读取。volatile的这个特性,相信也是大部分朋友所了解的特性。
在了解了C/C++ Volatile关键词的”易变”特性之后,再让我们接着继续来剖析Volatile的下一个特性:”不可优化”特性。
Volatile:不可优化的
与前面介绍的”易变”性类似,关于C/C++ Volatile关键词的第二个特性:”不可优化”性,也通过两个对比的代码片段来说明:
测试用例三:非Volatile变量
在这个用例中,非volatile变量a,b,c全部被编译器优化掉了 (optimize out),因为编译器通过分析,发觉a,b,c三个变量是无用的,可以进行常量替换。最后的汇编代码相当简介,高效率。
测试用例四:Volatile变量
测试用例四,与测试用例三类似,不同之处在于,a,b,c三个变量,都是volatile变量。这个区别,反映到汇编语言中,就是三个变量仍旧存在,需要将三个变量从内存读入到寄存器之中,然后再调用printf()函数。
小结
从测试用例三、四,可以总结出C/C++ Volatile关键词的第二个特性:“不可优化”特性。volatile告诉编译器,不要对我这个变量进行各种激进的优化,甚至将变量直接消除,保证程序员写在代码中的指令,一定会被执行。相对于前面提到的第一个特性:”易变”性,”不可优化”特性可能知晓的人会相对少一些。但是,相对于下面提到的C/C++ Volatile的第三个特性,无论是”易变”性,还是”不可优化”性,都是Volatile关键词非常流行的概念。
Volatile关键词的第三个特性:”顺序性”,能够保证Volatile变量间的顺序性,编译器不会进行乱序优化。Volatile变量与非Volatile变量的顺序,编译器不保证顺序,可能会进行乱序优化。同时,C/C++ Volatile关键词,并不能用于构建happens-before语义,因此在进行多线程程序设计时,要小心使用volatile,不要掉入volatile变量的使用陷阱之中。
]]>越狱前言
目前SurfaceRT1和2如果是巨硬的系统的话有ARM版的原版Windows8、原版Windows8.1和泄露版Windows10(15035)可以刷。
8是有工具(RT Jailbreak)可以绕过微软权限运行没有签名的arm版exe;
8.1是8的权限绕过漏洞被封锁了,不过没有打最新补丁的环境可以通过bcd命令开启测试模式,运行非微软签名的arm版exe;
10是泄露版本非正式发行版,所以不存在封锁权限。这里是RT的部署教程:http://tieba.baidu.com/p/6453637737%E3%80%82
我的RT默认是8.1的系统,这里暂时先谈8.1如何开启测试模式运行arm版exe程序。
开启测试模式
首先请去控制面板检查你的设备有没有 KB3088195 和 KB3084905 这两个更新。如果有,请删除并重启。这两个更新存在关闭普通用户开启测试模式的补丁。
然后我们开始输入开启命令。以管理员身份打开powershell,输入如下命令:
1
|
|
回车后正常执行后会提示命令成功完成!这个时候重启设备,再开机右下角会提示测试模式,就代表开启成功惹。
Tips:这条命令使用的是Unicode字符!尤其是那个N并不是字母N只是长得像,建议复制上面的命令字符串粘贴到powershell。不然也会提示命令成功完成但重启后还是打不开。
关闭自动更新
RT设备是无法通过组策略关闭系统自动更新的,不过通过修改注册表键值可以实现:
1 2 3 |
|
确定后操作中心会提示自动更新被关闭。
自己签名exe
这个就比较简单惹。无论是否dotnet应用通过VistualStudio的签名工具都可以签名。8.1系统开启测试模式也必须要带签名的exe才可以运行,不过它不会管你签名是否是微软的,只要有一个就好。
后来我还发现了个批量签名工具,对于不搞开发的朋友会很友好。只要把要签名的程序拖到这个工具里,它就会把exe和dll全部自动签名好。签名好后放到rt里就可以直接用:
https://blog.csdn.net/qq_19998167/article/details/87792544
https://share.weiyun.com/5jBlMB3
可以在RT里开一个共享文件夹,直接通过SMB局域网分享。
在哪获取应用
首先是通过商店:由于我是8.1系统的LTS用户(x),所以8.1微软的应用商店我还是比较亲切的,虽然没什么东西而且应用经常到期下架但是我还是知道哪些是我经常用的hhh。
其次是exe:我们刚刚开启了测试模式,也知道怎么给应用签名和在RT上运行。ARM下的话exe还是有不少的,除了有RT的忠实用户和有玩WindowsPhone但喜欢刷成Windows10的朋友,它们会多少移植些这样的应用外。不少开源跨平台项目和软件也还在支援ARM版exe。大家可以在github什么的看看自己中意的软件,下载ARM版源代码自己编译下也是可以的。或者可以自己写一些应用也没问题。
xda上也有一个帖子专门收录ARM指令集的应用:
Desktop apps ported to Windows RT | Windows 8, RT Development and Hacking
https://forum.xda-developers.com/showthread.php?t=2092348
大家可以下载下来签个名再拷到RT上。
最后是web:IE虽然难用但还是可以用的hhh。
拿来做什么
我的话,我是OneNote和Outlook的重度用户、也一直很喜欢窗边优和窗边爱这两个形象、应用商店虽然可怜但是有些也还能用、浏览器也增加了可玩性、也可以探索下arm版的exe。
平时浏览网页,听听歌做个闹钟之类的还是可以有的,玩玩应用商店。搭个smb、web、ftp什么的服务还是挺好的。查查邮件,改动笔记,还有完整的office加成。想具体了解ARM的NT内核还有各种开源的ARM工具可以自己编译安装去探索。
泡方便面的时候还可以当作泡面垫。坏了也不会太心疼。
@本地磁盘姬
ohayou.aimo.moe
微博:@本地磁盘姬碟酱
Twitter:本地磁盘姬碟酱
知乎:本地磁盘姬
2020年02月13日
]]>盘姬工具箱: 是一款以萌化为主题的绿色综合整合包;它集成惹一些Win平台(或其他平台版本)你所能想或没有想到大大小小的功能;
AimoMPC: 它内置惹一款基于DirectShow的经典播放器MPC-BE,一款强大的流媒体支援播放器VLC和一款像素数据播放器YUVPlayer等。我们在此基础上还集成惹一些常用分/解/渲染器.一些实用工具.一些压片工具和一些专业级的图像序列/声音分析工具,你可以利用它作为播放器或快速从事一些数字视音频的研究(ForWin)。 未来将是跨平台的,仿videoeye与megui项目。 未来会: 想来想去还是做一个数字媒体分析和处理方案工具吧。基于vlc或mpv类似开源项目,捆绑整合opencv和ffmpeg的等lib实现对视频源进行各种分析,捆绑一些special和完整的mediainfo实现一下封装分析。通过player自身扩展灵活各个解码渲染的过程和变更,实现8k/240帧/弹幕/视觉样式/推流/截图等等基础功能,在附加简单的比如基于系统api实现简单刻录,fmpeglib实现如剪辑.格式转换…一套看似没什么卵用的实验级系(lun)统(zi),基于cpp和delphi。(其实本来不就是想做一个界面萌一点的播放器来着么X
Aimoland: ≧≦过段日子想做一个弹幕站,核心是关于数字视音频交流的百科站点w。有各种新旧标准和封装容器.各种开源项目文档.各平台下媒体应用开发(媒体.图形库).算法分析。类似doom9和nmmhd那样synth各种压缩编解码处理交流.各种工具和播放器交流。 (=ω)视频内容的话主打音乐向ww.ACG音乐.PVMV和CD.鬼畜.音MAD和宅舞这些。主站CMS全部开源.采用版本相对激进的后台和功能.重心也是落在技术交流上qwq.以做出给大家带来更自由更好的技术和体验为重点;
Live2d AI(Aimo酱): 通过live2d映射出人物建模与你的交互.一台WinPC(或其它更多平台)来实现控制一切.可你帮助你做一些事;
萌辞书Wiki: 一个专注于收集各种萌化的百科站点。无论是在电信号内的,还是电信号外的..
天使道: 关于MTF的各种情报的收集文库站点;
太阳花论坛: 一个关于Mediawiki系统的交流站点;
114爱萌岛: 一个萌化的网址导航,仿Q+页面面板;
HelloWord: 一句话的事儿。各种简短代码收集;
MatMei: 基于matlab的图像处理库应用。主要围绕数字图像处理这本书进行探讨;
FuryOS: 基于Osaka与Linux项目的简单电子计算机操作系统。重点围绕操作系统理论体系架构的应用;
前辈请帮我修电脑吧: 关于计算机运维的讨论站点;
AngelSound: 是伪声练习的小工具;
其它项目: NetSparrow、软体改二、教程文章、个人博客、公众号、音视频作品、绘画绘本,etc..
]]>18年的7月25日,经过六院从大爷的诊断,我被诊断为易性症,属于性别认同障碍范畴。带有“易性症”标注的性认障碍表示为就医者对自己的生理性别也存在不认同的情况,并希望通过手术以改变。而根据18年初北大六院的新规定,易性症需要从第一次拿到证明的一那天起算两年内经过一系列检查和至少三个不同医生的咨询等才可拿到最终的手术证明。于是,我的易性症治疗之旅也就从这一天正式地开始惹。
从那天开始后,我就把易性症这件事告诉惹自己的家人和网络上的朋友,并开始留起惹长发、日常也开始穿女孩子的衣服惹,开始慢慢正式地向女孩子的生活过渡。虽然UI(相貌)还挺可爱的吧(#捂脸噗噗噗),正常在大街上生活中和陌生人见面也不会被发现出来(开心),不过..开口跪!(等到明年处理完升学后一定要努力学习伪声!)。
19年的02月21日,经过丛中医生的推荐,我去见惹唐宏宇医生(一个很和蔼可亲的医生,目前每周二四下午接诊)。见面的时候完全女装,我上来就把自己的病历本给了医生。医生看了看,问了问我最近一段日子的情况(学习呀、生活呀etc)。然后就开惹很多很多心里测试项目(眼动测试和一些在电脑上答的问卷),并让我去三院生殖中心做一个染色体检查,检查后继续找医生进行进一步咨询。
大概必要的流程就是这个样子!不过,当天我除此之外并没有再继续,因为我那天她!喵!的!没!带!医!保!卡!。光是心理测试的费用加起来就有700+,无奈/。只能先回家吧(趴。一会我会详细说下心理测试和染色体检查。
目前,北大六院性别认同障碍推荐去问诊的医生分别是:丛中医生(周3下午)、唐宏宇医生(2和4下午)、刘建成医生和方明昭医生。北医三院的话有“易性症诊疗团队”,负责人是潘柏林医生,他在医院的美容成形科,关于易性症的一切可以去咨询他。三院的话你也可以参照 北医三院关于易性症序列治疗就诊指南 对心里嗓音激素和手术等等进行咨询治疗,这个在三院官网、我的博客和天使道Wiki上都可以查到。关于预约挂号挂号,可以看我这篇续篇的上一篇。六院推荐通过alipay,三院推荐通过三院wechat公众号。
我决定还是先做染色体检查吧。19年04月25日,因为曾经有过去内分泌科结果被告知无法办理的情况、又正巧三院内分泌科可以看易性症的刘烨医生被调去病房的缘故,我直接去三院美容成型科找潘柏林医生去咨询。最终经过简单的交谈,我在潘医生那里办理了染色体核型分析的检查。
费用医保后是600元,在大厅缴费。静脉采血(在小臂上扎一下取一点血进行培养)。缴费后根据单子上提供的预约日期再去取血(周期大概是20+天左右),取血后需要等30天,30天后去大厅自助机取结果(结果好像是保留3个月)。
拿着缴费单,前往三院的生殖中心三层的护士站协商预约时间后方可离开。到预约时间的时候再去采血(我预约的是05月27日)只上午接待采血,很快就可采血完毕。07月10日放暑假的时候的时候去生殖中心取的结果,一张大纸,上面会画着染色体和你是XX(女)还是XY(男)。
19年07月30日,我拿着染色体证明和医保卡再次找到唐宏宇医生。确认染色体基本正常后,开了如下心理测试项目:
1 2 3 4 5 |
|
医保后总共花费200+元。眼动测试是看变化的图案回答问题、其它几项测试都是通过医院的局域网电脑做选择题,MMPI的题目比较多(大概600+道,但不用都做完),窝好像..做惹1个多小时。。(浏览器是Chrome,电脑挺稳定的,不用担心做到一半崩溃X)。当时就可以出结果。
心理测试结果只要都是正常范围就好。
除惹上述测试外还需要一个居住证明。这个证明很简单,就是一张证明你是我辖区的人。这个现在派出所已经不给开惹,需要拿着你的身份证和户口簿寻找你的辖区居委会,和工作人员说一下就可以开。不过建议到满两年后去领取大证明后再去办理,否则医院那边会因为证明中时间久远不予采纳。
好辣!截至到目前你已经完成惹大证明前大部分的事儿。由于截止到现在,我还剩下不到一年的时间(要等到20年07月25日后)才可以领到大证明。在此期间,你还需要不断地去医院找不同的医生咨询(几个月一次就好)才可以。等到两年后,拿着持续治疗的病历本+居住证明+染色体检查+心理测试找心理医生,心理医生批准后就可以拿着这一大套的东西去护士站办理最终的手术证明辣!
在这短短地一年里,经历惹很多事,我又成长惹许多w。我的爱好是计算机视觉与美术,除惹爱好上的一些技能提升X,我也慢慢即将做到惹基本上的女性的日常生活。要说和这些相关的话..除惹交到很多朋友还有日常之外,还成为了北京同志中心的一名志愿者,并搭建了天使道Wiki,一个关于跨性别的百科站。不过因为要准备升学的缘故哈,我的一些面向别人服务的项目都被暂时搁置惹,明年04月左右会正式启动,欢迎你可以来加入我们!
关于上面一些检查的照片什么的,你可以先暂时加入天使道QQ群(855845801)查看~
也(更)欢迎你与我做朋友!!
@本地磁盘姬
ohayou.aimo.moe
微博:@本地磁盘姬碟酱
Twitter:本地磁盘姬
知乎:本地磁盘姬
2019年08月27日
]]>FFFmpeg框架由AVFormat、AVCodec、AVFilter、AVDevice、AVUtil等模块库组成。
(1)AVFormat库实现了目前多媒体领域中的绝大多数媒体封装格式的封装和解封装,同时还支持增加自己定制的封装格式。
(2)AVCodec库实现了目前多媒体领域中的绝大多数常用的编解码格式的编码与解码,同时还支持第三方编解码器的外挂。
(3)AVFilter库提供了一个通用的音、视、字幕等滤镜的处理框架,滤镜框架可以有多个输入输出。它是通过切割视频流的方式将需要滤镜的部分扔给滤镜,然后再将滤镜后的流交给图层再合并压制出新的视频。
(4)其中的swscale模块是负责图像转换计算的,提供了高级别的图像转换API。例如1080p转720p,YUV转RGB等。
(5)其中swresample模块是负责音频重采样功能的,它允许操作音频采样、音频通道布局转换与布局调整。
1
|
|
FFmpeg主要是通过下面六个流程来执行封装格式转换的:
1 2 3 4 5 6 7 8 9 10 11 |
|
1
|
|
ffplay的基本流程是有avformat与avcode进行媒体档案的解封装与解码,再将解码后的数据输出给SDL库进行播放。ffplay提供了音视频显示和播放相关的图像信息、音频的波形信息等。
1
|
|
ffprobe是一个多媒体分析工具(类似MediaInfo),可以从媒体档案或者媒体流中获得一些信息,如视音频参数、媒体容器参数信息等。
编码器支持:
1
|
|
解码器支持:
1
|
|
封装支持:
1
|
|
解封装支持:
1
|
|
通信协议支持:
1
|
|
1 2 3 4 5 6 7 8 |
|
1 2 3 4 5 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
1 2 3 4 5 6 7 8 9 |
|
1 2 3 |
|
@本地磁盘姬
ohayou.aimo.moe
微博:@本地磁盘姬碟酱
Twitter:本地磁盘姬
2019年08月11日
]]>MathWorks公司历史悠久、团队强大、产品专一。它的matlab产品可用于多种学术研究专业,这样首屈一指的软件使得它在全世界都十分流行。也是数字图像处理仿真的好帮手。本文送给从未接触过matlab的朋友们。
图像处理系统基础设计的一个重要特点是测试和实验的有效程度。系统方法和快速原型候选解决方案的能力在减少运算开销和时间方面起着重要的作用。
一幅图像可以定义为一个二维函数f(x,y),其中x和y是空间坐标,而f在任意坐标(x,y)处的幅度称为图像在该点处的亮度和灰度。彩色图像是由多个单色图像组合而成。当x,y和f的幅值都是有限的离散值时,称该函数为数字图像。数字图像是由有限数量的数组组成的,每个元素都有一个特殊的位置和数值。这些元素称为图片元素(picture element)、图像元素(image element)和像素(pixels\pels)。
数字图像处理分为低中高三种处理: 低级处理包括原始操作(降低噪声、对比度增强..),输入输出都是图像。 中级处理(分割..),把图像分为区域或目标,然后对目标进行描述。输入是图像,输出是图像提取出的属性。 高级处理通过执行通常与人类视觉相关的感知函数,来对识别的对象进行总体确认。
一幅图像可定义为一个二维数组f(x,y),其中x和y是空间(平面)坐标。图像关于x坐标、y坐标和幅度是连续的。将坐标值数字化称为采样,将幅值数字化称为量化。当x、y和幅值f都是有限的、离散的量时,我们称该图像为数字图像。
采样和量化得到的是一个实数矩阵。假设对一幅图像f(x,y)采样后得到一个M行、N列的图像。我们可以称这幅图像的大小是MxN,坐标的值是离散量。
这样,一幅二维数字图像就可以把它看做成一个矩阵函数f(x,y),把阵列的每个元素赋值就可以显示出东西。这个阵列的每个元素都称为图像元素、图画元素或像素。一个1N的矩阵被称为一个行向量,一个M1的矩阵被称为一个列向量。一个1*1的矩阵则被称为标量。
把二位数字图像看成矩阵,这样我们就可以轻松地在matlab中做各种仿真尝试惹。
matlab的命令行(>>)窗口是我们操作matlab的一个重要媒介。
我们可以进行一些简单计算,比如把2+2的值赋给变量a。
1
|
|
如果输入的表达式后面加上分号;的话,那么结果就不会显示出来。还有,matlab的变量名是对大小写字母敏感的。它主要支持以下数值运算符:
1
|
|
同时,matlab中还提供一些预定义变量可以直接使用。
1 2 3 4 5 6 7 8 9 10 |
|
我们可以指定元素建立向量。创建一个1*4的行向量:
1
|
|
也可以增加向量,变成1 3 5 7 8:
1
|
|
用等间隔元素建立向量:
1
|
|
这个命令创建了一个1*101的向量,元素为0,0.1,0.2,…,10。这个表达式中前面的数字表示初值,后面的数字表示终值,中间的数字表示增量。
函数linespace和logspace也可用于创建向量;
1 2 3 4 |
|
矩阵可以通过输入行列元素获得:
1 2 3 |
|
矩阵特定位置元素可以通过下面的命令赋值:
1
|
|
用下面几个命令可以定义一些特殊矩阵:
1 2 3 4 |
|
要得到向量或矩阵的规模可以用下面这两个函数:
1 2 |
|
波形的绘制:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
数据的输入和输出:
1 2 3 4 5 |
|
其它常用matlab命令:
1 2 3 4 5 6 7 |
|
你还可以尝试在安卓或ios端安装matlab官方的远程软件操控电脑端的matlab,需要局域网环境和较新版本的matlab。
1 2 3 |
|
读入数字二维图像文件到matlab变量f:
1
|
|
在新的图形窗口显示变量f中的图像:
1
|
|
写入图像write函数(调整质量的范例):
1 2 |
|
matlab提供惹一个图像处理工具箱,它把matlab数值计算环境扩展到图像处理的函数合集。
工具箱支持4种图像类型:
灰度级图像(Gray-scale images)
二值图像(Binary images)
索引图像(Indexed images)
RGB图像(RGB images)
类和图像类型:
1 2 3 4 5 6 7 8 9 10 |
|
类uint8和logical广泛地用于图像处理,浮点类double和single用于计算灰度的操作。
灰度级图像:一幅灰度级图像是一个数据矩阵,矩阵的值表示灰度的浓淡。
二值图像:一幅二值图像是一个取值只有0和1的逻辑数组。使用函数logical可将数值数组转换为二值图像。
1 2 |
|
M文件是大量MATLAB命令的集合,它以文本文件的形式存储,文件后缀".m"。M文件可以是一个有输入、输出变量的函数,也可以是一系列的命令脚本。可以直接放到matlab里执行。
引例,一个计算两数之和的函数:
1 2 3 4 |
|
1 2 3 4 |
|
1 2 3 4 5 6 7 8 9 |
|
matlab函数tic和toc可用于测量函数执行的时间。
1
|
|
函数timeit可用于得到函数调用的可靠的可重复的时间测量。
1
|
|
利用矩阵和向量形式写的M文件效率比较高。循环和if语句也可以在matlab中使用,但是计算效率较低,所以要谨慎使用。
向量化说明和函数meshgrid的介绍。
我们用matlab基于如下公式写函数来创建一幅合成图像:f(x,y)=Asin(u0x+v0y)
for循环版:
1 2 3 4 5 6 7 8 9 |
|
meshgrid向量版:
1 2 3 4 5 6 |
|
检验:
1 2 3 |
|
向量化形式运行的时间约可少50%。
本地磁盘姬
ohayou.aimo.moe
微博:@本地磁盘姬碟酱
Twitter:本地磁盘姬
2019年07月16日
]]>OpenGL(开放式图形库)是用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口。通过它可以在一些计算机上描述图元、属性、几何变换、观察变换等其它操作。属于计算机图形学的范畴。
OpenGL的核心库中的函数名要以gl为前缀、函数名中每一个组成词的第一个字母要大写(如glBegin)。
有些函数要求一个或多个变量用符号常量赋值,如参数名、参数的值或特定的模式。这些常量均以GL开头并全部大写,单词间用_隔开(如GL_2D)。
OpenGL函数也有专门的数据类型,并且部分函数支持数组(比如多维坐标)。大写GL开头,小写字母表示标准数据类型名(如GLint)。
OpenGL除惹核心库外还有一些用于处理专门操作的附加库。比如实用函数库(GLU)、窗口扩充(GLX)、实用工具包(GLUT)等等,比较模块化。
新建项目-C++空白项目-创建C++文件;
工具-NuGet包管理器-包管理器控制台;
1
|
|
完成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
|
@本地磁盘姬
ohayou.aimo.moe
微博:@本地磁盘姬碟酱
Twitter:@AmyGreen
2019年04月02日
]]>
包括:3n+1猜想、挖掘机技术哪家强、找x、图形输出、日期差值、进制转换等。参见《算法笔记》第三章。备考笔记持续更新w~
卡拉兹(Callatz)猜想:
对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n+1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n=1。卡拉兹在 1950 年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证 (3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……
我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过 1000 的正整数 n,简单地数一下,需要多少步(砍几下)才能得到 n=1?
1 2 3 4 5 6 7 8 9 10 11 12 |
|
为了用事实说明挖掘机技术到底哪家强,PAT 组织了一场挖掘机技能大赛。现请你根据比赛结果统计出技术最强的那个学校。 输入格式:
输入在第 1 行给出不超过 10?的5次方?? 的正整数 N,即参赛人数。随后 N 行,每行给出一位参赛者的信息和成绩,包括其所代表的学校的编号(从 1 开始连续编号)、及其比赛成绩(百分制),中间以空格分隔。 输出格式:
在一行中给出总得分最高的学校的编号、及其总分,中间以空格分隔。题目保证答案唯一,没有并列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
输入一个数n,然后输入n个数值各不相同,再输入一个值x,输出这个值在这个数组中的下标(从0开始,若不在数组中则输出-1)。 输入:测试数据有多组,输入n(1<=n<=200),接着输入n个数,然后输入x。 输出:对于每组输入,请输出结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
2014年底,为庆祝“计算机科学教育周”正式启动,奥巴马编写了很简单的计算机代码:在屏幕上画一个正方形。现在你也跟他一起画吧!
输入:输入在一行中给出正方形边长 N (3<= N<= 20)和组成正方形边的某种字符 C,间隔一个空格。
输出:由给定字符 C 画出的正方形。但是注意到行间距比列间距大,所以为了让结果看上去更像正方形,我们输出的行数实际上是列数的 50%(四舍五入取整)。
四舍五入可通过判断奇偶性解决。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
题目描述:有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天。
输入:有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD
输出:每组数据输出一行,即日期差值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
|
题目描述:输入两个非负10进制整数A和B(<=2的30次方-1),输出A+B的D (1 < D <= 10)进制数。
输入格式:输入在一行中依次给出3个整数A、B和D。
输出格式:输出A+B的D进制数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
题目描述:读入一串字符,判断是否是回文串。“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。
输入:一行字符串,长度不超过255。
输出:如果是回文串,输出“YES”,否则输出“NO”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
给定一句英语,要求编写程序,将句中所有单词的顺序颠倒输出。
输入格式:测试输入包含一个测试用例,在一行内给出总长度不超过80的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用1个空格分开,输入保证句子末尾没有多余的空格。
输出格式:每个测试用例的输出占一行,输出倒序后的句子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
@本地磁盘姬
ohayou.aimo.moe
微博:@本地磁盘姬碟酱
Twitter:@AmyGreen
2019年03月17日
]]>分为Part1、团队及小程序介绍与Part2部分。
知乎预览:https://zhuanlan.zhihu.com/p/54155516
百度盘原图分享:
链接:https://pan.baidu.com/s/1mt_n-XpcrNKjtohc_9atDg
密码:og5m
PS:由于特殊性只公开部分截图。
转载请注明出处。
@本地磁盘姬
ohayou.aimo.moe
微博:@本地磁盘姬碟酱
Twitter:@AmyGreen
2019年01月06日
]]>转自:https://zhuanlan.zhihu.com/p/38595188
第一课 什么是卷积 卷积有什么用 什么是傅利叶变换 什么是拉普拉斯变换
引子
很多朋友是工科电子类专业,学了一堆信号方面的课,什么都没学懂,背了公式考了试,然后毕业了。
先说"卷积有什么用"这个问题。(有人抢答,"卷积"是为了学习"信号与系统"这门课的后续章节而存在的。我大吼一声,把他拖出去枪毙!)
讲一个故事:
张三刚刚应聘到了一个电子产品公司做测试人员,他没有学过"信号与系统"这门课程。一天,他拿到了一个产品,开发人员告诉他,产品有一个输入端,有一个输出端,有限的输入信号只会产生有限的输出。
然后,经理让张三测试当输入sin(t)(t<1秒)信号的时候(有信号发生器),该产品输出什么样的波形。张三照做了,花了一个波形图。
“很好!"经理说。然后经理给了张三一叠A4纸: "这里有几千种信号,都用公式说明了,输入信号的持续时间也是确定的。你分别测试以下我们产品的输出波形是什么吧!”
这下张三懵了,他在心理想"上帝,帮帮我把,我怎么画出这些波形图呢?"
于是上帝出现了: “张三,你只要做一次测试,就能用数学的方法,画出所有输入波形对应的输出波形"。
上帝接着说:“给产品一个脉冲信号,能量是1焦耳,输出的波形图画出来!”
张三照办了,"然后呢?"
上帝又说,"对于某个输入波形,你想象把它微分成无数个小的脉冲,输入给产品,叠加出来的结果就是你的输出波形。你可以想象这些小脉冲排着队进入你的产品,每个产生一个小的输出,你画出时序图的时候,输入信号的波形好像是反过来进入系统的。"
张三领悟了:“ 哦,输出的结果就积分出来啦!感谢上帝。这个方法叫什么名字呢?”
上帝说:“叫卷积!”
从此,张三的工作轻松多了。每次经理让他测试一些信号的输出结果,张三都只需要在A4纸上做微积分就是提交任务了!
张三愉快地工作着,直到有一天,平静的生活被打破。
经理拿来了一个小的电子设备,接到示波器上面,对张三说: “看,这个小设备产生的波形根本没法用一个简单的函数来说明,而且,它连续不断的发出信号!不过幸好,这个连续信号是每隔一段时间就重复一次的。张三,你 来测试以下,连到我们的设备上,会产生什么输出波形!”
张三摆摆手:“输入信号是无限时长的,难道我要测试无限长的时间才能得到一个稳定的,重复的波形输出吗?”
经理怒了:“反正你给我搞定,否则炒鱿鱼!”
张三心想:“这次输入信号连公式都给出出来,一个很混乱的波形;时间又是无限长的,卷积也不行了,怎么办呢?”
及时地,上帝又出现了:“把混乱的时间域信号映射到另外一个数学域上面,计算完成以后再映射回来”
“宇宙的每一个原子都在旋转和震荡,你可以把时间信号看成若干个震荡叠加的效果,也就是若干个可以确定的,有固定频率特性的东西。”
“我给你一个数学函数f,时间域无限的输入信号在f域有限的。时间域波形混乱的输入信号在f域是整齐的容易看清楚的。这样你就可以计算了”
“同时,时间域的卷积在f域是简单的相乘关系,我可以证明给你看看”
“计算完有限的程序以后,取f(-1)反变换回时间域,你就得到了一个输出波形,剩下的就是你的数学计算了!”
张三谢过了上帝,保住了他的工作。后来他知道了,f域的变换有一个名字,叫做傅利叶,什么什么… …
再后来,公司开发了一种新的电子产品,输出信号是无限时间长度的。这次,张三开始学拉普拉斯了……
后记:
不是我们学的不好,是因为教材不好,老师讲的也不好。
很欣赏Google的面试题: 用3句话像老太太讲清楚什么是数据库。这样的命题非常好,因为没有深入的理解一个命题,没有仔细的思考一个东西的设计哲学,我们就会陷入细节的泥沼: 背公式,数学推导,积分,做题;而没有时间来回答"为什么要这样"。做大学老师的做不到"把厚书读薄"这一点,讲不出哲学层面的道理,一味背书和翻讲 ppt,做着枯燥的数学证明,然后责怪"现在的学生一代不如一代",有什么意义吗?
第二课 到底什么是频率 什么是系统?
这一篇,我展开的说一下傅立叶变换F。注意,傅立叶变换的名字F可以表示频率的概念(freqence),也可以包括其他任何概念,因为它只是一个概念模 型,为了解决计算的问题而构造出来的(例如时域无限长的输入信号,怎么得到输出信号)。我们把傅立叶变换看一个C语言的函数,信号的输出输出问题看为IO 的问题,然后任何难以求解的x->y的问题都可以用x->f(x)->f-1(x)->y来得到。
一个基本的假设: 任何信息都具有频率方面的特性,音频信号的声音高低,光的频谱,电子震荡的周期,等等,我们抽象出一个件谐振动的概念,数学名称就叫做频率。想象在x-y 平面上有一个原子围绕原点做半径为1匀速圆周运动,把x轴想象成时间,那么该圆周运动在y轴上的投影就是一个sin(t)的波形。相信中学生都能理解这 个。
那么,不同的频率模型其实就对应了不同的圆周运动速度。圆周运动的速度越快,sin(t)的波形越窄。频率的缩放有两种模式
(a) 老式的收音机都是用磁带作为音乐介质的,当我们快放的时候,我们会感觉歌唱的声音变得怪怪的,调子很高,那是因为"圆周运动"的速度增倍了,每一个声音分量的sin(t)输出变成了sin(nt)。
(b) 在CD/计算机上面快放或满放感觉歌手快唱或者慢唱,不会出现音调变高的现象:因为快放的时候采用了时域采样的方法,丢弃了一些波形,但是承载了信息的输出波形不会有宽窄的变化;满放时相反,时域信号填充拉长就可以了。
解释: F变换是个数学工具,不具有直接的物理意义,负数/复数的存在只是为了计算的完整性。
对于通信和电子类的学生来说,很多情况下我们的工作是设计或者OSI七层模型当中的物理层技术,这种技术的复杂性首先在于你必须确立传输介质的电气特 性,通常不同传输介质对于不同频率段的信号有不同的处理能力。以太网线处理基带信号,广域网光线传出高频调制信号,移动通信,2G和3G分别需要有不同的 载频特性。那么这些介质(空气,电线,光纤等)对于某种频率的输入是否能够在传输了一定的距离之后得到基本不变的输入呢? 那么我们就要建立介质的频率相应数学模型。同时,知道了介质的频率特性,如何设计在它上面传输的信号才能大到理论上的最大传输速率?—-这就是信号与 系统这们课带领我们进入的一个世界。
当然,信号与系统的应用不止这些,和香农的信息理论挂钩,它还可以用于信息处理(声音,图像),模式识别,智能控制等领域。如果说,计算机专业的课程是 数据表达的逻辑模型,那么信号与系统建立的就是更底层的,代表了某种物理意义的数学模型。数据结构的知识能解决逻辑信息的编码和纠错,而信号的知识能帮我 们设计出码流的物理载体(如果接受到的信号波形是混乱的,那我依据什么来判断这个是1还是0? 逻辑上的纠错就失去了意义)。在工业控制领域,计算机的应用前提是各种数模转换,那么各种物理现象产生的连续模拟信号(温度,电阻,大小,压力,速度等) 如何被一个特定设备转换为有意义的数字信号,首先我们就要设计一个可用的数学转换模型。
设计物理上的系统函数(连续的或离散的状态),有输入,有输出,而中间的处理过程和具体的物理实现相关,不是这们课关心的重点(电子电路设计?)。信号 与系统归根到底就是为了特定的需求来设计一个系统函数。设计出系统函数的前提是把输入和输出都用函数来表示(例如sin(t))。分析的方法就是把一个复 杂的信号分解为若干个简单的信号累加,具体的过程就是一大堆微积分的东西,具体的数学运算不是这门课的中心思想。
那么系统有那些种类呢?
(a) 按功能分类: 调制解调(信号抽样和重构),叠加,滤波,功放,相位调整,信号时钟同步,负反馈锁相环,以及若干子系统组成的一个更为复杂的系统—-你可以画出系统 流程图,是不是很接近编写程序的逻辑流程图? 确实在符号的空间里它们没有区别。还有就是离散状态的数字信号处理(后续课程)。
(b) 按系统类别划分,无状态系统,有限状态机,线性系统等。而物理层的连续系统函数,是一种复杂的线性系统。
符号系统的核心是集合论,不是微积分,没有集合论构造出来的系统,实现用到的微积分便毫无意义—-你甚至不知道运算了半天到底是要作什么。以计算机的观点来学习信号与系统,最好的教材之一就是<>, 作者是UC Berkeley的Edward A.Lee and Pravin Varaiya—-先定义再实现,符合人类的思维习惯。国内的教材通篇都是数学推导,就是不肯说这些推导是为了什么目的来做的,用来得到什么,建设什 么,防止什么;不去从认识论和需求上讨论,通篇都是看不出目的的方法论,本末倒置了。
第三课 抽样定理是干什么的
那么,问题来了,每M毫秒采样一次,M多小是足够的? 在收端怎么才能恢复语言波形呢?
对于第一个问题,我们考虑,语音信号是个时间频率信号(所以对应的F变换就表示时间频率)把语音信号分解为若干个不同频率的单音混合体(周期函数的复利叶 级数展开,非周期的区间函数,可以看成补齐以后的周期信号展开,效果一样),对于最高频率的信号分量,如果抽样方式能否保证恢复这个分量,那么其他的低频 率分量也就能通过抽样的方式使得信息得以保存。如果人的声音高频限制在3000Hz,那么高频分量我们看成sin(3000t),这个sin函数要通过抽 样保存信息,可以看为: 对于一个周期,波峰采样一次,波谷采样一次,也就是采样频率是最高频率分量的2倍(奈奎斯特抽样定理),我们就可以通过采样信号无损的表示原始的模拟连续 信号。这两个信号一一对应,互相等价。
对于第二个问题,在收端,怎么从脉冲序列(梳装波形)恢复模拟的连续信号呢? 首先,我们已经肯定了在频率域上面的脉冲序列已经包含了全部信息,但是原始信息只在某一个频率以下存在,怎么做? 我们让输入脉冲信号I通过一个设备X,输出信号为原始的语音O,那么I()X=O,这里()表示卷积。时域的特性不好分析,那么在频率域 F(I)*F(X)=F(O)相乘关系,这下就很明显了,只要F(X)是一个理想的,低通滤波器就可以了(在F域画出来就是一个方框),它在时间域是一个 钟型函数(由于包含时间轴的负数部分,所以实际中不存在),做出这样的一个信号处理设备,我们就可以通过输入的脉冲序列得到几乎理想的原始的语音。在实际 应用中,我们的抽样频率通常是奈奎斯特频率再多一点,3k赫兹的语音信号,抽样标准是8k赫兹。
话说回来了,直接在信道上传原始语音信号不好吗? 模拟信号没有抗干扰能力,没有纠错能力,抽样得到的信号,有了数字特性,传输性能更佳。
什么信号不能理想抽样? 时域有跳变,频域无穷宽,例如方波信号。如果用有限带宽的抽样信号表示它,相当于复利叶级数取了部分和,而这个部分和在恢复原始信号的时候,在不可导的点上面会有毛刺,也叫吉布斯现象。
入门第四课 傅立叶变换的复数 小波
说的广义一点,"复数"是一个"概念",不是一种客观存在。
什么是"概念"? 一张纸有几个面? 两个,这里"面"是一个概念,一个主观对客观存在的认知,就像"大"和"小"的概念一样,只对人的意识有意义,对客观存在本身没有意义(康德: 纯粹理性的批判)。把纸条的两边转一下相连接,变成"莫比乌斯圈",这个纸条就只剩下一个"面"了。概念是对客观世界的加工,反映到意识中的东西。
数的概念是这样被推广的: 什么数x使得x2=-1? 实数轴显然不行,(-1)(-1)=1。那么如果存在一个抽象空间,它既包括真实世界的实数,也能包括想象出来的x2=-1,那么我们称这个想象空间 为"复数域"。那么实数的运算法则就是复数域的一个特例。为什么1(-1)=-1? +-符号在复数域里面代表方向,-1就是"向后,转!“这样的命令,一个1在圆周运动180度以后变成了-1,这里,直线的数轴和圆周旋转,在复数的空间 里面被统一了。
因此,(-1)*(-1)=1可以解释为"向后转"+“向后转”=回到原地。那么复数域如何表示x2=-1呢? 很简单,"向左转","向左转"两次相当于"向后转"。由于单轴的实数域(直线)不包含这样的元素,所以复数域必须由两个正交的数轴表示–平面。很明 显,我们可以得到复数域乘法的一个特性,就是结果的绝对值为两个复数绝对值相乘,旋转的角度=两个复数的旋转角度相加。高中时代我们就学习了迪莫弗定理。 为什么有这样的乘法性质? 不是因为复数域恰好具有这样的乘法性质(性质决定认识),而是发明复数域的人就是根据这样的需求去弄出了这么一个复数域(认识决定性质),是一种主观唯心 主义的研究方法。为了构造x2=-1,我们必须考虑把乘法看为两个元素构成的集合: 乘积和角度旋转。
因为三角函数可以看为圆周运动的一种投影,所以,在复数域,三角函数和乘法运算(指数)被统一了。我们从实数域的傅立叶级数展开入手,立刻可以得到形式更 简单的,复数域的,和实数域一一对应的傅立叶复数级数。因为复数域形式简单,所以研究起来方便—-虽然自然界不存在复数,但是由于和实数域的级数一一 对应,我们做个反映射就能得到有物理意义的结果。
那么傅立叶变换,那个令人难以理解的转换公式是什么含义呢? 我们可以看一下它和复数域傅立叶级数的关系。什么是微积分,就是先微分,再积分,傅立叶级数已经作了无限微分了,对应无数个离散的频率分量冲击信号的和。 傅立叶变换要解决非周期信号的分析问题,想象这个非周期信号也是一个周期信号: 只是周期为无穷大,各频率分量无穷小而已(否则积分的结果就是无穷)。那么我们看到傅立叶级数,每个分量常数的求解过程,积分的区间就是从T变成了正负无 穷大。而由于每个频率分量的常数无穷小,那么让每个分量都去除以f,就得到有值的数—-所以周期函数的傅立叶变换对应一堆脉冲函数。同理,各个频率分 量之间无限的接近,因为f很小,级数中的f,2f,3f之间几乎是挨着的,最后挨到了一起,和卷积一样,这个复数频率空间的级数求和最终可以变成一个积分 式:傅立叶级数变成了傅立叶变换。注意有个概念的变化:离散的频率,每个频率都有一个"权"值,而连续的F域,每个频率的加权值都是无穷小(面积=0), 只有一个频率范围内的"频谱"才对应一定的能量积分。频率点变成了频谱的线。
因此傅立叶变换求出来的是一个通常是一个连续函数,是复数频率域上面的可以画出图像的东西? 那个根号2Pai又是什么? 它只是为了保证正变换反变换回来以后,信号不变。我们可以让正变换除以2,让反变换除以Pi,怎么都行。慢点,怎么有"负数"的部分,还是那句话,是数轴 的方向对应复数轴的旋转,或者对应三角函数的相位分量,这样说就很好理解了。有什么好处? 我们忽略相位,只研究"振幅"因素,就能看到实数频率域内的频率特性了。
我们从实数(三角函数分解)->复数(e和Pi)->复数变换(F)->复数反变换(F-1)->复数(取幅度分量)-> 实数,看起来很复杂,但是这个工具使得,单从实数域无法解决的频率分析问题,变得可以解决了。两者之间的关系是: 傅立叶级数中的频率幅度分量是a1-an,b1-bn,这些离散的数表示频率特性,每个数都是积分的结果。而傅立叶变换的结果是一个连续函数: 对于f域每个取值点a1-aN(N=无穷),它的值都是原始的时域函数和一个三角函数(表示成了复数)积分的结果—-这个求解和级数的表示形式是一样 的。不过是把N个离散的积分式子统一为了一个通用的,连续的积分式子。
复频域,大家都说画不出来,但是我来画一下!因为不是一个图能够表示清楚的。我用纯中文来说:
画一个x,y轴组成的平面,以原点为中心画一个圆(r=1)。再画一条竖直线: (直线方程x=2),把它看成是一块挡板。
想象,有一个原子,从(1,0)点出发,沿着这个圆作逆时针匀速圆周运动。想象太阳光从x轴的复数方向射向x轴的正数方向,那么这个原子运动在挡板(x=2)上面的投影,就是一个简协震动。
再修改一下,x=2对应的不是一个挡板,而是一个打印机的出纸口,那么,原子运动的过程就在白纸上画下了一条连续的sin(t)曲线!
上面3条说明了什么呢? 三角函数和圆周运动是一一对应的。如果我想要sin(t+x),或者cos(t)这种形式,我只需要让原子的起始位置改变一下就可以了:也就是级坐标的向量,半径不变,相位改变。
傅立叶级数的实数展开形式,每一个频率分量都表示为AnCos(nt)+BnSin(nt),我们可以证明,这个式子可以变成 sqr(An2+Bn2)sin(nt+x)这样的单个三角函数形式,那么:实数值对(An,Bn),就对应了二维平面上面的一个点,相位x对应这个 点的相位。实数和复数之间的一一对应关系便建立起来了,因此实数频率唯一对应某个复数频率,我们就可以用复数来方便的研究实数的运算:把三角运算变成指数 和乘法加法运算。
但是,F变换仍然是有限制的(输入函数的表示必须满足狄义赫立条件等),为了更广泛的使用"域"变换的思想来表示一种"广义"的频率信息,我们就发明出了 拉普拉斯变换,它的连续形式对应F变换,离散形式就成了Z变换。离散信号呢? 离散周期函数的F级数,项数有限,离散非周期函数(看为周期延拓以后仍然是离散周期函数),离散F级数,仍然项数有限。离散的F变换,很容易理解—- 连续信号通过一个周期采样滤波器,也就是频率域和一堆脉冲相乘。时域取样对应频域周期延拓。为什么? 反过来容易理解了,时域的周期延拓对应频率域的一堆脉冲。
两者的区别:FT=从负无穷到正无穷对积分 LT=从零到正无穷对积分 (由于实际应用,通常只做单边Laplace变换,即积分从零开始) 具体地,在Fourier积分变换中,所乘因子为exp(-jwt),此处,-jwt显然是为一纯虚数;而在laplace变换中,所乘因子为 exp(-st),其中s为一复数:s=D+jw,jw是为虚部,相当于Fourier变换中的jwt,而D则是实部,作为衰减因子,这样就能将许多无法 作Fourier变换的函数(比如exp(at),a>0)做域变换。
而Z变换,简单地说,就是离散信号(也可以叫做序列)的Laplace变换,可由抽样信号的Laplace变换导出。ZT=从n为负无穷到正无穷对求和。 Z域的物理意义: 由于值被离散了,所以输入输出的过程和花费的物理时间已经没有了必然的关系(t只对连续信号有意义),所以频域的考察变得及其简单起来,我们把 (1,-1,1,-1,1,-1)这样的基本序列看成是数字频率最高的序列,他的数字频率是1Hz(数字角频率2Pi),其他的数字序列频率都是N分之 1Hz,频率分解的结果就是0-2Pi角频率当中的若干个值的集合,也是一堆离散的数。由于时频都是离散的,所以在做变换的时候,不需要写出冲击函数的因 子
离散傅立叶变换到快速傅立叶变换—-由于离散傅立叶变换的次数是O(N2),于是我们考虑把离散序列分解成两两一组进行离散傅立叶变换,变换的计算复杂度就下降到了O(NlogN),再把计算的结果累加O(N),这就大大降低了计算复杂度。
再说一个高级话题: 小波。在实际的工程应用中,前面所说的这些变换大部分都已经被小波变换代替了。
什么是小波?先说什么是波:傅立叶级数里面的分量,sin/cos函数就是波,sin(t)/cos(t)经过幅度的放缩和频率的收紧,变成了一系列的波 的求和,一致收敛于原始函数。注意傅立叶级数求和的收敛性是对于整个数轴而言的,严格的。不过前面我们说了,实际应用FFT的时候,我们只需要关注部分信 号的傅立叶变换然后求出一个整体和就可以了,那么对于函数的部分分量,我们只需要保证这个用来充当砖块的"波函数",在某个区间(用窗函数来滤波)内符合 那几个可积分和收敛的定义就可以了,因此傅立叶变换的"波"因子,就可以不使用三角函数,而是使用一系列从某些基本函数构造出来的函数族,只要这个基本函 数符合那些收敛和正交的条件就可以了。怎么构造这样的基本函数呢?sin(t)被加了方形窗以后,映射到频域是一堆无穷的散列脉冲,所以不能再用三角函数 了。我们要得到频率域收敛性好的函数族,能覆盖频率域的低端部分。说的远一点,如果是取数字信号的小波变换,那么基础小波要保证数字角频率是最大的 2Pi。利用小波进行离频谱分析的方法,不是像傅立叶级数那样求出所有的频率分量,也不是向傅立叶变换那样看频谱特性,而是做某种滤波,看看在某种数字角 频率的波峰值大概是多少。可以根据实际需要得到如干个数字序列。
我们采用(0,f),(f,2f),(2f,4f)这样的倍频关系来考察函数族的频率特性,那么对应的时间波形就是倍数扩展(且包含调制—所以才有频 谱搬移)的一系列函数族。频域是窗函数的基本函数,时域就是钟形函数。当然其他类型的小波,虽然频率域不是窗函数,但是仍然可用:因为小波积分求出来的变 换,是一个值,例如(0,f)里包含的总能量值,(f,2f)里面包含的总能量值。所以即使频域的分割不是用长方形而是其他的图形,对于结果来说影响不 大。同时,这个频率域的值,它的分辨率密度和时域
小波基函数的时间分辨率是冲突的(时域紧频域宽,时域宽频域紧),所以设计的时候受到海森堡测不准原理的 制约。Jpeg2000压缩就是小波:因为时频都是局部的,变换结果是数值点而不是向量,所以,计算复杂度从FFT的O(NlgN)下降到了O(N),性 能非常好。
]]>1)定义:图像是对客观存在对象的一种相似性的、生动性的描述或写真,是各种图形和影像的总称。
2)分类:按图像的明暗程度和空间坐标连续性,可将图像分为数字和模拟。
(1)模拟图像:又称光学图像,其空间坐标的明暗程度是连续变化的。计算机无法直接处理,属于可见图像。
(2)数字图像:空间坐标和灰度均不连续的、用离散的数学(一般整数)表示的图像,是图像的数字表示,能用于计算机处理。像素是其最小单位。
模拟图像连续可见,不便于用计算机存储,也不便于图像的存储、传输。数字图像不连续可见。
定义:图像处理是指对图像信息进行加工以满足人的视觉或应用需求的行为。包括图像变换、图像增强、图像恢复、图像压缩编码、图像的特征提取、形态学图像处理方法等。
Digital Image Processing 又称计算机图像处理,它是指将图像信号转换成数字信号并利用计算机对其进行处理的过程。
数字图像处理与计算机图形学的联系和区别:数字图像处理是对景物或图像的分析技术,是从图像到图像的处理过程。而计算机图形学是通过算法和程序在显示设备上构造图形,是从数据到图像的处理过程。
(1)处理精度高,再现性好;
(2)易于控制处理效果;
(3)处理具有多样性;
(4)处理技术综合性强;
(5)图像数据量庞大,处理费时。
(1)提高图像的视感质量。如进行图像的亮度、彩色变换,增强或抑制图像中的某些成分等。
(2)提取图像中所包含的某些特征和特殊信息。这个过程是模式识别或计算机视觉的预处理过程。提取的特征可以包括很多方面,如频域特征、灰度或颜色特征、边界特征、区域特征、纹理特征、形状特征、拓扑特征和关系结构等。
(3)图像数据的变换、编码和压缩,以便于图像的存储和传输。
(1)图像数字化:将一幅光学图像表示成一组数字,既不失真又便于计算机分析处理。主要包括图像的采样与量化。
(2)图像增强:用来改善图像的对比度,突出感兴趣的图像信息,提高图像的目视觉解释效果,它包括灰度拉伸、平滑、锐化、滤波、变换、彩色合成、代数运算、融合等。
(3)图像恢复/复原:去除和压抑成像过程中由各种因素影响而导致的图像失真。
(4)图像编码:简化图像的表示,压缩表示图像的数据,以便于存储和传输。
(5)图像的重建:由二维图像重建三维图像(如CT)。
(6)图像分割与特征提取
图像分割:用于从背景中分割出感兴趣的物体目标。分割的结果可作为监督分类的训练区。
图像的特征提取:包括形状特征、纹理特征、颜色特征等。
(7)图像分析:对图像中的不同对象进行分割、分类、识别、描述和解释。
(8)图像隐藏:
媒体信息的相互隐藏 数字水印 图像的信息伪装
图像理解(从图像到解释) 图像分析(从图像到数据) 图像处理(从图像到图像)
(1)抽象程度(从高到低);
(2)数据量(从小到大);
(3)语义(高层、中层、底层);
(4)操作对象(符号、目标、像素)。
图像处理:输入->处理(增强、复原、编码、压缩等)->输出。
图像分析:输入->预处理(增强、复原)->分割->特征提取->图像分类->类别、识别结果。 图像分析主要是对图像中感兴趣的目标进行检测和测量,以获得它们的客观信息,从而建立对图像的描述。
图像理解:输入->预处理->描述->分析和理解->解释。 重点是在图像的分析基础上再进一步研究图像中各个目标的性质和它们之间的相互联系,并得出对图像内容含义的理解以及对原来客观场景的解释,从而指导和规划行动。
(1)提高精度和处理速度;
(2)加强软件研究、开发新方法;
(3)加强边缘学科的研究工作、促进图像处理技术发展;
(4)加强理论研究;
(5)图像处理领域的标准化问题;
@本地磁盘姬
ohayou.aimo.moe
微博:@本地磁盘姬碟酱
Twitter:@AmyGreen
2019年01月02日
]]>