Commit 8a5b3248 张士柳

1 个父辈 697c55cc
......@@ -924,7 +924,7 @@ namespace eyemLib_Sharp
//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);
//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);
......
......@@ -112,6 +112,7 @@
<PreprocessorDefinitions>_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<OpenMPSupport>true</OpenMPSupport>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
......
......@@ -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();
//图像金字塔
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;
......@@ -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);
//加载模板
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;
tplWidth = tplMat.cols, tplHeight = tplMat.rows;
......@@ -4122,12 +4134,20 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
cv::findNonZero(matchParts, matchPts);
#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)
{
//cv::drawMarker(cc, cv::Point((*itv).x, (*itv).y), cv::Scalar(0, 255, 0, 255));
}
#endif
//考虑留在外面,元件间距只需要计算一次(用二者结合的方式确定元件)
//标签图
cv::Mat trackMat(Y, X, CV_8UC1, cv::Scalar(0));
......@@ -4158,6 +4178,9 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
//标记计数
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 {
int iLimit, iPartSize;
double dMatchDeg;
......@@ -4185,42 +4208,75 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
//偏移角度(元件尺寸)
const double dOffset = (2 * asin(2 * trackLength / (2 * startRadius))) * 180. / PI;
//初始搜索角度,用以确定元件间距
//初始搜索角度,用以确定元件间距(默认15度范围内存在元件)
const double dScanRange = 15;
//追踪元件间距(弦长,可以尽量避免因个别器件偏离导致的追踪中断)
double dChordL = .0;
for (double t = startAngle + (dOffset / 1.5); t < startAngle + (dOffset / 1.5) + dScanRange; t += dMinorStep * 2)
double dChordL = .0; std::vector<Track> trackScore; bool expect = false;
for (double t = startAngle + dOffset; t < startAngle + dOffset + dScanRange; t += dMinorStep)
{
float x = float(reelCenter.x + startRadius*cos(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)),
cvRound(y + trackWidth * sin(angle)));
cv::Point2f pts[4];
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)
{
//计算元件间距(弦长)
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;
}
}
//初次满足分数阈值
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)));
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;
}
//标记当前位置
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) {
......@@ -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);
......@@ -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::min(r.boundingRect().y + r.boundingRect().height + cvRound(trackWidth), Y)));
cv::Mat yyuc = srcPrev(rr);
//不同方向模板图像(考虑实时更新模板图像或多角度模板,这样可能速度会下降)
//不同方向模板图像(考虑实时更新模板图像或多角度模板,活动模板,用定位到的区域选取当前位置的模板,这样可能速度会下降)
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::matchTemplate(yyuc, yyu, tplResult0, cv::TM_CCOEFF_NORMED);
cv::matchTemplate(srcPrev(rr), yyu, tplResult0, cv::TM_CCOEFF_NORMED);
//
double maxyyu; cv::Point maxyyuloc;
......@@ -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))
{
found = false;
//当分数过低采用其他方式确定是否真的终止
cv::drawMarker(cc, cv::Point(cvRound(trackCenter.x), cvRound(trackCenter.y)), cv::Scalar(0, 0, 255, 255), 0, 5);
}
else
{
......@@ -4358,7 +4419,7 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
}
//#pragma omp section
//逆时针追踪
//逆时针追踪
{
//追踪起点
cv::Point2f trackCenter(startCenter.x, startCenter.y);
......@@ -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::min(r.boundingRect().y + r.boundingRect().height + cvRound(trackWidth), Y)));
cv::Mat yyuc = srcPrev(rr);
//不同方向模板图像(考虑实时更新模板图像或多角度模板,这样可能速度会下降)
cv::Mat yyu = getTplMat(tplMat, 90 - (trackAngle + 180));
//判断待匹配图像是否小于模板图像
if (rr.width < yyu.cols || rr.height < yyu.rows)
continue;
//计算中心位置
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;
......@@ -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))
{
found = false;
//当分数过低采用其他方式确定是否真的终止
cv::drawMarker(cc, cv::Point(cvRound(trackCenter.x), cvRound(trackCenter.y)), cv::Scalar(0, 0, 255, 255), 0, 5);
}
else
{
......
......@@ -6,6 +6,7 @@
#define __EYEM_MISC_H
#include <io.h>
#include <omp.h>
#include <fstream>
#include <direct.h>
#include "eyemLib.h"
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!