Commit 8a5b3248 张士柳

1 个父辈 697c55cc
...@@ -924,7 +924,7 @@ namespace eyemLib_Sharp ...@@ -924,7 +924,7 @@ namespace eyemLib_Sharp
//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); //eyemCountObjectE(image, fileName, ref pNumObj, out tpDstImg);
eyemCountObjectIrregularPartsE(image, file.Replace(".png", ""), "IP_LARGE_PARTS", "D://批量测试图像2//template.png", 0.6, ref pNumObj, out tpDstImg); eyemCountObjectIrregularPartsE(image, file.Replace(".png", ""), "IP_LARGE_PARTS", "D://批量测试图像模板文件//" + file.Replace(".png", "") + "_tpl.png", 0.65, ref pNumObj, out tpDstImg);
Bitmap bmp = eyemCvtToBitmap(tpDstImg); Bitmap bmp = eyemCvtToBitmap(tpDstImg);
......
...@@ -112,6 +112,7 @@ ...@@ -112,6 +112,7 @@
<PreprocessorDefinitions>_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<OpenMPSupport>true</OpenMPSupport>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
......
...@@ -3818,6 +3818,13 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -3818,6 +3818,13 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
//苏州公司&成都纬创 //苏州公司&成都纬创
//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();
//图像金字塔
if (true)
{
//cv::pyrDown(src, src, );
//cv::resize(src, src, cv::Size(src.cols / 4, src.rows / 4));
}
//图像尺寸 //图像尺寸
int X = src.cols, Y = src.rows; int X = src.cols, Y = src.rows;
...@@ -4059,7 +4066,12 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4059,7 +4066,12 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
tr = cv::Point(br.x, tl.y); bl = cv::Point(tl.x, br.y); tr = cv::Point(br.x, tl.y); bl = cv::Point(tl.x, br.y);
//加载模板 //加载模板
cv::Mat tplMat = cv::imread("D://批量测试图像2//template.png", -1); cv::Mat tplMat = cv::imread(tplName, -1);
if (true) {
//cv::pyrDown(tplMat, tplMat, cv::Size(tplMat.cols / 4, tplMat.rows / 4));
//cv::resize(tplMat, tplMat, cv::Size(tplMat.cols / 4, tplMat.rows / 4));
}
int tplWidth, tplHeight; int tplWidth, tplHeight;
tplWidth = tplMat.cols, tplHeight = tplMat.rows; tplWidth = tplMat.cols, tplHeight = tplMat.rows;
...@@ -4122,12 +4134,20 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4122,12 +4134,20 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
cv::findNonZero(matchParts, matchPts); cv::findNonZero(matchParts, matchPts);
#ifdef _DEBUG #ifdef _DEBUG
//计算元件间距(弦长)
/*
已知弦长L和半径R求角度2A:
sinA=(1/2)*L/R=L/(2R),2A=2asin(L/(2R)).
*/
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)
{ {
//cv::drawMarker(cc, cv::Point((*itv).x, (*itv).y), cv::Scalar(0, 255, 0, 255)); //cv::drawMarker(cc, cv::Point((*itv).x, (*itv).y), cv::Scalar(0, 255, 0, 255));
} }
#endif #endif
//考虑留在外面,元件间距只需要计算一次(用二者结合的方式确定元件)
//标签图 //标签图
cv::Mat trackMat(Y, X, CV_8UC1, cv::Scalar(0)); cv::Mat trackMat(Y, X, CV_8UC1, cv::Scalar(0));
...@@ -4158,6 +4178,9 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4158,6 +4178,9 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
//标记计数 //标记计数
lbMat.ptr<uint8_t>(cvRound(startCenter.y))[cvRound(startCenter.x)] = 255; lbMat.ptr<uint8_t>(cvRound(startCenter.y))[cvRound(startCenter.x)] = 255;
//标记当前位置
cv::drawMarker(cc, cv::Point((*itv).x, (*itv).y), cv::Scalar(0, 165, 255, 255), cv::MARKER_DIAMOND, 5);
struct Track { struct Track {
int iLimit, iPartSize; int iLimit, iPartSize;
double dMatchDeg; double dMatchDeg;
...@@ -4185,42 +4208,75 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4185,42 +4208,75 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
//偏移角度(元件尺寸) //偏移角度(元件尺寸)
const double dOffset = (2 * asin(2 * trackLength / (2 * startRadius))) * 180. / PI; const double dOffset = (2 * asin(2 * trackLength / (2 * startRadius))) * 180. / PI;
//初始搜索角度,用以确定元件间距 //初始搜索角度,用以确定元件间距(默认15度范围内存在元件)
const double dScanRange = 15; const double dScanRange = 15;
//追踪元件间距(弦长,可以尽量避免因个别器件偏离导致的追踪中断) //追踪元件间距(弦长,可以尽量避免因个别器件偏离导致的追踪中断)
double dChordL = .0; double dChordL = .0; std::vector<Track> trackScore; bool expect = false;
for (double t = startAngle + (dOffset / 1.5); t < startAngle + (dOffset / 1.5) + dScanRange; t += dMinorStep * 2) for (double t = startAngle + dOffset; t < startAngle + dOffset + dScanRange; t += dMinorStep)
{ {
float x = float(reelCenter.x + startRadius*cos(t*c)); float x = float(reelCenter.x + startRadius*cos(t*c));
float y = float(reelCenter.y + startRadius*sin(t*c)); float y = float(reelCenter.y + startRadius*sin(t*c));
//初次确定元件间距
const double angle = atan2((double)reelCenter.y - y, (double)reelCenter.x - x);
cv::Point p1 = cv::Point(cvRound(x + trackWidth * cos(angle)), cv::Point2f pts[4];
cvRound(y + trackWidth * sin(angle))); calcRotateRect(cv::Point2f(x, y), (float)t, (float)trackLength, (float)trackWidth, pts);
cv::Point p2 = cv::Point(cvRound(x + trackWidth * cos(angle + CV_PI)), //旋转矩形
cvRound(y + trackWidth * sin(angle + CV_PI))); cv::RotatedRect r(pts[0], pts[1], pts[2]);
cv::line(cc, p1, p2, cv::Scalar(0, 255, 0, 255)); //待匹配图像
cv::Rect rr(cv::Point2i(cv::max(r.boundingRect().x - cvRound(trackWidth), 0), \
cv::max(r.boundingRect().y - cvRound(trackWidth), 0)), \
cv::Point2i(cv::min(r.boundingRect().x + r.boundingRect().width + cvRound(trackWidth), X), \
cv::min(r.boundingRect().y + r.boundingRect().height + cvRound(trackWidth), Y)));
cv::LineIterator it(binary, p1, p2, 4); //测试
for (int n = 0; n < it.count; n++, ++it) cv::Mat df = srcPrev(rr);
//不同方向模板图像(考虑实时更新模板图像或多角度模板,这样可能速度会下降)
cv::Mat yyu = getTplMat(tplMat, 90 - (t + 180));
//待匹配图像小于模板图像的话不进行匹配
if (rr.width < yyu.cols || rr.height < yyu.rows)
continue;
//计算中心位置
cv::Mat tplResult0;
cv::matchTemplate(srcPrev(rr), yyu, tplResult0, cv::TM_CCOEFF_NORMED);
//
double maxyyu; cv::Point maxyyuloc;
cv::minMaxLoc(tplResult0, NULL, &maxyyu, NULL, &maxyyuloc);
//匹配阈值
if (maxyyu > dMinScore)
{ {
if ((binary.data)[(it.pos().x) + (it.pos().y)*X] == 255) //初次满足分数阈值
{ cv::Point2f trackCentert = cv::Point2f(float(maxyyuloc.x + rr.x + cvRound((float)yyu.cols / 2.0f)), \
//计算元件间距(弦长) float(maxyyuloc.y + rr.y + cvRound((float)yyu.rows / 2.0f)));
dChordL = 2.0 * startRadius*sin(((2.0 * asin((cv::norm(startCenter - cv::Point2f(x, y))) / (2.0 * startRadius)))\
* 180.0 / PI - dOffset / 2.0)*PI / 180.0 / 2.0);
break;
}
}
if (dChordL > 0) trackScore.push_back(Track(0, 0, maxyyu, (cv::Point)trackCentert, std::vector<cv::Point2f>()));
if (!expect)
expect = true;
}
if ((maxyyu < dMinScore) && expect)
break; break;
} }
//标记当前位置
cv::drawMarker(cc, cv::Point((*itv).x, (*itv).y), cv::Scalar(0, 165, 255, 255), cv::MARKER_DIAMOND, 5); //计算元件间距
if (trackScore.size() != 0) {
cv::Point ecpectPos = trackScore[0].Pos;
std::sort(trackScore.begin(), trackScore.end(), std::greater<Track>());
dChordL = 2.0 * startRadius*sin(((2.0 * asin((cv::norm(startCenter - cv::Point2f((float)ecpectPos.x, \
(float)ecpectPos.y))) / (2.0 * startRadius))) * 180.0 / PI - dOffset)*PI / 180.0 / 2.0);
//cv::drawMarker(cc, cv::Point(ecpectPos.x, ecpectPos.y), cv::Scalar(0, 255, 0, 255), 0, 5);
}
else {
//用先前的方式
}
//无法计算元件间距 //无法计算元件间距
if (dChordL <= 0) { if (dChordL <= 0) {
...@@ -4228,10 +4284,10 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4228,10 +4284,10 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
} }
//并行处理 //并行处理
//#pragma omp parallel sections //#pragma omp parallel sections
{ {
//(顺时针) //(顺时针)
//#pragma omp section //#pragma omp section
{ {
//追踪中心 //追踪中心
cv::Point2f trackCenter = cv::Point2f(startCenter.x, startCenter.y); cv::Point2f trackCenter = cv::Point2f(startCenter.x, startCenter.y);
...@@ -4296,15 +4352,18 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4296,15 +4352,18 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
cv::Point2i(cv::min(r.boundingRect().x + r.boundingRect().width + cvRound(trackWidth), X), \ cv::Point2i(cv::min(r.boundingRect().x + r.boundingRect().width + cvRound(trackWidth), X), \
cv::min(r.boundingRect().y + r.boundingRect().height + cvRound(trackWidth), Y))); cv::min(r.boundingRect().y + r.boundingRect().height + cvRound(trackWidth), Y)));
cv::Mat yyuc = srcPrev(rr); //不同方向模板图像(考虑实时更新模板图像或多角度模板,活动模板,用定位到的区域选取当前位置的模板,这样可能速度会下降)
//不同方向模板图像(考虑实时更新模板图像或多角度模板,这样可能速度会下降)
cv::Mat yyu = getTplMat(tplMat, 90 - (trackAngle + 180)); cv::Mat yyu = getTplMat(tplMat, 90 - (trackAngle + 180));
//测试用
//cv::rectangle(cc, rr, cv::Scalar(0, 0, 255, 255));
//判断待匹配图像是否小于模板图像
if (rr.width < yyu.cols || rr.height < yyu.rows)
continue;
//计算中心位置 //计算中心位置
cv::Mat tplResult0; cv::Mat tplResult0;
cv::matchTemplate(yyuc, yyu, tplResult0, cv::TM_CCOEFF_NORMED); cv::matchTemplate(srcPrev(rr), yyu, tplResult0, cv::TM_CCOEFF_NORMED);
// //
double maxyyu; cv::Point maxyyuloc; double maxyyu; cv::Point maxyyuloc;
...@@ -4333,6 +4392,8 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4333,6 +4392,8 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
if ((trackMat.ptr<uint8_t>(cvRound(trackCenter.y))[cvRound(trackCenter.x)] == 255) || (maxyyu < dMinScore*0.7)) if ((trackMat.ptr<uint8_t>(cvRound(trackCenter.y))[cvRound(trackCenter.x)] == 255) || (maxyyu < dMinScore*0.7))
{ {
found = false; found = false;
//当分数过低采用其他方式确定是否真的终止
cv::drawMarker(cc, cv::Point(cvRound(trackCenter.x), cvRound(trackCenter.y)), cv::Scalar(0, 0, 255, 255), 0, 5);
} }
else else
{ {
...@@ -4358,7 +4419,7 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4358,7 +4419,7 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
} }
//#pragma omp section //#pragma omp section
//逆时针追踪 //逆时针追踪
{ {
//追踪起点 //追踪起点
cv::Point2f trackCenter(startCenter.x, startCenter.y); cv::Point2f trackCenter(startCenter.x, startCenter.y);
...@@ -4423,14 +4484,16 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4423,14 +4484,16 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
cv::Point2i(cv::min(r.boundingRect().x + r.boundingRect().width + cvRound(trackWidth), X), \ cv::Point2i(cv::min(r.boundingRect().x + r.boundingRect().width + cvRound(trackWidth), X), \
cv::min(r.boundingRect().y + r.boundingRect().height + cvRound(trackWidth), Y))); cv::min(r.boundingRect().y + r.boundingRect().height + cvRound(trackWidth), Y)));
cv::Mat yyuc = srcPrev(rr);
//不同方向模板图像(考虑实时更新模板图像或多角度模板,这样可能速度会下降) //不同方向模板图像(考虑实时更新模板图像或多角度模板,这样可能速度会下降)
cv::Mat yyu = getTplMat(tplMat, 90 - (trackAngle + 180)); cv::Mat yyu = getTplMat(tplMat, 90 - (trackAngle + 180));
//判断待匹配图像是否小于模板图像
if (rr.width < yyu.cols || rr.height < yyu.rows)
continue;
//计算中心位置 //计算中心位置
cv::Mat tplResult0; cv::Mat tplResult0;
cv::matchTemplate(yyuc, yyu, tplResult0, cv::TM_CCOEFF_NORMED); cv::matchTemplate(srcPrev(rr), yyu, tplResult0, cv::TM_CCOEFF_NORMED);
// //
double maxyyu; cv::Point maxyyuloc; double maxyyu; cv::Point maxyyuloc;
...@@ -4458,6 +4521,8 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4458,6 +4521,8 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
if ((trackMat.ptr<uint8_t>(cvRound(trackCenter.y))[cvRound(trackCenter.x)] == 255) || (maxyyu < dMinScore*0.7)) if ((trackMat.ptr<uint8_t>(cvRound(trackCenter.y))[cvRound(trackCenter.x)] == 255) || (maxyyu < dMinScore*0.7))
{ {
found = false; found = false;
//当分数过低采用其他方式确定是否真的终止
cv::drawMarker(cc, cv::Point(cvRound(trackCenter.x), cvRound(trackCenter.y)), cv::Scalar(0, 0, 255, 255), 0, 5);
} }
else else
{ {
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define __EYEM_MISC_H #define __EYEM_MISC_H
#include <io.h> #include <io.h>
#include <omp.h>
#include <fstream> #include <fstream>
#include <direct.h> #include <direct.h>
#include "eyemLib.h" #include "eyemLib.h"
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!