物理の駅 by onsanai

Physics-station 研究で日々感じたことを忘れないための備忘録

OpenCVを使った画像内のピーク検出プログラム

ピークの周波数によって、途中の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);