gen_sin_bandpass( : ImageFilter : Frequency, Norm, Mode, Width, Height : )
一、算法介绍
gen_sin_bandpass 算子生成一个二维带通滤波模板,形式上是一个 正弦调制的高斯波(类似于 Gabor filter)。
公式上类似于:
或
其中:
• 是沿 Direction 方向旋转后的坐标;
• f 是调制频率;
• 是相位,单位为弧度。
二、原理
根据Halcon形式构造频率域滤波器:
其中:
• :频域径向距离
• :中心截止频率
• 滤波器在半径 内 缓慢上升并下降为 0,峰值在
代码
// 分母用 N-1,正频率紧接负频率
inline float halcFreq(int k, int N)
{
int half = N / 2;
return (k <= half)
? float(k) / float(N - 1)
: float(k - N) / float(N - 1);
}
void __cdecl GenSinBandpass(cv::Mat& ImageBandpass, double Frequency, const char* cNorm, const char* cMode, int Width, int Height)
{
CV_Assert(Frequency >= 0.0f && Frequency <= 1.0f);
// rft 模式只保留半谱
int WF = (strcmp("rft", cMode) == 0) ? (Width / 2 + 1) : Width;
ImageBandpass.create(Height, WF, CV_32F);
for (int j = 0; j < Height; ++j)
{
float* row = ImageBandpass.ptr<float>(j);
// v 索引
int j0 = (strcmp("dc_center", cMode) == 0) ? ((j + Height / 2) % Height) : j;
float v = halcFreq(j0, Height);
for (int k = 0; k < WF; ++k)
{
int k0 = (strcmp("dc_center", cMode) == 0) ? ((k + Width / 2) % Width) : k;
float u = halcFreq(k0, Width);
// 径向频率
float r = std::sqrt(u * u + v * v);
float val = 0.0f;
// DC (r=0) = 0;当 0<r<=Frequency 时,H(r)=sin(arg),arg ∈ [0,π]
if (r > 0.0f && r <= Frequency) {
val = std::sinf(float(CV_PI) * (r / (float)Frequency));
}
row[k] = val;
}
}
// 应用归一化系数
float f = 1.F / (Width * Height);
if (strcmp("n", cNorm) == 0) {
ImageBandpass *= f;
}
}