using System.Collections.Generic;
using System.Threading.Tasks;
namespace KassWitkinBandPassFilterTest
private static double tx(double centerX, double theta)
return centerX * Math.Cos(theta);
private static double ty(double centerY, double theta)
return centerY * Math.Sin(theta);
private static double u_star(double u, double centerX, double centerY, double theta)
double txx = tx(centerX, theta);
double tyy = ty(centerY, theta);
double cost = Math.Cos(theta);
double sint = Math.Sin(theta);
double costutxx = cost * (u + txx);
double sintutyy = sint * (u + tyy);
return costutxx + sintutyy;
private static double v_star(double u, double centerX, double centerY, double theta)
return (-1) * Math.Sin(theta) * (u + tx(centerX, theta)) + Math.Cos(theta) * (u + ty(centerY, theta));
public static double ApplyFilterOnOneCoord(double u, double v, double Dh, double Dv, double CenterX, double CenterY, double Theta, int N)
double u_star = KassWitkin.u_star(u, CenterX, CenterY, Theta);
double v_star = KassWitkin.v_star(u, CenterX, CenterY, Theta);
double uStarDh = (u_star / Dh);
double vStarDh = (v_star / Dv);
double sqrts = Math.Sqrt(uStarDh + vStarDh);
double power = Math.Pow(sqrts, 2 * N);
double divvy = (1 + 0.414 * power);
double returns = 1 / divvy;
public class KassWitkinBandpassFilter
public readonly int N = 4;
private double[, ] GetKernel(int width, int height)
double[, ] kernel2d = new double[width, height];
for (int i = 0; i < width; i++)
for (int j = 0; j < height; j++)
kernel2d[i, j] = (double)KassWitkin.ApplyFilterOnOneCoord(i, j, Dh, Dv, CenterX, CenterY, Theta, N);
public Complex[, ] ApplyFilter(Complex[, ] input)
int width = input.GetLength(0);
int height = input.GetLength(1);
double[, ] kernel = GetKernel(width, height);
Complex[, ] output = new Complex[width, height];
for (int i = 0; i < width; i++)
for (int j = 0; j < height; j++)
output[i, j] = input[i, j] * kernel[i, j];