Commit 37fb9c9a 张士柳

1 个父辈 592aab70
...@@ -911,10 +911,11 @@ namespace eyemLib_Sharp ...@@ -911,10 +911,11 @@ namespace eyemLib_Sharp
//"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS","" //"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS",""
//eyemCountObject(image, file.Replace(".png", ""), 35, 0, 100, 5, ref pNumObj, out tpDstImg); //eyemCountObject(image, file.Replace(".png", ""), 35, 0, 100, 5, ref pNumObj, out tpDstImg);
//eyemCountObjectIrregularParts(image, file.Replace(".png", ""), 0.1, "IP_LARGE_PARTS", 100, 7, ref pNumObj, out tpDstImg); //eyemCountObjectIrregularParts(image, file.Replace(".png", ""), 0.1, "IP_LARGE_PARTS", 100, 7, ref pNumObj, out tpDstImg);
//eyemCountObjectE(image, fileName, ref pNumObj, out tpDstImg);
eyemCountObjectIrregularPartsE(image, file.Replace(".png", ""), "IP_LARGE_PARTS", "D://批量测试图像2//template.png", 0.7, ref pNumObj, out tpDstImg); eyemCountObjectIrregularPartsE(image, file.Replace(".png", ""), "IP_LARGE_PARTS", "D://批量测试图像2//template.png", 0.7, ref pNumObj, out tpDstImg);
//int ipNum; EyemBarCode* tpResults; //int ipNum; EyemBarCode* tpResults;
//DataCodeHandle hObject; //DataCodeHandle hObject;
//int iRes = eyemDetectAndDecode(image, tpRoi, file.Replace(".png", ""), "QR_CODE|DATA_MATRIX|CODE_39|CODE_128", out hObject, out tpResults, out ipNum, false, 11, 5, 128, 256, 1d); //int iRes = eyemDetectAndDecode(image, tpRoi, file.Replace(".png", ""), "QR_CODE|DATA_MATRIX|CODE_39|CODE_128", out hObject, out tpResults, out ipNum, false, 11, 5, 128, 256, 0.5);
//for (int i = 0; i < ipNum; i++) //for (int i = 0; i < ipNum; i++)
//{ //{
// Console.WriteLine("类型:" + Marshal.PtrToStringAnsi(tpResults[i].hType) + ";坐标" + "[" + tpResults[i].iCenterX.ToString() + "," + tpResults[i].iCenterY.ToString() + "]" + ";角度:" + tpResults[i].dAngle.ToString("F4") + "," + ";内容:" + Marshal.PtrToStringAnsi(tpResults[i].hText) + ""); // Console.WriteLine("类型:" + Marshal.PtrToStringAnsi(tpResults[i].hType) + ";坐标" + "[" + tpResults[i].iCenterX.ToString() + "," + tpResults[i].iCenterY.ToString() + "]" + ";角度:" + tpResults[i].dAngle.ToString("F4") + "," + ";内容:" + Marshal.PtrToStringAnsi(tpResults[i].hText) + "");
......
...@@ -23,7 +23,6 @@ namespace eyemLib_Sharp ...@@ -23,7 +23,6 @@ namespace eyemLib_Sharp
//} //}
//EyemLib.eyemTest2(fileNames); //EyemLib.eyemTest2(fileNames);
foreach (var item in fileNames) foreach (var item in fileNames)
{ {
EyemLib.eyemReadImageTool(item); EyemLib.eyemReadImageTool(item);
......
...@@ -355,6 +355,37 @@ static void decodeMul(std::vector<WaitArea> &waitAreas, std::vector<std::string> ...@@ -355,6 +355,37 @@ static void decodeMul(std::vector<WaitArea> &waitAreas, std::vector<std::string>
//优先当作DM来解码,因为它比较快 //优先当作DM来解码,因为它比较快
if (!waitAreas[i].oneD) if (!waitAreas[i].oneD)
{ {
//DmtxMessage *msg;
//DmtxRegion *reg;
//DmtxImage *img = NULL;
//img = dmtxImageCreate(waitAreas[i].waitArea.data, waitAreas[i].waitArea.cols, waitAreas[i].waitArea.rows, DmtxPack8bppK);
//DmtxDecode *dec = dmtxDecodeCreate(img, 1);
////超时
//DmtxTime beginTime = dmtxTimeNow();
//DmtxTime timeout = dmtxTimeAdd(beginTime, 15);
//reg = dmtxRegionFindNext(dec, &timeout);
//if (NULL != reg)
//{
// //解码
// msg = dmtxDecodeMatrixRegion(dec, reg, DmtxUndefined);
// if (NULL != msg)
// {
// bDecode = true;
// ptResult = waitAreas[i].Pt;
// strResultType = "DATA_MATRIX";
// strResult = std::string(reinterpret_cast<const char *>(msg->output));
// //销毁资源
// dmtxMessageDestroy(&msg);
// }
// //解码失败
// dmtxRegionDestroy(&reg);
//}
//dmtxDecodeDestroy(&dec);
//dmtxImageDestroy(&img);
#pragma region 有问题
for (int d = waitAreas[i].C - iRangeC; d <= waitAreas[i].C + 2 * iRangeC; d += (int)dMinorStep) for (int d = waitAreas[i].C - iRangeC; d <= waitAreas[i].C + 2 * iRangeC; d += (int)dMinorStep)
{ {
cv::Mat binary; cv::Mat binary;
...@@ -400,6 +431,8 @@ static void decodeMul(std::vector<WaitArea> &waitAreas, std::vector<std::string> ...@@ -400,6 +431,8 @@ static void decodeMul(std::vector<WaitArea> &waitAreas, std::vector<std::string>
if (bDecode) if (bDecode)
break; break;
} }
#pragma endregion
} }
//如果未解码,判断可能是QR或者一维码或者DATA_MATRIX //如果未解码,判断可能是QR或者一维码或者DATA_MATRIX
if (!bDecode) if (!bDecode)
......
...@@ -51,6 +51,28 @@ static void calcRotateRect(std::vector<cv::Point2f> &vRect, std::vector<cv::Poin ...@@ -51,6 +51,28 @@ static void calcRotateRect(std::vector<cv::Point2f> &vRect, std::vector<cv::Poin
} }
} }
static cv::Mat getTplMat(cv::Mat &tplMat, double t)
{
const int tplH = tplMat.rows, tplW = tplMat.cols;
int width = cvRound((double)tplH * abs(sin(t * CV_PI / 180.)) + (double)tplW * abs(cos(t * CV_PI / 180.)));
int height = cvRound(ceil((double)tplW * abs(sin(t * CV_PI / 180.)) + (double)tplH * abs(cos(t * CV_PI / 180.))));
cv::Mat matx23f(2, 3, CV_64F);
matx23f = cv::getRotationMatrix2D(cv::Point2f((float)tplW / 2.0f - 0.5f, (float)tplH / 2.0f - 0.5f), t, 1.0);
//由于旋转产生的偏移
matx23f.ptr<double>(0)[2] += (float)(width - tplW) / 2.0;
matx23f.ptr<double>(1)[2] += (float)(height - tplH) / 2.0;
//旋转
cv::Mat tplMatD;
cv::warpAffine(tplMat, tplMatD, matx23f, cv::Size((int)width, (int)height), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar(0));
return tplMatD;
}
static int Otsu(int hist[]) static int Otsu(int hist[])
{ {
// Otsu's threshold algorithm // Otsu's threshold algorithm
...@@ -3778,9 +3800,9 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -3778,9 +3800,9 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
//图像裁剪 //图像裁剪
//环鸿&佳世达 //环鸿&佳世达
src = src(cv::Range(200, src.cols - 70), cv::Range(200, src.rows - 10)).clone(); //src = src(cv::Range(200, src.cols - 70), cv::Range(200, src.rows - 10)).clone();
//苏州公司&成都纬创 //苏州公司&成都纬创
//src = src(cv::Range(10, src.cols - 10), cv::Range(10, src.rows - 10)).clone(); src = src(cv::Range(10, src.cols - 10), cv::Range(10, src.rows - 10)).clone();
//图像尺寸 //图像尺寸
int X = src.cols, Y = src.rows; int X = src.cols, Y = src.rows;
...@@ -3944,7 +3966,6 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -3944,7 +3966,6 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
//使用大料算法 //使用大料算法
else if (strcmp(ccSubType, "IP_LARGE_PARTS") == 0) else if (strcmp(ccSubType, "IP_LARGE_PARTS") == 0)
{ {
//cv::imwrite("tplResult.png", srcPrev);
//二值化 //二值化
cv::threshold(srcPrev, binary, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU); cv::threshold(srcPrev, binary, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
...@@ -3952,34 +3973,42 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -3952,34 +3973,42 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
cv::morphologyEx(binary, srcPrevEx0, cv::MORPH_CLOSE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(95, 95))); cv::morphologyEx(binary, srcPrevEx0, cv::MORPH_CLOSE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(95, 95)));
//定位料盘中心 //定位料盘中心
std::vector<std::vector<cv::Point>> contoursFilter; std::vector<std::vector<cv::Point>> contours;
cv::findContours(srcPrevEx0, contoursFilter, cv::RETR_TREE, cv::CHAIN_APPROX_NONE); cv::findContours(srcPrevEx0, contours, cv::RETR_TREE, cv::CHAIN_APPROX_NONE);
cv::Mat image = cv::Mat::zeros(src8U.size(), CV_8UC1); cv::Mat srcPrevEx1 = cv::Mat::zeros(src8U.size(), CV_8UC1);
//填充料盘 //填充料盘
for (int i = 0; i < contoursFilter.size(); i++) for (int i = 0; i < contours.size(); i++)
{ {
cv::drawContours(image, contoursFilter, i, cv::Scalar(255), -1); cv::drawContours(srcPrevEx1, contours, i, cv::Scalar(255), -1);
} }
cv::Mat image = srcPrevEx1.clone();
//取中间部分,避免因料盘散开而导致中心定位错误
srcPrevEx1 -= srcPrevEx0;
//
cv::morphologyEx(srcPrevEx1, srcPrevEx1, cv::MORPH_CLOSE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(95, 95)));
//获取最大轮廓 //获取最大轮廓
cv::findContours(image, contoursFilter, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); cv::findContours(srcPrevEx1, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
if (contoursFilter.size() <= 0) if (contours.size() <= 0)
return FUNC_CANNOT_CALC; return FUNC_CANNOT_CALC;
std::vector<cv::Point> contourMax = contoursFilter[0]; std::vector<cv::Point> contourMax = contours[0]; double contourMaxArea = cv::contourArea(contourMax);
for (int i = 1; i < contoursFilter.size(); i++) for (int i = 1; i < contours.size(); i++)
{ {
if (cv::contourArea(contoursFilter[i]) > cv::contourArea(contourMax)) double contourArea = cv::contourArea(contours[i]);
if (contourArea > contourMaxArea)
{ {
contourMax = contoursFilter[i]; contourMax = contours[i];
contourMaxArea = contourArea;
} }
} }
//计算最大外接圆半径 //质心
float tFRadius = 0;
cv::minEnclosingCircle(contourMax, cv::Point2f(), tFRadius);
cv::Moments mu = cv::moments(contourMax); cv::Moments mu = cv::moments(contourMax);
cv::Point2f reelCenter(float(mu.m10 / mu.m00), float(mu.m01 / mu.m00)); cv::Point2f reelCenter(float(mu.m10 / mu.m00), float(mu.m01 / mu.m00));
...@@ -3988,6 +4017,20 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -3988,6 +4017,20 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
reelCenter.y = reelCenter.y > 0 && reelCenter.y < Y ? reelCenter.y : 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); cv::drawMarker(cc, reelCenter, cv::Scalar(0, 0, 238, 255), 1, 35, 2);
//计算料盘范围
cv::findContours(image, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
contourMax = contours[0]; contourMaxArea = cv::contourArea(contourMax);
for (int i = 1; i < contours.size(); i++)
{
double contourArea = cv::contourArea(contours[i]);
if (contourArea > contourMaxArea)
{
contourMax = contours[i];
contourMaxArea = contourArea;
}
}
cv::Rect rec = cv::boundingRect(contourMax); cv::Rect rec = cv::boundingRect(contourMax);
cv::Point tl, br, tr, bl; cv::Point tl, br, tr, bl;
...@@ -4010,29 +4053,16 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4010,29 +4053,16 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
//用于计数 //用于计数
cv::Mat matchParts(Y, X, CV_8UC1, cv::Scalar(0)); cv::Mat matchParts(Y, X, CV_8UC1, cv::Scalar(0));
double begin0 = (double)cv::getTickCount();
cv::parallel_for_(cv::Range(0, 4), [&](const cv::Range& range)->void { cv::parallel_for_(cv::Range(0, 4), [&](const cv::Range& range)->void {
for (int tpl = range.start; tpl < range.end; tpl++) for (int tpl = range.start; tpl < range.end; tpl++)
{ {
float t = icvDirections[tpl]; float t = icvDirections[tpl];
int width = cvRound((double)tplHeight * abs(sin(t * CV_PI / 180)) + (double)tplWidth * abs(cos(t * CV_PI / 180)));
int height = cvRound(ceil((double)tplWidth * abs(sin(t * CV_PI / 180)) + (double)tplHeight * abs(cos(t * CV_PI / 180))));
cv::Mat matx23f(2, 3, CV_64F);
matx23f = cv::getRotationMatrix2D(cv::Point2f((float)tplWidth / 2.0f - 0.5f, (float)tplHeight / 2.0f - 0.5f), t, 1.0);
//由于旋转产生的偏移
matx23f.ptr<double>(0)[2] += (float)(width - tplWidth) / 2.0;
matx23f.ptr<double>(1)[2] += (float)(height - tplHeight) / 2.0;
//旋转
cv::Mat tplMatD;
cv::warpAffine(tplMat, tplMatD, matx23f, cv::Size((int)width, (int)height), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar(0));
//模板匹配(仅处理料盘区域以提高速度) //模板匹配(仅处理料盘区域以提高速度)
cv::Mat tplResult0; cv::Mat tplResult0;
cv::matchTemplate(srcPrev(cv::Rect(tl, br)), tplMatD, tplResult0, cv::TM_CCOEFF_NORMED); cv::matchTemplate(srcPrev(cv::Rect(tl, br)), getTplMat(tplMat, t), tplResult0, cv::TM_CCOEFF_NORMED);
//分数大于0.7才当作元件处理 //分数大于0.7才当作元件处理
tplResult0 = cv::Mat(tplResult0 > dMinScore); tplResult0 = cv::Mat(tplResult0 > dMinScore);
...@@ -4063,11 +4093,22 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4063,11 +4093,22 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
} }
}); });
std::cout << "剩余耗时:" << 1000 * (static_cast<double>(cv::getTickCount()) - begin0) / cv::getTickFrequency() << std::endl;
///<追踪元件算法 ///<追踪元件算法
//标记初始区域 //标记初始区域
std::vector<cv::Point> matchPts; std::vector<cv::Point> matchPts;
cv::findNonZero(matchParts, matchPts); cv::findNonZero(matchParts, matchPts);
#ifdef _DEBUG
for (std::vector<cv::Point>::iterator itv = matchPts.begin(); itv != matchPts.end(); ++itv)
{
//cv::drawMarker(cc, cv::Point((*itv).x, (*itv).y), cv::Scalar(0, 255, 0, 255));
}
#endif
double begin1 = (double)cv::getTickCount();
//单个元件尺寸 //单个元件尺寸
double sinPartSize = (double)tplWidth*(double)tplHeight; double sinPartSize = (double)tplWidth*(double)tplHeight;
...@@ -4075,8 +4116,6 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4075,8 +4116,6 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
unsigned char *ucpTrackLabel = new unsigned char[Y*X](); unsigned char *ucpTrackLabel = new unsigned char[Y*X]();
cv::Mat trackMat(Y, X, CV_8UC1, ucpTrackLabel); cv::Mat trackMat(Y, X, CV_8UC1, ucpTrackLabel);
clock_t begin = clock();
//开始追踪 //开始追踪
for (std::vector<cv::Point>::iterator itv = matchPts.begin(); itv != matchPts.end(); ++itv) for (std::vector<cv::Point>::iterator itv = matchPts.begin(); itv != matchPts.end(); ++itv)
{ {
...@@ -4169,12 +4208,7 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4169,12 +4208,7 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
break; break;
} }
//标记当前位置 //标记当前位置
cv::circle(cc, cv::Point(startCenter), 2, cv::Scalar(0, 255, 0, 255), 1); cv::drawMarker(cc, cv::Point((*itv).x, (*itv).y), cv::Scalar(0, 165, 255, 255), cv::MARKER_DIAMOND, 5);
for (int j = 0; j < 4; j++)
{
cv::line(cc, points[j], points[(j + 1) % 4], cv::Scalar(0, 165, 255, 255), 1);
}
//无法计算元件间距 //无法计算元件间距
if (dChordL <= 0) { if (dChordL <= 0) {
...@@ -4248,6 +4282,8 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4248,6 +4282,8 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
trackCenter = cv::Point(vParts[0].Pos.x, vParts[0].Pos.y); trackCenter = cv::Point(vParts[0].Pos.x, vParts[0].Pos.y);
//更新扫描角度 //更新扫描角度
trackAngle = atan2((double)trackCenter.y - reelCenter.y, (double)trackCenter.x - reelCenter.x) * 180 / PI; trackAngle = atan2((double)trackCenter.y - reelCenter.y, (double)trackCenter.x - reelCenter.x) * 180 / PI;
//测试用
//cv::rectangle(cc, vParts[0].Rect, cv::Scalar(0, 0, 255, 255));
//纵向扫描 //纵向扫描
vParts.clear(); vParts.clear();
std::vector<cv::Point> trackLine; std::vector<cv::Point> trackLine;
...@@ -4286,6 +4322,40 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4286,6 +4322,40 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
} }
vParts.push_back(Track(iLimit, iPartSize, dMatch, it.pos(), vRect)); vParts.push_back(Track(iLimit, iPartSize, dMatch, it.pos(), vRect));
} }
//测试用
{
float b = (float)cos(trackAngle*PI / 180.)*0.5f;
float a = (float)sin(trackAngle*PI / 180.)*0.5f;
pts[0].x = (float)(trackCenter.x - a*trackLength * 2 - b*trackWidth * 4);
pts[0].y = (float)(trackCenter.y + b*trackLength * 2 - a*trackWidth * 4);
pts[1].x = (float)(trackCenter.x + a*trackLength * 2 - b*trackWidth * 4);
pts[1].y = (float)(trackCenter.y - b*trackLength * 2 - a*trackWidth * 4);
pts[2].x = (float)(2 * trackCenter.x - pts[0].x);
pts[2].y = (float)(2 * trackCenter.y - pts[0].y);
pts[3].x = (float)(2 * trackCenter.x - pts[1].x);
pts[3].y = (float)(2 * trackCenter.y - pts[1].y);
//
cv::RotatedRect r(pts[0], pts[1], pts[2]);
cv::rectangle(cc, r.boundingRect(), cv::Scalar(0, 255, 0, 255));
//
cv::Mat yyuc = srcPrev(cv::Rect(r.boundingRect().x - 27, r.boundingRect().y - 27, r.boundingRect().width + 54, r.boundingRect().height + 54));
//不同方向模板图像
cv::Mat yyu = getTplMat(tplMat, 90 - (trackAngle + 180));
//计算中心位置
cv::Mat tplResult0;
cv::matchTemplate(yyuc, yyu, tplResult0, cv::TM_CCOEFF_NORMED);
//
double minyyu, maxyyu; cv::Point minyyuloc, maxyyuloc;
cv::minMaxLoc(tplResult0, &minyyu, &maxyyu, &minyyuloc, &maxyyuloc);
cv::circle(cc, cv::Point(maxyyuloc.x + r.boundingRect().x + cvRound(yyu.cols / 2) - 27, maxyyuloc.y + r.boundingRect().y + cvRound(yyu.rows / 2) - 27), 1, cv::Scalar(0, 0, 255, 255), -1);
}
if (vParts.size() == 0) continue; if (vParts.size() == 0) continue;
//灰度极值认为是元件(最多问题出现在这里,加个条件判断矩形内是否存在已标记像素) //灰度极值认为是元件(最多问题出现在这里,加个条件判断矩形内是否存在已标记像素)
std::sort(vParts.begin(), vParts.end(), std::greater<Track>()); std::sort(vParts.begin(), vParts.end(), std::greater<Track>());
...@@ -4324,8 +4394,8 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4324,8 +4394,8 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
{ {
ptPoly.push_back(cv::Point(cvRound(mac.Rect[j].x), cvRound(mac.Rect[j].y))); ptPoly.push_back(cv::Point(cvRound(mac.Rect[j].x), cvRound(mac.Rect[j].y)));
} }
//画图显示 //标记当前位置
cv::circle(cc, trackCenter, 2, cv::Scalar(0, 255, 0, 255), 1); cv::drawMarker(cc, trackCenter, cv::Scalar(0, 255, 0, 255), cv::MARKER_DIAMOND, 5);
//for (int j = 0; j < 4; j++) //for (int j = 0; j < 4; j++)
//{ //{
...@@ -4333,8 +4403,6 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4333,8 +4403,6 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
//} //}
//标记已追踪 //标记已追踪
cv::fillConvexPoly(trackMat, ptPoly, cv::Scalar(255)); cv::fillConvexPoly(trackMat, ptPoly, cv::Scalar(255));
//标记计数
//cv::circle(matchParts, trackCenter, 0, cv::Scalar(255), 1);
} }
trackEnd = (!found); trackEnd = (!found);
} while (!trackEnd); } while (!trackEnd);
...@@ -4405,8 +4473,9 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4405,8 +4473,9 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
trackCenter = cv::Point(vParts[0].Pos.x, vParts[0].Pos.y); trackCenter = cv::Point(vParts[0].Pos.x, vParts[0].Pos.y);
//更新扫描角度 //更新扫描角度
trackAngle = atan2((double)trackCenter.y - reelCenter.y, (double)trackCenter.x - reelCenter.x) * 180 / PI; trackAngle = atan2((double)trackCenter.y - reelCenter.y, (double)trackCenter.x - reelCenter.x) * 180 / PI;
//纵向扫描 //向心/离心方向
vParts.clear(); vParts.clear();
//计算端点坐标
std::vector<cv::Point> trackLine; std::vector<cv::Point> trackLine;
drawLine(cc, reelCenter, trackCenter, cv::Scalar(0, 255, 255, 255), 1, trackLength, trackWidth * 2, trackLine); drawLine(cc, reelCenter, trackCenter, cv::Scalar(0, 255, 255, 255), 1, trackLength, trackWidth * 2, trackLine);
//更改纵向扫描方向,分两个方向 //更改纵向扫描方向,分两个方向
...@@ -4443,6 +4512,40 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4443,6 +4512,40 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
} }
vParts.push_back(Track(iLimit, iPartSize, dMatch, it.pos(), vRect)); vParts.push_back(Track(iLimit, iPartSize, dMatch, it.pos(), vRect));
} }
//测试用
{
float b = (float)cos(trackAngle*PI / 180.)*0.5f;
float a = (float)sin(trackAngle*PI / 180.)*0.5f;
pts[0].x = (float)(trackCenter.x - a*trackLength * 2 - b*trackWidth * 4);
pts[0].y = (float)(trackCenter.y + b*trackLength * 2 - a*trackWidth * 4);
pts[1].x = (float)(trackCenter.x + a*trackLength * 2 - b*trackWidth * 4);
pts[1].y = (float)(trackCenter.y - b*trackLength * 2 - a*trackWidth * 4);
pts[2].x = (float)(2 * trackCenter.x - pts[0].x);
pts[2].y = (float)(2 * trackCenter.y - pts[0].y);
pts[3].x = (float)(2 * trackCenter.x - pts[1].x);
pts[3].y = (float)(2 * trackCenter.y - pts[1].y);
//
cv::RotatedRect r(pts[0], pts[1], pts[2]);
cv::rectangle(cc, r.boundingRect(), cv::Scalar(0, 255, 0, 255));
//
cv::Mat yyuc = srcPrev(cv::Rect(r.boundingRect().x - 27, r.boundingRect().y - 27, r.boundingRect().width + 54, r.boundingRect().height + 54));
//不同方向模板图像
cv::Mat yyu = getTplMat(tplMat, 90 - (trackAngle + 180));
//计算中心位置
cv::Mat tplResult0;
cv::matchTemplate(yyuc, yyu, tplResult0, cv::TM_CCOEFF_NORMED);
//
double minyyu, maxyyu; cv::Point minyyuloc, maxyyuloc;
cv::minMaxLoc(tplResult0, &minyyu, &maxyyu, &minyyuloc, &maxyyuloc);
cv::circle(cc, cv::Point(maxyyuloc.x + r.boundingRect().x + cvRound(yyu.cols / 2) - 27, maxyyuloc.y + r.boundingRect().y + cvRound(yyu.rows / 2) - 27), 1, cv::Scalar(0, 0, 255, 255), -1);
}
if (vParts.size() == 0) continue; if (vParts.size() == 0) continue;
//灰度极值认为是元件 //灰度极值认为是元件
std::sort(vParts.begin(), vParts.end(), std::greater<Track>()); std::sort(vParts.begin(), vParts.end(), std::greater<Track>());
...@@ -4484,29 +4587,18 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4484,29 +4587,18 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
} }
//画图显示 //画图显示
cv::circle(cc, trackCenter, 2, cv::Scalar(0, 255, 0, 255), 1); cv::circle(cc, trackCenter, 2, cv::Scalar(0, 255, 0, 255), 1);
//for (int j = 0; j < 4; j++)
//{
// cv::line(cc, pts[j], pts[(j + 1) % 4], cv::Scalar(0, 165, 255, 255), 1);
//}
//标记Label //标记Label
cv::fillConvexPoly(trackMat, ptPoly, cv::Scalar(255)); cv::fillConvexPoly(trackMat, ptPoly, cv::Scalar(255));
//标记计数
//cv::circle(matchParts, trackCenter, 0, cv::Scalar(255), 1);
} }
trackEnd = (!found); trackEnd = (!found);
} while (!trackEnd); } while (!trackEnd);
} }
} }
//测试用
//cv::circle(cc, cv::Point(cvRound(trackCenter.x), cvRound(trackCenter.y)), 0, cv::Scalar(0, 255, 0, 255), -1);
} }
std::cout << "模板匹配耗时:" << clock() - begin << std::endl;
//释放资源 //释放资源
delete[] ucpTrackLabel; delete[] ucpTrackLabel;
ucpTrackLabel = NULL; ucpTrackLabel = NULL;
} }
//对单个器件间存在断裂使用,及料盘内圈颜色过深 //对单个器件间存在断裂使用,及料盘内圈颜色过深
else if (strcmp(ccSubType, "IP_LONG_PARTS") == 0) else if (strcmp(ccSubType, "IP_LONG_PARTS") == 0)
...@@ -5199,6 +5291,9 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -5199,6 +5291,9 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
} }
} }
//输出图像
//计数 //计数
std::vector<cv::Point> vLocations; std::vector<cv::Point> vLocations;
cv::findNonZero(binary, vLocations); cv::findNonZero(binary, vLocations);
...@@ -5231,9 +5326,8 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -5231,9 +5326,8 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
int eyemCreateTemplateImage(EyemImage tpImage, EyemRect tpRoi, const char *ccTplName) int eyemCreateTemplateImage(EyemImage tpImage, EyemRect tpRoi, const char *ccTplName)
{ {
cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage); cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage)\
(cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight));
cv::Mat tplMat = src(cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight));
return FUNC_OK; return FUNC_OK;
} }
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <io.h> #include <io.h>
#include <direct.h> #include <direct.h>
#include <fstream>
#include "eyemLib.h" #include "eyemLib.h"
constexpr double c = PI / 180.; constexpr double c = PI / 180.;
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!