边缘检测算法2.-自定义差分算子
边缘检测,根据原理,只要是计算像素差异,都能产生边缘检测效果。
我根据一些 实际情况,定义一种很简单的差分算子:
- 计算 核 Width x Height 的最大值 pMax 和最小值 pMin
- 计算 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)