Opencv实现Halcon中的频域滤波相关函数(一)

gen_gauss_filter( : ImageGauss : Sigma1, Sigma2, Phi, Norm, Mode, Width, Height : )

算法介绍
gen_gauss_filter 在频域生成一个(可能是各向异性的)高斯滤波器。高斯滤波器在空间域的标准偏差(即平滑量)由 Sigma1 和 Sigma2 决定。Sigma1 是滤波器在空间域的主方向标准偏差,由角度 Phi 决定。为了实现滤波操作的最大整体效率,参数 Norm 可用来指定滤波器的归一化系数。如果使用 fft_generic 和 Norm = 'n',则可以避免在 FFT 中进行归一化处理。Mode 可用于确定滤波器直流项的位置,或滤波器是否应在实值 FFT 中使用。如果使用 fft_generic,则可以使用 “dc_edge ”来提高效率。如果使用 fft_image 和 fft_image_inv 进行滤波,则必须使用 Norm = 'none' 和 Mode = 'dc_center'。如果使用 rft_generic,则必须使用 Mode = 'rft'。

算法原理
    •    空间域高斯

G(x,y) = \exp\!\bigl(-\frac{x{\prime}^2}{2\Sigma_1^2} - \frac{y{\prime}^2}{2\Sigma_2^2}\bigr),
其中\begin{pmatrix}x{\prime}\\y{\prime}\end{pmatrix} = R_{-\Phi}\begin{pmatrix}x\\y\end{pmatrix}R_{-\Phi}为旋转矩阵。
    •    频域响应
连续情形下,傅里叶变换仍为高斯:\mathcal{F}\{G\}(u,v) = \exp\!\Bigl(-2\pi^2\,\bigl[\Sigma_1^2\,u{\prime}^2 + \Sigma_2^2\,v{\prime}^2\bigr]\Bigr),
其中\begin{pmatrix}u{\prime}\\v{\prime}\end{pmatrix} = R_{\Phi}\begin{pmatrix}u\\v\end{pmatrix}
    •    离散化、RFT 存储
    •    水平频率 u = k/W,只保留k=0\ldots W/2 。
    •    垂直频率 v = \begin{cases}j/H,&j\le H/2\\(j-H)/H,&j>H/2\end{cases},j=0\ldots H-1
    •    输出一个大小为 H\times (W/2+1) 的矩阵,直接与 rft_generic 的结果相乘即可完成滤波。

主要实现一下Mode:

    •    rft:只算半频谱,输出 H\times(W/2+1) 大小,DC 在边缘,给 rft_generic 用。
    •    dc_edge:输出全频谱 H\times W,DC 在 (0,0)(边缘),可配合任意 FFT 函数(如 fft_generic + Norm='n')直接乘。
    •    dc_center:输出全频谱 H\times W,DC 在中心 (H/2,W/2)。

代码:

void __cdecl GenGaussFilter(cv::Mat& ImageGauss, double Sigma1, double Sigma2, double Phi, const char* ccNorm, const char* ccMode, double Width, double Height)
{
	// 计算输出尺寸
	std::string Mode = std::string(ccMode);
	int WF = (Mode == "rft" ? (Width / 2 + 1) : Width);
	cv::Mat filt(Height, WF, CV_32F);

	double cosPhi = std::cos(Phi), sinPhi = std::sin(Phi);
	const double scale = -2.0 * CV_PI * CV_PI;
	for (int j = 0; j < Height; ++j) {
		// 计算垂直频率 v
		double v;
		if (Mode == "rft") {
			v = (j <= Height / 2) ? double(j) / Height : double(j - Height) / Height;
		}
		else if (Mode == "dc_edge") {
			v = (j <= Height / 2) ? double(j) / Height : double(j - Height) / Height;
		}
		else { // dc_center
			v = (j - Height / 2) / double(Height);
		}

		for (int k = 0; k < WF; ++k) {
			// 计算水平频率 u
			double u;
			if (Mode == "rft") {
				u = double(k) / Width;
			}
			else if (Mode == "dc_edge") {
				u = (k <= Width / 2) ? double(k) / Width : double(k - Width) / Width;
			}
			else { // dc_center
				u = (k - Width / 2) / double(Width);
			}

			// 在主/次方向上做旋转
			double u_rot = u * cosPhi + v * sinPhi;
			double v_rot = -u * sinPhi + v * cosPhi;

			// 频域高斯公式
			double expo = scale * (
				Sigma1 * Sigma1 * u_rot * u_rot +
				Sigma2 * Sigma2 * v_rot * v_rot
				);
			filt.at<float>(j, k) = float(std::exp(expo));
		}
	}
	// Apply normalization factor
	float f = 1. / (Width * Height);
	if (strcmp("n", ccNorm) == 0) {
		filt *= f;
	}
	filt.copyTo(ImageGauss);
}

结果和Halcon一致:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zzzzzzzzzzzzzz---

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值