边缘检测算法2.-自定义差分算子

边缘检测,根据原理,只要是计算像素差异,都能产生边缘检测效果。

我根据一些 实际情况,定义一种很简单的差分算子:

  1. 计算 核 Width x Height 的最大值 pMax 和最小值 pMin
  2. 计算 pMax - pMin的值,然后作为 边缘响应点。

算子很容易懂,实现代码如下:

KLIB_DECL void edge_min_max(const Mat& _grayImg, Mat& edgeImg, const Size& kSize = Size(3, 3)){ Mat& grayImg = const_cast<Mat&>(_grayImg); edgeImg = Mat::zeros(grayImg.size(), CV_8U); int hs = kSize.height / 2; int ws = kSize.width / 2; int rows = edgeImg.rows; int cols = edgeImg.cols; int step = edgeImg.step; uchar* data = grayImg.data; uchar* dstData = edgeImg.data; for (int i = hs; i < rows - hs; ++i) { for (int j = ws; j < cols - ws; ++j) { int maxV = -1, minV = 256; for (int u = -hs; u < hs; ++u) for (int v = -ws; v < ws; ++v) { int val = data[(i + u)*step + (j + v)]; if (maxV < val) maxV = val; if (minV > val) minV = val; } dstData[ i*step + j] = maxV - minV; } }}

该算法,非常容易理解。可以用在一些需要强调 颜色突变的边缘区域,可以得到比较强的 边缘特征。

最好的学习方法,就是实践。所以,我一般都是 先写一个实用的算法,然后集成到 可视化平台。

算法流程

测试 2x2 核

Rect2x2

从效果看,有不错的 细小边缘,比Laplace 算子效果好一些。

Rect5x5

从效果看,有一种 边缘 膨胀的效果。

Rect7x7

核心改成 7x7,膨胀效果更剧烈。

以前,我用这种方式测试一些 颜色区别较大的边缘,比如 二维码 或者 条形码等 区域。

边缘强化

相当于一个 边缘检测,然后进行一定的膨胀效果。

膨胀操作,就是最大值滤波。 我目前定义的 边缘检测,就是 边缘检测 + 最大值滤波。

条形码

这个差分算法,属于自定义的。

其实,还可以根据一定的数学模型来定义 其他方式的 边缘检测,

比如:邻域 第二大值 和 邻域 倒数第二小 值得差异,消除一些噪声影响。

定义 高斯权重 的差分算子,……此处可以发散思维。

算法重在灵活运用,懂了很多概念,但是如果能够实际应用起来,那才是好的。如果,能够扩展起来,那就更好了。

(0)

相关推荐