前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >sobel算子实现

sobel算子实现

作者头像
全栈程序员站长
发布2022-09-14 11:02:07
1680
发布2022-09-14 11:02:07
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

原理:

在这里插入图片描述
在这里插入图片描述

实现:

代码语言:javascript
复制
/** * @description: 计算阶乘 * @param n 自然数 * @return 阶乘 */
int factorial(int n) 
{ 
   
	int fac = 1;
	if (n == 0)	return fac;
	for (int i = 1; i <= n; ++i)	fac *= i;
	return fac;
}

/** * @description: 获得Sobel平滑算子 * @param size 掩膜大小 * @return Sobel平滑算子 */
cv::Mat getSobelSmooth(int size)
{ 
   
	int n = size - 1;
    cv::Mat SobelSmoothoper = cv::Mat::zeros(size, 1, CV_32F);
	for (int k = 0; k <= n; k++)
	{ 
   
		float *pt = SobelSmoothoper.ptr<float>(0);
		pt[k] = factorial(n) / (factorial(k)*factorial(n - k));
	}
	return SobelSmoothoper;
}

/** * @description: 获得Sobel差分算子 * @param size 掩膜大小 * @return Sobel差分算子 */
cv::Mat getSobeldiff(int size)
{ 
   
    cv::Mat Sobeldiffoper = cv::Mat::zeros(cv::Size(size, 1), CV_32F);
    cv::Mat SobelSmooth = getSobelSmooth(size - 1);
	for (int k = 0; k < size; k++) 
	{ 
   
		if (k == 0)
			Sobeldiffoper.at<float>(0, k) = 1;
		else if (k == size - 1)
			Sobeldiffoper.at<float>(0, k) = -1;
		else
			Sobeldiffoper.at<float>(0, k) = SobelSmooth.at<float>(0, k) - SobelSmooth.at<float>(0, k - 1);
	}
	return Sobeldiffoper;
}

/** * @description: 卷积实现 * @param src 输入图像 * @param dst 输出图像 * @param kernel 卷积核 */
void conv2D(cv::Mat& src, cv::Mat& dst, cv::Mat kernel)
{ 
   
    cv::flip(kernel, kernel, -1);
    cv::filter2D(src, dst, src.depth(), kernel);
}

/** * @description: 可分离卷积———先水平方向卷积,后垂直方向卷积 * @param src 输入图像 * @param dst 输出图像 * @param kernel_X x方向卷积 * @param kernel_Y y方向卷积 */
void sepConv2D_X_Y(cv::Mat& src, cv::Mat& dst, cv::Mat kernel_X, cv::Mat kernel_Y)
{ 
   
    cv::Mat dst_kernel_X;
    conv2D(src, dst_kernel_X, kernel_X); 
    conv2D(dst_kernel_X, dst, kernel_Y); 
}

/** * @description: 可分离卷积———先垂直方向卷积,后水平方向卷积 * @param src 输入图像 * @param dst 输出图像 * @param kernel_Y y方向卷积 * @param kernel_X x方向卷积 */
void sepConv2D_Y_X(cv::Mat& src, cv::Mat& dst, cv::Mat kernel_Y, cv::Mat kernel_X)
{ 
   
    cv::Mat dst_kernel_Y;
    conv2D(src, dst_kernel_Y, kernel_Y); 
    conv2D(dst_kernel_Y, dst, kernel_X); 
}

/** * @description: Sobel算子边缘检测 * @param src 输入图像 * @param dst 输出图像 * @param size 掩膜大小 */
void sobel(cv::Mat& src, cv::Mat& dst, int size)
{ 
   
	cv::Mat SobelSmoothoper = getSobelSmooth(size); 
	cv::Mat Sobeldiffoper = getSobeldiff(size);		
	cv::Mat dst_X, dst_Y;
	
	sepConv2D_X_Y(src, dst_Y, SobelSmoothoper, Sobeldiffoper.t()); 
	sepConv2D_Y_X(src, dst_X, SobelSmoothoper.t(), Sobeldiffoper); 

	dst = abs(dst_X) + abs(dst_Y);
	cv::convertScaleAbs(dst, dst);
	cv::convertScaleAbs(dst_X, dst_X);
	cv::convertScaleAbs(dst_Y, dst_Y);
}

代码传送门:https://github.com/taifyang/OpenCV-algorithm

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/158976.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年7月1,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档