ピークの周波数によって、途中の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); //Fill { float val = signal.Get<float>(iy, ix); signal.Set(iy, ix, val + (float)(1.0)); } Mat bg = new Mat(size, MatType.CV_32F); // local average Mat sub = new Mat(size, MatType.CV_32F); // signal - bg Mat error = new Mat(size, MatType.CV_32F); // error Mat sig = new Mat(size, MatType.CV_32F); // significance Mat buf = new Mat(size, MatType.CV_32F); // buffer Cv2.BoxFilter(signal, signal, -1, new OpenCvSharp.Size(3, 3), null, false); //3x3の膨張処理 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);//0.01は0除算を避けるため Cv2.ConvertScaleAbs(sig, sig8U, 255.0 / 5.0, 0);//>=5sigma = 255 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); //Fill { signal.at<float>(cv::Point(dx + width / 2, dy + width / 2)) += 1; } cv::Mat bg = cv::Mat(size, CV_32F); // local average cv::Mat sub = cv::Mat(size, CV_32F); // signal - bg cv::Mat error = cv::Mat(size, CV_32F); // error cv::Mat sig = cv::Mat(size, CV_32F); // significance cv::Mat buf = cv::Mat(size, CV_32F); // buffer cv::boxFilter(signal, signal, -1, cv::Size(3, 3), cv::Point(-1,-1), false); //3x3の膨張処理 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);//0.01は0除算を避けるため cv::convertScaleAbs(sig, sig8U, 255.0 / 5.0, 0);//>=5sigma = 255 double minval, maxval; cv::Point minloc, maxloc; cv::minMaxLoc(sig, &minval, &maxval, &minloc, &maxloc);