HImage img("D:\\123.png");
HTuple ch = img.CountChannels();
HImage gray = (ch == 3) ? img.Rgb1ToGray() : img;
gray = gray.MedianImage("circle", 3, "mirrored");
// 边缘提取
HXLDCont contours = gray.EdgesSubPix(
"canny",
1,
20,
40);
// 看有多少条轮廓
HTuple numContours = contours.CountObj();
CString msg;
msg.Format(_T("轮廓数=%d"), numContours.I());
AfxMessageBox(msg);
if (numContours.I() < 1)
return;
// 取第一条轮廓
HXLDCont contour =
contours.SelectObj(1);
// 获取轮廓点
HTuple rows, cols;
contour.GetContourXld(
&rows,
&cols);
// 点数
int len = rows.Length();
CString str;
str.Format(
_T("轮廓点数=%d"),
len);
AfxMessageBox(str);
//---------------------------------
// 手动按 row 排序
//---------------------------------
std::vector<std::pair<double, double>> pts;
for (int i = 0; i < len; i++)
{
pts.push_back(
std::make_pair(
rows[i].D(),
cols[i].D()));
}
std::sort(
pts.begin(),
pts.end(),
[](const std::pair<double, double>& a,
const std::pair<double, double>& b)
{
return a.first < b.first;
});
//---------------------------------
// 分10段找峰值
//---------------------------------
int M = 10;
int step = (int)pts.size() / M;
std::vector<std::pair<double, double>> peaks;
for (int k = 0; k < M; k++)
{
int start = k * step;
int end =
(k == M - 1) ?
(int)pts.size() :
(k + 1) * step;
double maxY = -1e9;
double maxX = 0;
for (int i = start; i < end; i++)
{
if (pts[i].second > maxY)
{
maxY = pts[i].second;
maxX = pts[i].first;
}
}
peaks.push_back(
std::make_pair(maxX, maxY));
}
//---------------------------------
// 显示
//---------------------------------
HWindow win;
win.OpenWindow(
0,
0,
1000,
800,
0,
"visible",
"");
win.DispObj(gray);
win.SetColor("red");
for (size_t i = 0; i < peaks.size(); i++)
{
win.DispCross(
peaks[i].first,
peaks[i].second,
20,
0);
}
CString result;
result.Format(
_T("检测峰值=%d"),
(int)peaks.size());
AfxMessageBox(result);
}
catch (HException& e)
{
CString str;
str.Format(
_T("Error=%d\r\n%s"),
e.ErrorCode(),
CString(e.ErrorMessage().Text()));
AfxMessageBox(str);
}