ピークの周波数によって、途中のBoxFilterとGaussianBlurのカーネルサイズは変えると良い。
背景の強度を求めて、有意度を求めるのがこのプログラムのミソである。
var size = new OpenCvSharp.Size(nbin, nbin);
Mat signal = Mat.Zeros(size, MatType.CV_32F);
var sig8U = new Mat(size, MatType.CV_8UC1);
{
float val = signal.Get<float>(iy, ix);
signal.Set(iy, ix, val + (float)(1.0));
}
Mat bg = new Mat(size, MatType.CV_32F);
Mat sub = new Mat(size, MatType.CV_32F);
Mat error = new Mat(size, MatType.CV_32F);
Mat sig = new Mat(size, MatType.CV_32F);
Mat buf = new Mat(size, MatType.CV_32F);
Cv2.BoxFilter(signal, signal, -1, new OpenCvSharp.Size(3, 3), null, false);
Cv2.GaussianBlur(signal, bg, new OpenCvSharp.Size(15, 15), -1);
Cv2.Subtract(signal, bg, sub);
Cv2.Add(signal, bg, buf);
Cv2.Sqrt(buf, error);
Cv2.Add(error, 0.01, buf);
Cv2.Divide(sub, buf, sig);
Cv2.ConvertScaleAbs(sig, sig8U, 255.0 / 5.0, 0);
Cv2.MinMaxLoc(sig, out double minval, out double maxval,
out OpenCvSharp.Point minloc, out OpenCvSharp.Point maxloc);
cv::Size size = cv::Size(width, width);
cv::Mat signal = cv::Mat::zeros(size, CV_32F);
cv::Mat sig8U = cv::Mat(size, CV_8UC1);
{
signal.at<float>(cv::Point(dx + width / 2, dy + width / 2)) += 1;
}
cv::Mat bg = cv::Mat(size, CV_32F);
cv::Mat sub = cv::Mat(size, CV_32F);
cv::Mat error = cv::Mat(size, CV_32F);
cv::Mat sig = cv::Mat(size, CV_32F);
cv::Mat buf = cv::Mat(size, CV_32F);
cv::boxFilter(signal, signal, -1, cv::Size(3, 3), cv::Point(-1,-1), false);
cv::GaussianBlur(signal, bg, cv::Size(15, 15), -1);
cv::subtract(signal, bg, sub);
cv::add(signal, bg, buf);
cv::sqrt(buf, error);
cv::add(error, 0.01, buf);
cv::divide(sub, buf, sig);
cv::convertScaleAbs(sig, sig8U, 255.0 / 5.0, 0);
double minval, maxval;
cv::Point minloc, maxloc;
cv::minMaxLoc(sig, &minval, &maxval,
&minloc, &maxloc);