Commit 92353bf2 张士柳

解决内圈多计数的问题;解决偶然间会计数出错的bug。

1 个父辈 d268845f
......@@ -304,23 +304,25 @@ namespace eyemLib_Sharp
#endregion
#region 项目
//圆形/矩形(红色)mark点定位
/// <summary>
/// 圆形/矩形(红色)mark点定位
/// </summary>
/// <param name="tpImage">输入图像</param>
/// <param name="dThreshold">二值化阈值</param>
/// <param name="tpCircle">结果</param>
/// <param name="bHighAccuracy">是否是高精度定位</param>
/// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemMarkerTracing(EyemImage tpImage, double dThreshold, ref EyemOcsFXYR tpCircle, bool bHighAccuracy = false);
#endregion
#region 通用
// Win32 memory copy function
[DllImport("ntdll.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern byte* memcpy(byte* dst, byte* src, int count);
//读取图像,支持彩色与多深度
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemImageRead(string filename, int iFalgs, out EyemImage tpImage);
private static extern int eyemImageRead(string filename, int iFlags, out EyemImage tpImage);
//释放图像资源
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern void eyemImageFree(ref EyemImage tpImage);
#endregion
//例程
......@@ -342,7 +344,7 @@ namespace eyemLib_Sharp
//eyemImageFree(ref image);
#endregion
#region //从网络读图
#region //从内存读图
//image = eyemCvtToEyemImage(bitmap);
......
......@@ -1721,8 +1721,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range range)->void {
for (int y = range.start; y < range.end; y++) {
for (int x = 0; x < X; x++) {
if ((src8U.data)[(x)+(y)*X] >= backThresh)
{
if ((src8U.data)[(x)+(y)*X] >= backThresh) {
(src8U.data)[(x)+(y)*X] = backThresh;
}
}
......@@ -2134,7 +2133,6 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
reelCenter.x = reelCenter.x > 0 && reelCenter.x < X ? reelCenter.x : 0;
reelCenter.y = reelCenter.y > 0 && reelCenter.y < Y ? reelCenter.y : 0;
cv::drawMarker(cc, reelCenter, cv::Scalar(0, 0, 238, 255), 1, 35, 2);
//包含未粘连器件
image = cv::Scalar(0);
std::vector<uchar> colors(nccomps + 1, 0);
......@@ -2209,10 +2207,10 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
return dMatchDeg < te.dMatchDeg;
}
};
////测试用
//if (strcmp(fileName, "6H107-R50892202006136I075-20200805100224") == 0) {
// std::cout << "_" << std::endl;
//}
//测试用
if (strcmp(fileName, "Img20210318120338") == 0) {
std::cout << "_" << std::endl;
}
//缩放比例
float coeff = 1.0f;
//填充值
......@@ -2220,7 +2218,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
//元件尺寸
const double taLength = tracingAnchors[tracingAnchors.size() / 2].Length; const double taHeight = tracingAnchors[tracingAnchors.size() / 2].Height;
//元件灰度值
float taMinGray;
double taMaxGray = 0.0;
//标签图
unsigned char *ucpTrackLabel = new unsigned char[Y*X]();
cv::Mat trackMat(Y, X, CV_8UC1, ucpTrackLabel);
......@@ -2232,14 +2230,14 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
//随机打乱顺序(降低计算错误dChordL的可能性,也为了测试在起点信息不同时的稳定性)
std::random_shuffle(tracingAnchors.begin(), tracingAnchors.end());
//开始确定起点(现在是用圆轨迹来追踪,不排除用螺旋线轨迹来追踪)
for (std::vector<TracingAnchor>::iterator itv = tracingAnchors.begin(); itv != tracingAnchors.end(); ++itv) {
for (std::vector<TracingAnchor>::iterator itvx = tracingAnchors.begin(); itvx != tracingAnchors.end(); ++itvx) {
//跳过执行
if (killProcessID == 0) {
logger.t("eyemCountObjectIrregularParts 点料阶段被跳过执行...");
break;
}
//起始位置信息
TracingAnchor ta = (*itv);
TracingAnchor ta = (*itvx);
//起始位置坐标
cv::Point2f startCenter(ta.Anchor.x, ta.Anchor.y);
//最小外包矩形
......@@ -2255,15 +2253,18 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
__mmpts[j].x = _matx[0] * (_pts[j].x - (float)ta.RBox.boundingRect().x) + _matx[1] * (_pts[j].y - (float)ta.RBox.boundingRect().y) + _matx[2];
__mmpts[j].y = _matx[3] * (_pts[j].x - (float)ta.RBox.boundingRect().x) + _matx[4] * (_pts[j].y - (float)ta.RBox.boundingRect().y) + _matx[5];
}
cv::Rect _r(cvFloor(std::min(std::min(std::min(__mmpts[0].x, __mmpts[1].x), __mmpts[2].x), __mmpts[3].x)),
cvFloor(std::min(std::min(std::min(__mmpts[0].y, __mmpts[1].y), __mmpts[2].y), __mmpts[3].y)),
cv::Rect _r(cvFloor(std::min(std::min(std::min(__mmpts[0].x, __mmpts[1].x), __mmpts[2].x), __mmpts[3].x)) + 1,
cvFloor(std::min(std::min(std::min(__mmpts[0].y, __mmpts[1].y), __mmpts[2].y), __mmpts[3].y)) + 1,
cvCeil(std::max(std::max(std::max(__mmpts[0].x, __mmpts[1].x), __mmpts[2].x), __mmpts[3].x)),
cvCeil(std::max(std::max(std::max(__mmpts[0].y, __mmpts[1].y), __mmpts[2].y), __mmpts[3].y))); _r.width -= _r.x - 1; _r.height -= _r.y - 1;
//已作标记
if (cv::countNonZero(ty(_r&cv::Rect(0, 0, ty.cols, ty.rows))) > 0)
if (cv::countNonZero((ty(_r&cv::Rect(0, 0, ty.cols, ty.rows)) > 250)) > 0)
continue;
////已做标记
//if (trackMat.ptr<uint8_t>(cvRound(startCenter.y))[cvRound(startCenter.x)] == 255) {
// continue;
//}
//获取模板图像(是否每次起点都计算模板,如果元件变形过大是否还会有用?)
if (tplMat.empty())
{
......@@ -2278,7 +2279,6 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
double t = atan2((double)startCenter.y - reelCenter.y, (double)startCenter.x - reelCenter.x) * 180.0 / PI;
//计算旋转角度
cv::Mat traceMat = srcPrev(_rLimits);
//这里计算得出的模板不是很对
float matx[6];
tplMat = getTrackMat(traceMat, t + 90.0, 0, matx);
......@@ -2355,8 +2355,8 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
if (MIN(tplMat.size().width, tplMat.size().height) < 12.0) {
coeff = 2.0f;
}
//
taMinGray = (float)cv::mean(tplMat)[0];
//最大
cv::minMaxLoc(tplMat, NULL, &taMaxGray);
}
//标记为已追踪过
std::vector<cv::Point> vT = { cv::Point(_pts[0]),cv::Point(_pts[1]) ,cv::Point(_pts[2]) ,cv::Point(_pts[3]) };
......@@ -2383,7 +2383,6 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
{
float x = float(reelCenter.x + startRadius*cos(t*c));
float y = float(reelCenter.y + startRadius*sin(t*c));
//防止超出图像范围
if (cvRound(x) < 0 || (cvRound(x) > X - 1) || cvRound(y) < 0 || (cvRound(y) > Y - 1)) {
break;
......@@ -2418,7 +2417,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
}
//没确定出元件间距一般为结尾处,继续从下一个起点计算弦长并开始追踪
if (dChordL <= 0.1) {
break;
continue;
}
//顺时针(是否并行取决于在windows下运行还是树莓派上)
{
......@@ -2441,7 +2440,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
cv::Point2f predicPos;
predicPos.x = reelCenter.x + (float)trackRadius*(float)cos((trackAngle + (trackOffset + partDist))*c);
predicPos.y = reelCenter.y + (float)trackRadius*(float)sin((trackAngle + (trackOffset + partDist))*c);
//如果追踪到图像外追踪终止
//如果追踪到图像外追踪终止
if (cvRound(predicPos.x) < 0 || (cvRound(predicPos.x) > X - 1) || cvRound(predicPos.y) < 0 || (cvRound(predicPos.y) > Y - 1)) {
trayEnd = true;
break;
......@@ -2509,12 +2508,13 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
cv::Mat mmRescaling;
cv::normalize(dst, mmRescaling, 1.0, 0.0, cv::NORM_MINMAX);
//测试用:模板匹配,为了尽量避免定位出错
//模板匹配,为了尽量避免定位出错
cv::Mat _tplMat;
tplMat.convertTo(_tplMat, CV_32FC1);
if (coeff > 1.0f) {
cv::resize(_tplMat, _tplMat, cv::Size(), coeff, coeff);
}
//考虑并行计算两个模板结果
cv::Mat tplResult0;
cv::matchTemplate(_traceMat, _tplMat, tplResult0, cv::TM_SQDIFF_NORMED);
......@@ -2554,19 +2554,21 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
}
}
//目标元件在小图中的位置
cv::Point2f maxLox;
//元件位置判断
if (_vParts.size() <= 0) {
//大概率终止
trayEnd = true;
}
else if (_vParts.size() == 1) {
//大概率不会出错
cv::Point2f maxLoc = cv::Point2f(_vParts[0].Pos.x, _vParts[0].Pos.y);
if (tRecF.contains(cv::Point2f(maxLoc.x / coeff, maxLoc.y / coeff))) {
//有可能会出错
maxLox = cv::Point2f(_vParts[0].Pos.x / coeff, _vParts[0].Pos.y / coeff);
if (tRecF.contains(maxLox)) {
//计算旋转前的坐标(即匹配的最终坐标)
float realX = 0.0f, realY = 0.0f;
realX = (float)rLimits.tl().x + ((maxLoc.x / coeff - matx[2])*matx[4] - (maxLoc.y / coeff - matx[5])*matx[1]) / (matx[0] * matx[4] - matx[3] * matx[1]);
realY = (float)rLimits.tl().y + ((maxLoc.x / coeff - matx[2])*matx[3] - (maxLoc.y / coeff - matx[5])*matx[0]) / (matx[1] * matx[3] - matx[4] * matx[0]);
realX = (float)rLimits.tl().x + ((maxLox.x - matx[2])*matx[4] - (maxLox.y - matx[5])*matx[1]) / (matx[0] * matx[4] - matx[3] * matx[1]);
realY = (float)rLimits.tl().y + ((maxLox.x - matx[2])*matx[3] - (maxLox.y - matx[5])*matx[0]) / (matx[1] * matx[3] - matx[4] * matx[0]);
//外包矩形顶点
cv::Point2f pts[4];
......@@ -2602,7 +2604,8 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
//排序
std::sort(__vParts.begin(), __vParts.end(), std::less<Track>());
cv::Point2f maxLox = cv::Point2f(__vParts[0].Pos.x / coeff, __vParts[0].Pos.y / coeff);
//在小图中的位置
maxLox = cv::Point2f(__vParts[0].Pos.x / coeff, __vParts[0].Pos.y / coeff);
//计算旋转前的坐标(即匹配的最终坐标)
float realX = 0.0f, realY = 0.0f;
......@@ -2627,12 +2630,12 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
//存在多个峰值,先判断分数最高是否位于理论位置
std::sort(_vParts.begin(), _vParts.end(), std::greater<Track>());
for (auto&_vPart : _vParts) {
cv::Point2f maxLoc = cv::Point2f(_vPart.Pos.x, _vPart.Pos.y);
if (tRecF.contains(cv::Point2f(maxLoc.x / coeff, maxLoc.y / coeff))) {
maxLox = cv::Point2f(_vPart.Pos.x / coeff, _vPart.Pos.y / coeff);
if (tRecF.contains(maxLox)) {
//计算旋转前的坐标(即匹配的最终坐标)
float realX = 0.0f, realY = 0.0f;
realX = (float)rLimits.tl().x + ((maxLoc.x / coeff - matx[2])*matx[4] - (maxLoc.y / coeff - matx[5])*matx[1]) / (matx[0] * matx[4] - matx[3] * matx[1]);
realY = (float)rLimits.tl().y + ((maxLoc.x / coeff - matx[2])*matx[3] - (maxLoc.y / coeff - matx[5])*matx[0]) / (matx[1] * matx[3] - matx[4] * matx[0]);
realX = (float)rLimits.tl().x + ((maxLox.x - matx[2])*matx[4] - (maxLox.y - matx[5])*matx[1]) / (matx[0] * matx[4] - matx[3] * matx[1]);
realY = (float)rLimits.tl().y + ((maxLox.x - matx[2])*matx[3] - (maxLox.y - matx[5])*matx[0]) / (matx[1] * matx[3] - matx[4] * matx[0]);
//外包矩形顶点
cv::Point2f pts[4];
......@@ -2671,7 +2674,8 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
//排序
std::sort(__vParts.begin(), __vParts.end(), std::less<Track>());
cv::Point2f maxLox = cv::Point2f(__vParts[0].Pos.x / coeff, __vParts[0].Pos.y / coeff);
//在小图中的位置
maxLox = cv::Point2f(__vParts[0].Pos.x / coeff, __vParts[0].Pos.y / coeff);
//计算旋转前的坐标(即匹配的最终坐标)
float realX = 0.0f, realY = 0.0f;
......@@ -2692,9 +2696,26 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
}
}
}
#ifdef _DEBUG
cc.ptr<cv::Vec4b>(cvRound(predicPos.y))[cvRound(predicPos.x)] = cv::Vec4b(100, 100, 238, 255);
#endif
if (!vParts.empty()) {
//显示用
//cv::Mat traceMat4, traceMat5;
//_traceMat.convertTo(traceMat4, CV_8U);
//traceMat.convertTo(traceMat5, CV_8U);
cv::Rect tRec_ = cv::Rect(cv::Point(cvFloor((((float)maxLox.x)*2.0f - (float)trackLength*2.0f) / 2.0f),
cvFloor((((float)maxLox.y)*2.0f - (float)trackWidth*4.0f) / 2.0f)),
cv::Size(cvRound(trackLength*2.0) + 2, cvRound(trackWidth*4.0) + 2))
&cv::Rect(0, 0, traceMat.cols, traceMat.rows);
//cv::rectangle(traceMat5, tRec_, cv::Scalar(0));
//cv::rectangle(traceMat4, _rr, cv::Scalar(0));
//当作一种辅助手段,无需设置太严格
double dmax;
cv::minMaxLoc(traceMat(tRec_).clone(), NULL, &dmax);
if (dmax < 0.75*taMaxGray) {
trayEnd = true;
}
}
break;
}
//追踪终止,选取下一个起点
......@@ -2831,12 +2852,13 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
cv::Mat mmRescaling;
cv::normalize(dst, mmRescaling, 1.0, 0.0, cv::NORM_MINMAX);
//测试用:模板匹配,为了尽量避免定位出错
//模板匹配,为了尽量避免定位出错
cv::Mat _tplMat;
tplMat.convertTo(_tplMat, CV_32FC1);
if (coeff > 1.0f) {
cv::resize(_tplMat, _tplMat, cv::Size(), coeff, coeff);
}
//考虑并行计算两个模板结果
cv::Mat tplResult0;
cv::matchTemplate(_traceMat, _tplMat, tplResult0, cv::TM_SQDIFF_NORMED);
......@@ -2874,20 +2896,21 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
_vParts.push_back(Track(0, 0, confidence, cv::Point2f((float)pt.x, (float)pt.y), std::vector<cv::Point2f>()));
}
}
//目标元件在小图中的位置
cv::Point2f maxLox;
//元件位置判断
if (_vParts.size() <= 0) {
//大概率终止
trayEnd = true;
}
else if (_vParts.size() == 1) {
maxLox = cv::Point2f(_vParts[0].Pos.x / coeff, _vParts[0].Pos.y / coeff);
//有可能会出错,当靠的太近可能只存在一个峰值
cv::Point2f maxLoc = cv::Point2f(_vParts[0].Pos.x, _vParts[0].Pos.y);
if (tRecF.contains(cv::Point2f(maxLoc.x / coeff, maxLoc.y / coeff))) {
if (tRecF.contains(maxLox)) {
//计算旋转前的坐标(即匹配的最终坐标)
float realX = 0.0f, realY = 0.0f;
realX = (float)rLimits.tl().x + ((maxLoc.x / coeff - matx[2])*matx[4] - (maxLoc.y / coeff - matx[5])*matx[1]) / (matx[0] * matx[4] - matx[3] * matx[1]);
realY = (float)rLimits.tl().y + ((maxLoc.x / coeff - matx[2])*matx[3] - (maxLoc.y / coeff - matx[5])*matx[0]) / (matx[1] * matx[3] - matx[4] * matx[0]);
realX = (float)rLimits.tl().x + ((maxLox.x - matx[2])*matx[4] - (maxLox.y - matx[5])*matx[1]) / (matx[0] * matx[4] - matx[3] * matx[1]);
realY = (float)rLimits.tl().y + ((maxLox.x - matx[2])*matx[3] - (maxLox.y - matx[5])*matx[0]) / (matx[1] * matx[3] - matx[4] * matx[0]);
//外包矩形顶点
cv::Point2f pts[4];
......@@ -2922,8 +2945,8 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
//排序
std::sort(__vParts.begin(), __vParts.end(), std::less<Track>());
cv::Point2f maxLox = cv::Point2f(__vParts[0].Pos.x / coeff, __vParts[0].Pos.y / coeff);
//小图中的定位坐标
maxLox = cv::Point2f(__vParts[0].Pos.x / coeff, __vParts[0].Pos.y / coeff);
//计算旋转前的坐标(即匹配的最终坐标)
float realX = 0.0f, realY = 0.0f;
realX = (float)rLimits.tl().x + ((maxLox.x - matx[2])*matx[4] - (maxLox.y - matx[5])*matx[1]) / (matx[0] * matx[4] - matx[3] * matx[1]);
......@@ -2941,24 +2964,18 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
{
cv::line(cc, predicBox[j], predicBox[(j + 1) % 4], cv::Scalar(0, 0, 238, 255), 1);
}
////显示用
//cv::Mat traceMat4, traceMat5;
//_traceMat.convertTo(traceMat4, CV_8U);
//traceMat.convertTo(traceMat5, CV_8U);
//cv::rectangle(traceMat5, rr, cv::Scalar(0));
//cv::rectangle(traceMat4, _rr, cv::Scalar(0));
}
}
else {
//存在定位出错的可能性,先判断分数最高是否位于理论位置
std::sort(_vParts.begin(), _vParts.end(), std::greater<Track>());
for (auto&_vPart : _vParts) {
cv::Point2f maxLoc = cv::Point2f(_vPart.Pos.x, _vPart.Pos.y);
if (tRecF.contains(cv::Point2f(maxLoc.x / coeff, maxLoc.y / coeff))) {
maxLox = cv::Point2f(_vPart.Pos.x / coeff, _vPart.Pos.y / coeff);
if (tRecF.contains(maxLox)) {
//计算旋转前的坐标(即匹配的最终坐标)
float realX = 0.0f, realY = 0.0f;
realX = (float)rLimits.tl().x + ((maxLoc.x / coeff - matx[2])*matx[4] - (maxLoc.y / coeff - matx[5])*matx[1]) / (matx[0] * matx[4] - matx[3] * matx[1]);
realY = (float)rLimits.tl().y + ((maxLoc.x / coeff - matx[2])*matx[3] - (maxLoc.y / coeff - matx[5])*matx[0]) / (matx[1] * matx[3] - matx[4] * matx[0]);
realX = (float)rLimits.tl().x + ((maxLox.x - matx[2])*matx[4] - (maxLox.y - matx[5])*matx[1]) / (matx[0] * matx[4] - matx[3] * matx[1]);
realY = (float)rLimits.tl().y + ((maxLox.x - matx[2])*matx[3] - (maxLox.y - matx[5])*matx[0]) / (matx[1] * matx[3] - matx[4] * matx[0]);
//外包矩形顶点
cv::Point2f pts[4];
......@@ -2996,8 +3013,8 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
//排序
std::sort(__vParts.begin(), __vParts.end(), std::less<Track>());
cv::Point2f maxLox = cv::Point2f(__vParts[0].Pos.x / coeff, __vParts[0].Pos.y / coeff);
//小图中的位置
maxLox = cv::Point2f(__vParts[0].Pos.x / coeff, __vParts[0].Pos.y / coeff);
//计算旋转前的坐标(即匹配的最终坐标)
float realX = 0.0f, realY = 0.0f;
realX = (float)rLimits.tl().x + ((maxLox.x - matx[2])*matx[4] - (maxLox.y - matx[5])*matx[1]) / (matx[0] * matx[4] - matx[3] * matx[1]);
......@@ -3017,13 +3034,25 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
}
}
}
#ifdef _DEBUG
cc.ptr<cv::Vec4b>(cvRound(predicPos.y))[cvRound(predicPos.x)] = cv::Vec4b(100, 100, 238, 255);
//for (int j = 0; j < 4; j++)
//{
// cv::line(cc, predicBox[j], predicBox[(j + 1) % 4], cv::Scalar(0, 165, 255, 255), 1);
//}
#endif
if (!vParts.empty()) {
////显示用
//cv::Mat traceMat4, traceMat5;
//_traceMat.convertTo(traceMat4, CV_8U);
//traceMat.convertTo(traceMat5, CV_8U);
//cv::rectangle(traceMat5, rr, cv::Scalar(0));
//cv::rectangle(traceMat4, _rr, cv::Scalar(0));
cv::Rect tRec_ = cv::Rect(cv::Point(cvFloor((((float)maxLox.x)*2.0f - (float)trackLength*2.0f) / 2.0f),
cvFloor((((float)maxLox.y)*2.0f - (float)trackWidth*4.0f) / 2.0f)),
cv::Size(cvRound(trackLength*2.0) + 2, cvRound(trackWidth*4.0) + 2))
&cv::Rect(0, 0, traceMat.cols, traceMat.rows);
//当作一种辅助手段,无需设置太严格
double dmax;
cv::minMaxLoc(traceMat(tRec_).clone(), NULL, &dmax);
if (dmax < 0.75*taMaxGray) {
trayEnd = true;
}
}
break;
}
//接着下一个起点
......@@ -3998,7 +4027,6 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
}
}
}
//计数
std::vector<cv::Point> idx;
cv::findNonZero(binary, idx);
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!