分享

边缘检测算法4.-教你动手实现kirsch和robinson算子

 taotao_2016 2019-12-12

还有很多 边缘检测算子,在OpenCV中没有实现代码。

所以,我们得掌握看懂算法,然后扩展 算法得能力。

比如,我已知的一些 边缘检测核心:

边缘检测算法4.-教你动手实现kirsch和robinson算子

Kirsch 8方向算子

边缘检测算法4.-教你动手实现kirsch和robinson算子

Robinson 8方向算子

这个时候,需要我们自己去实现这个算子。

这些算子的具体介绍,其实就是 用 8个核,进行8个方向卷积,然后选取 最大值做响应。

比如 实现 kirsch 算子

KLIB_DECL void edge_kirsch_all_direction(const Mat& grayImg, Mat& edgeImg, double scale = 1, double delta = 0) { edgeImg.create(grayImg.size(), CV_16S); edgeImg.setTo(0); ushort* pDst = (ushort*)edgeImg.data; uchar* pSrc = grayImg.data; int w = grayImg.cols; int h = grayImg.rows; vector<int> vals(8); for(int i = 1; i< h - 1; ++i) for (int j = 1; j < w - 1; ++j) { uchar v1 = pSrc[(i - 1)*w + j - 1]; uchar v2 = pSrc[(i - 1)*w + j]; uchar v3 = pSrc[(i - 1)*w + j + 1]; uchar v4 = pSrc[ i*w + j - 1]; uchar v6 = pSrc[ i*w + j + 1]; uchar v7 = pSrc[(i + 1)*w + j - 1]; uchar v8 = pSrc[(i + 1)*w + j]; uchar v9 = pSrc[(i + 1)*w + j + 1]; vals[0] = 5 * (v1 + v2 + v3) - 3 * (v4 + v6 + v7 + v8 + v9); vals[1] = 5 * (v6 + v2 + v3) - 3 * (v4 + v1 + v7 + v8 + v9); vals[2] = 5 * (v6 + v9 + v3) - 3 * (v4 + v1 + v7 + v8 + v2); vals[3] = 5 * (v6 + v9 + v8) - 3 * (v4 + v1 + v7 + v3 + v2); vals[4] = 5 * (v7 + v9 + v8) - 3 * (v4 + v1 + v6 + v3 + v2); vals[5] = 5 * (v7 + v4 + v8) - 3 * (v9 + v1 + v6 + v3 + v2); vals[6] = 5 * (v7 + v4 + v1) - 3 * (v9 + v8 + v6 + v3 + v2); vals[7] = 5 * (v2 + v4 + v1) - 3 * (v9 + v8 + v6 + v3 + v7); int maxV = *(std::max_element(vals.begin(), vals.end())); pDst[i*w + j] = scale * maxV + delta; }}

调用的方法:

边缘检测算法4.-教你动手实现kirsch和robinson算子

调用 Kirsch算子

同理 实现 Robinson 算子:

KLIB_DECL void edge_robinson_all_direction(const Mat& grayImg, Mat& edgeImg, double scale = 1, double delta = 0){ edgeImg.create(grayImg.size(), CV_16S); edgeImg.setTo(0); ushort* pDst = (ushort*)edgeImg.data;  uchar* pSrc = grayImg.data; int w = grayImg.cols; int h = grayImg.rows; vector<int> vals(8); for (int i = 1; i < h - 1; ++i) for (int j = 1; j < w - 1; ++j) { uchar v1 = pSrc[(i - 1)*w + j - 1]; uchar v2 = pSrc[(i - 1)*w + j]; uchar v3 = pSrc[(i - 1)*w + j + 1]; uchar v4 = pSrc[i*w + j - 1]; uchar v6 = pSrc[i*w + j + 1]; uchar v7 = pSrc[(i + 1)*w + j - 1]; uchar v8 = pSrc[(i + 1)*w + j]; uchar v9 = pSrc[(i + 1)*w + j + 1]; vals[0] = 1 * (v1 + v3) + 2 * (v2 - v8) - 1 * (v7 + v9); vals[1] = 1 * (v2 + v6) + 2 * (v3 - v7) - 1 * (v4 + v8); vals[2] = 1 * (v3 + v9) + 2 * (v6 - v4) - 1 * (v1 + v7); vals[3] = 1 * (v6 + v8) + 2 * (v9 - v1) - 1 * (v2 + v4); vals[4] = 1 * (v7 + v9) + 2 * (v8 - v2) - 1 * (v1 + v3); vals[5] = 1 * (v4 + v8) + 2 * (v7 - v3) - 1 * (v2 + v6); vals[6] = 1 * (v1 + v7) + 2 * (v4 - v6) - 1 * (v3 + v9); vals[7] = 1 * (v2 + v4) + 2 * (v1 - v9) - 1 * (v8 + v6); int maxV = *(std::max_element(vals.begin(), vals.end())); pDst[i*w + j] = scale * maxV + delta; }}

调用的方法类似。

然后编译为一个 插件,加载到平台测试:

边缘检测算法4.-教你动手实现kirsch和robinson算子

Krisch cast模式

边缘检测算法4.-教你动手实现kirsch和robinson算子

Krisch abs模式

边缘检测算法4.-教你动手实现kirsch和robinson算子

Krish nono模式

测试 Robinson算子,效果类似:

边缘检测算法4.-教你动手实现kirsch和robinson算子

Robinson 算子 响应弱一些

这就是 其他人的博客里面 提到的 Kirsch 算子和 Robinson算子。

对比知道:

Laplace 边缘响应最弱

Sobel 边缘响应稍强

Robinson 边缘响应更强

Kirsch 边缘响应最强

希望大家学会了OpenCV之外的 边缘检测算子。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多