源码:

源码作者:fivekogfx

源码地址:https://github.com/fiveko/fivekogfx

官网:https://fiveko.com/,上面有关于这款源码的一些说明

若github下载太慢,可翻到本文章结尾,使用国内网盘下载。

介绍:

这是一款简单的在浏览器上运行的图片视频处理器,用到了webgl和自定义shader。所有源码加起来约70kb,适合进阶学习者。废话不多说,直接进入文件结构吧。

index.html,preview.js,fivekogfx.js都是一些初始化的操作。

color.js

是对颜色空间的操作。

shaderSourceRGB2GREY用来将RGB图转换为灰度图,灰度化处理有多种处理方式:分量法 最大法,平均法,加权平均法,这里采用的是对R、G、B分量进行加权平均的算法:

0.2989R+ 0.5870G + 0.1140B

matlab使用的也是同样的算法。

shaderSourceRGB2YCbCr用来将RGB颜色空间转换为YCbCr颜色空间。YCbCr颜色空间用于数字视频系统中。

使用公式如下:

shaderSourceYCbCr2RGB当然就是将YCbCr颜色空间转换为RGB颜色空间了。使用公式如下:

shaderSourceSkinMask用来检测人的皮肤。

人的皮肤在一般的光照条件下,在YCbCr颜色空间上,符合如下公式

80≤Cb≤120 并且 133≤Cr≤173

这个算法来源于这篇文章。

shaderSourceRGB2XYZ用于将RGB转换为sRGB。对于 PC, Mac 或是 iOS & Android 来说,最为适合描述屏幕色域的就是 sRGB, Adobe RGB 和 P3

使用算法如下:

其逆为:

shaderSourceRGB2HSL使用的算法如下:

shaderSourceRGB2BIN用于将图像颜色二值化,greaterThan(x,y)在x > y时返回1否则0。

conv.js

用来处理卷积。卷积的概念请看这篇文章。与二维卷积不同的是,一维卷积还多了一个方向变量,来说明这个卷积究竟是行卷积还是列卷积。

Gauss.js

用来处理高斯模糊相关。高斯模糊的概念请看这篇文章。除了这篇文章提到的连续高斯卷积外,fivekogfx官网上还提到了一种离散高斯卷积,可以用来简单近似地模拟:

3x3卷积核

5x5卷积核

Harris.js

角点检测可以参考这篇文章。

在harris.js中,会两次调用shaderSource。第一次计算水平和垂直方向的梯度,然后将导数储存在dx和dy中。

float dx = ...
float dy = ...
gl_FragColor = vec4(dx*dx, dy*dy, dx*dy, 1.0);

然后计算每个像素的harris分数,这里会使用3x3像素格的平均值。

#define DET(_p)     ((_p).x*(_p).y - (_p).z*(_p).z)
#define TRACE(_p)   ((_p).x + (_p).y)

vec4 p = (GET_PIXEL(0, 0) + GET_PIXEL(-1, -1) + 
        GET_PIXEL(-1,  0) + GET_PIXEL(-1,  1) + 
        GET_PIXEL( 0,  1) + GET_PIXEL( 1,  1) + 
        GET_PIXEL( 1,  0) + GET_PIXEL( 1, -1) +
        GET_PIXEL( 0, -1)) / 9.0;
float k = 0.04;
float R = DET(p) - (k * (TRACE(p)*TRACE(p)));

最后使用NMS (non-maximum suppression)。

gl_FragColor = vec4(vec3(max(R, 0.0)), 1.0);

hough.js

霍夫圆环检测,用来检测图像上的圆。

一个圆可以用极坐标表示,其中(a,b)是圆心,R是半径,(x,y)则是圆上任意一点:

a = x - Rcosθ

b = y - Rsinθ

Hough Circel算法步骤如下:

  1. 使用边缘检测算法,得到那些在边缘上的那些点
  2. 对于每一个“边缘”点(x,y),根据半径R遍历以自身为圆心的圆,并给每一个在这个圆上的像素“加一分”。
  3. 最后,遍历整个图像,分数最高的那个像素就是圆心。

如果不知道半径R,则需要预先计算出半径的可能范围并遍历。更多可参考这篇文章。

lbp.js

局部二值检测模式,Local binary pattern (LBP),在机器视觉领域,是非常重要的一种特征。参考这篇文章。

logPolar.js

处理极坐标。

mean.js

均值滤波器,简单来说,就是将周围像素的平均值作为中心像素的值。这里使用的是如下形式:

请参考这篇文章。

morph.js

形态学算子。这里主要实现了腐蚀(erosion),可以消除一些小物体。以及膨胀(dilation),将原本相邻而不相连的两个物体变得相连。

请参考《数字图像处理》第九章。

npm.js

非极大值抑制,即Non-Maximum suppression,在检测一些物体时,可能会获得一些重叠的检测框,如下图左,我们需要一个算法保留其中最优的,而去掉其他重复的。

可以参考这篇文章。

sobel.js

sobel算子是边缘检测算法中使用的一种算子,一个离散微分算子 (discrete differentiation operator)。 它用来计算图像灰度函数的近似梯度。由两个分离的3x3卷积组成,参数相同。

请参考这篇文章。

symmetricnn.js

对称邻近均值滤波器,与均值滤波器相同的地方是,也使用一个滑动窗口,不同的是,前者会将中心像素周围的像素对称分成几组像素,每组两个。

如上图,颜色相同的像素即为一组,白色的为中心像素。在每一组像素中,选择与中心像素接近的像素加到结果中,另一个丢弃,而不是像均值滤波器那样全部加到结果中。

请参考这篇文章这篇文章

watershed.js

分水岭算法是一种图像区域分割法,在分割的过程中,它会把跟临近像素间的相似性作为重要的参考依据,从而将在空间位置上相近并且灰度值相近的像素点互相连接起来构成一个封闭的轮廓。可以参考这篇文章以及《数字图像处理》第10章。

最后

如果github下载太慢,可关注公众号,回复“five”获得源码国内网盘下载地址,以及持续跟踪最新消息!


clatterrr
60 声望6 粉丝