Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
张士柳
/
eyemLib
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
图表
网络
创建新的问题
提交
问题看板
文件
提交
网络
比较
分支
标签
Commit 6c7e636f
由
张士柳
编写于
2022-03-18 16:51:29 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
无
1 个父辈
c7efc275
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
413 行增加
和
106 行删除
eyemLib-Sharp/EyemLib.cs
eyemLib-Sharp/UnmanagedBitmap.cs
eyemLib/eyemLib.h
eyemLib/eyemLib.rc
eyemLib/eyemMisc.cpp
eyemLib-Sharp/EyemLib.cs
查看文件 @
6c7e636
...
@@ -1227,34 +1227,6 @@ namespace eyemLib_Sharp
...
@@ -1227,34 +1227,6 @@ namespace eyemLib_Sharp
Stopwatch
sw
=
new
Stopwatch
();
Stopwatch
sw
=
new
Stopwatch
();
sw
.
Restart
();
sw
.
Restart
();
string
file
=
fileName
.
Split
(
new
string
[]
{
"\\"
},
StringSplitOptions
.
RemoveEmptyEntries
)[
2
];
string
file
=
fileName
.
Split
(
new
string
[]
{
"\\"
},
StringSplitOptions
.
RemoveEmptyEntries
)[
2
];
//string[] fileNames = Directory.GetFiles(@"C:\Users\nzslw\PycharmProjects\pythonProject\venv\data\AntBee\test\ants", "*.jpg", SearchOption.AllDirectories);
//return;
//foreach (var item in fileNames)
//{
// eyemBuildTrainFile(item, "D:\\标签识别\\" + item.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[4]);
//}
//return;
//for (int i = 0; i < fileNames.Length; i++)
//{
// string item = fileNames[i];
// string[] items = item.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries);
// FileInfo fi = new FileInfo(item);
// fi.MoveTo(@"D:\日志\" + (i+83).ToString() + ".png");
//}
//return;
//StreamWriter swr = new StreamWriter("D:\\val.txt", true);
//foreach (var item in random_shuffle)
//{
// string[] items = item.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries);
// swr.WriteLine("data/val_images/" + items[items.Length - 1]);
// swr.Flush();
//}
//return;
//eyemRenameFile(@"D:\训练数据集\20211021");
//return;
//flag = eyemInitNNDetector(".\\darknet\\cifar_resnet50.cfg", ".\\darknet\\cifar_resnet50.weights");
//flag = eyemInitNNDetector(".\\darknet\\cifar_resnet50.cfg", ".\\darknet\\cifar_resnet50.weights");
//if (flag == 0)
//if (flag == 0)
...
@@ -1388,8 +1360,6 @@ namespace eyemLib_Sharp
...
@@ -1388,8 +1360,6 @@ namespace eyemLib_Sharp
//eyemImageFree(ref search);
//eyemImageFree(ref search);
//return;
//return;
//flag = eyemNormalize(ref image);
//EyemImage image1 = new EyemImage(); EyemImage image2 = new EyemImage(); EyemImage image3 = new EyemImage();
//EyemImage image1 = new EyemImage(); EyemImage image2 = new EyemImage(); EyemImage image3 = new EyemImage();
//eyemDecompose(image, out image1, out image2, out image3);
//eyemDecompose(image, out image1, out image2, out image3);
...
@@ -1655,12 +1625,12 @@ namespace eyemLib_Sharp
...
@@ -1655,12 +1625,12 @@ namespace eyemLib_Sharp
int
[]
ipReelNum
=
new
int
[
4
];
int
[]
ipReelNum
=
new
int
[
4
];
//"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS","IP_SQUARE_PARTS","IP_DYNAMIC_PARTS","","IP_DYNAMIC_SP1","IP_DYNAMIC_SP2"
//"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS","IP_SQUARE_PARTS","IP_DYNAMIC_PARTS","","IP_DYNAMIC_SP1","IP_DYNAMIC_SP2"
//eyemCountObject(image, tpRoi, file.Replace(".png", ""), ipReelNum, out tpDstImg);
//eyemCountObject(image, tpRoi, file.Replace(".png", ""), ipReelNum, out tpDstImg);
//eyemCountObjectIrregularParts(image, tpRoi, file.Replace(".png", ""), "IP_L
ARGE
_PARTS", ipReelNum, out tpDstImg);
//eyemCountObjectIrregularParts(image, tpRoi, file.Replace(".png", ""), "IP_L
ONG
_PARTS", ipReelNum, out tpDstImg);
eyemCountObjectE
(
image
,
tpRoi
,
file
.
Replace
(
".png"
,
""
),
ipReelNum
,
out
tpDstImg
);
//
eyemCountObjectE(image, tpRoi, file.Replace(".png", ""), ipReelNum, out tpDstImg);
//eyemCountObjectIrregularPartsE(image, tpRoi, file.Replace(".png", ""), "D:\\模板文件\\" + "20210825095751-1.tpl", hModelID, ipReelNum, out tpDstImg);
//eyemCountObjectIrregularPartsE(image, tpRoi, file.Replace(".png", ""), "D:\\模板文件\\" + "20210825095751-1.tpl", hModelID, ipReelNum, out tpDstImg);
//算法选项
//算法选项
//std::string sOptions[8] = { "IP_DEFAULT_PARTS","IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS","IP_SQUARE_PARTS","","IP_DYNAMIC_SP1","IP_DYNAMIC_SP2" };
//std::string sOptions[8] = { "IP_DEFAULT_PARTS","IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS","IP_SQUARE_PARTS","","IP_DYNAMIC_SP1","IP_DYNAMIC_SP2" };
//eyemCountObjectIrregularPartsMultiopt(image, tpRoi, new int[] { 2, 2, 2, 2
}, ipReelNum, out tpDstImg);
eyemCountObjectIrregularPartsMultiopt
(
image
,
tpRoi
,
new
int
[]
{
0
,
0
,
0
,
0
},
ipReelNum
,
out
tpDstImg
);
//移除模板
//移除模板
//flag = eyemRemoveModelByName(hModelID, "D:\\模板文件及图像\\df871193-6632-48f9-abfe-540c3fc49c3f.tpl");
//flag = eyemRemoveModelByName(hModelID, "D:\\模板文件及图像\\df871193-6632-48f9-abfe-540c3fc49c3f.tpl");
...
...
eyemLib-Sharp/UnmanagedBitmap.cs
查看文件 @
6c7e636
...
@@ -28,7 +28,7 @@ namespace eyemLib_Sharp
...
@@ -28,7 +28,7 @@ namespace eyemLib_Sharp
eyemImageRead
(
fileName
,
-
1
,
out
image
);
eyemImageRead
(
fileName
,
-
1
,
out
image
);
}
}
/// <summary>
/// <summary>
/// 从Bitmap初始化Unmanaged新实例(GDI不支持除8位以外深度的图像;若要加载不同深度图像请
使用从文件名加载
)
/// 从Bitmap初始化Unmanaged新实例(GDI不支持除8位以外深度的图像;若要加载不同深度图像请
从文件名初始化
)
/// </summary>
/// </summary>
/// <param name="bitmap"></param>
/// <param name="bitmap"></param>
public
UnmanagedBitmap
(
Bitmap
bitmap
)
public
UnmanagedBitmap
(
Bitmap
bitmap
)
...
...
eyemLib/eyemLib.h
查看文件 @
6c7e636
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
#include <opencv.hpp>
#include <opencv.hpp>
#ifndef FILEVERSION
#ifndef FILEVERSION
#define FILEVERSION "2.4.8.
2
"
#define FILEVERSION "2.4.8.
4
"
#endif
#endif
#ifndef COPYRIGHT
#ifndef COPYRIGHT
...
...
eyemLib/eyemLib.rc
查看文件 @
6c7e636
此文件类型无法预览
eyemLib/eyemMisc.cpp
查看文件 @
6c7e636
...
@@ -1791,7 +1791,8 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -1791,7 +1791,8 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
int
backThresh
=
15
*
cvRound
((
double
)
maxIdx
[
0
]
-
processLevel
);
int
backThresh
=
15
*
cvRound
((
double
)
maxIdx
[
0
]
-
processLevel
);
//去掉背景
//去掉背景
cv
::
parallel_for_
(
cv
::
Range
(
0
,
Y
),
[
&
](
const
cv
::
Range
range
)
->
void
{
cv
::
parallel_for_
(
cv
::
Range
(
0
,
Y
),
[
&
](
const
cv
::
Range
range
)
->
void
{
for
(
int
y
=
range
.
start
;
y
<
range
.
end
;
y
++
)
{
for
(
int
y
=
range
.
start
;
y
<
range
.
end
;
y
++
)
{
for
(
int
x
=
0
;
x
<
X
;
x
++
)
{
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
;
(
src8U
.
data
)[(
x
)
+
(
y
)
*
X
]
=
backThresh
;
...
@@ -1801,6 +1802,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -1801,6 +1802,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
});
});
//增强到目标亮度方便显示
//增强到目标亮度方便显示
cc
+=
cv
::
Scalar
((
162
-
backThresh
),
(
162
-
backThresh
),
(
162
-
backThresh
));
cc
+=
cv
::
Scalar
((
162
-
backThresh
),
(
162
-
backThresh
),
(
162
-
backThresh
));
//cv::imwrite("cc.png",cc);
//料盘中心
//料盘中心
cv
::
Point
reelPt
;
cv
::
Point
reelPt
;
//去掉干扰
//去掉干扰
...
@@ -2182,7 +2184,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -2182,7 +2184,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
image
=
cv
::
Scalar
(
0
);
image
=
cv
::
Scalar
(
0
);
//当仅剩一圈的情况
//当仅剩一圈的情况
cv
::
Mat
srcPrevEx1
;
cv
::
Mat
srcPrevEx1
;
cv
::
morphologyEx
(
binary
,
srcPrevEx1
,
cv
::
MORPH_DILATE
,
cv
::
getStructuringElement
(
cv
::
MORPH_RECT
,
cv
::
Size
(
15
,
15
)));
cv
::
morphologyEx
(
binary
,
srcPrevEx1
,
cv
::
MORPH_DILATE
,
cv
::
getStructuringElement
(
cv
::
MORPH_RECT
,
cv
::
Size
(
31
,
31
)));
cv
::
findContours
(
srcPrevEx1
,
contoursFilter
,
cv
::
RETR_TREE
,
cv
::
CHAIN_APPROX_NONE
);
cv
::
findContours
(
srcPrevEx1
,
contoursFilter
,
cv
::
RETR_TREE
,
cv
::
CHAIN_APPROX_NONE
);
//闭合轮廓
//闭合轮廓
...
@@ -2198,10 +2200,10 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -2198,10 +2200,10 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
cv
::
findContours
(
image
,
contoursFilter
,
cv
::
RETR_EXTERNAL
,
cv
::
CHAIN_APPROX_NONE
);
cv
::
findContours
(
image
,
contoursFilter
,
cv
::
RETR_EXTERNAL
,
cv
::
CHAIN_APPROX_NONE
);
if
(
contoursFilter
.
empty
())
if
(
contoursFilter
.
empty
())
{
{
//当不足一圈,中心定位是不对的无法应用追踪算法
//当不足一圈,中心定位是不对的无法应用追踪算法
return
FUNC_CANNOT_CALC
;
return
FUNC_CANNOT_CALC
;
}
}
}
}
//过滤轮廓
//过滤轮廓
std
::
vector
<
cv
::
Point
>
contourMax
=
contoursFilter
[
0
];
std
::
vector
<
cv
::
Point
>
contourMax
=
contoursFilter
[
0
];
...
@@ -2215,6 +2217,9 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -2215,6 +2217,9 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
//计算最大外接圆半径
//计算最大外接圆半径
float
tFRadius
=
0
;
float
tFRadius
=
0
;
cv
::
minEnclosingCircle
(
contourMax
,
cv
::
Point2f
(),
tFRadius
);
cv
::
minEnclosingCircle
(
contourMax
,
cv
::
Point2f
(),
tFRadius
);
//
tFRadius
=
tFRadius
<
300
?
300
:
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
));
//画中心
//画中心
...
@@ -2297,6 +2302,36 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -2297,6 +2302,36 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
return
dMatchDeg
<
te
.
dMatchDeg
;
return
dMatchDeg
<
te
.
dMatchDeg
;
}
}
};
};
#ifdef _DEBUG
/** 链码节点(理想情况是一盘料首尾相接,对于追踪条件较好的料盘有用,但是对于存在乱七八糟的起点则难以追踪)
bJunction 是否是节点
iDirect 追踪方向(1 顺时针 -1 逆时针)
iStartOrEnd 起点或终点(0 起点 1 终点 2 中间节点)
iLinkID (每颗料都有的唯一编号)
iChainID 批次编号
iContPrev、iContCt、iContNxt 链接节点(指的是两个不同追踪流程连接处,用iLinkID表示,默认0)
vInfo 位置信息
ptCenter 元件中心坐标
*/
struct
Link
{
//是否是接口处
bool
bJunction
=
false
;
//方向(1 顺时针 -1 逆时针),起点或终点(0 起点 1 终点 2 中间),编号(总编号),批次编号
int
iDirect
,
iStartOrEnd
,
iLinkID
,
iChainID
;
//连接节点
int
iContPrev
,
iContCt
,
iContNxt
;
//iContPrev 上一个编号,iContCt 当前编号,iContNxt下一个编号
//位置信息
std
::
vector
<
cv
::
Point
>
vInfo
;
//中心
cv
::
Point
ptCenter
;
Link
()
{};
Link
(
bool
bJunction
,
int
iDirect
,
int
iStartOrEnd
,
int
iLinkID
,
int
iChainID
,
int
iContPrev
,
int
iContCt
,
int
iContNxt
,
cv
::
Point
ptCenter
,
std
::
vector
<
cv
::
Point
>
vInfo
)
:
bJunction
(
bJunction
),
iDirect
(
iDirect
),
iStartOrEnd
(
iStartOrEnd
),
iLinkID
(
iLinkID
),
iChainID
(
iChainID
),
iContPrev
(
iContPrev
),
iContCt
(
iContCt
),
iContNxt
(
iContNxt
),
ptCenter
(
ptCenter
),
vInfo
(
vInfo
)
{};
};
#endif
//缩放比例
//缩放比例
float
coeff
=
1.0
f
;
float
coeff
=
1.0
f
;
//填充值
//填充值
...
@@ -2310,6 +2345,11 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -2310,6 +2345,11 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
cv
::
Mat
trackMat
(
Y
,
X
,
CV_8UC1
,
ucpTrackLabel
);
cv
::
Mat
trackMat
(
Y
,
X
,
CV_8UC1
,
ucpTrackLabel
);
//计数图像
//计数图像
cv
::
Mat
lbMat
(
Y
,
X
,
CV_8UC1
,
cv
::
Scalar
(
0
));
cv
::
Mat
lbMat
(
Y
,
X
,
CV_8UC1
,
cv
::
Scalar
(
0
));
#ifdef _DEBUG //<编号图像(2022034:新增测试用)
int
tracingID
=
0
;
std
::
vector
<
Link
>
Links
;
cv
::
Mat
tracingChainMap
(
Y
,
X
,
CV_16SC3
,
cv
::
Scalar
(
-
32768
,
-
32768
,
-
32768
));
#endif
//定位图像
//定位图像
cv
::
Mat
srcPrevS
,
tplMat
;
//模板文件
cv
::
Mat
srcPrevS
,
tplMat
;
//模板文件
srcPrev
.
convertTo
(
srcPrevS
,
CV_32F
);
srcPrev
.
convertTo
(
srcPrevS
,
CV_32F
);
...
@@ -2322,6 +2362,8 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -2322,6 +2362,8 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
logger
.
t
(
"eyemCountObjectIrregularParts 点料阶段被跳过执行..."
);
logger
.
t
(
"eyemCountObjectIrregularParts 点料阶段被跳过执行..."
);
break
;
break
;
}
}
//20220314:新增测试用,起始编号等信息
auto
chainID
=
(
int
)
std
::
distance
(
tracingAnchors
.
begin
(),
itvx
)
+
1
;
//起始位置信息
//起始位置信息
TracingAnchor
ta
=
(
*
itvx
);
TracingAnchor
ta
=
(
*
itvx
);
//起始位置坐标
//起始位置坐标
...
@@ -2428,9 +2470,15 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -2428,9 +2470,15 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
//最大值
//最大值
cv
::
minMaxLoc
(
tplMat
,
NULL
,
&
taMaxGray
);
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
])
};
std
::
vector
<
cv
::
Point
>
vT
=
{
cv
::
Point
(
_pts
[
0
]),
cv
::
Point
(
_pts
[
1
])
,
cv
::
Point
(
_pts
[
2
])
,
cv
::
Point
(
_pts
[
3
])
};
cv
::
fillConvexPoly
(
trackMat
,
vT
,
cv
::
Scalar
(
255
));
cv
::
fillConvexPoly
(
trackMat
,
vT
,
cv
::
Scalar
(
255
));
#ifdef _DEBUG //<20220314:新增测试用
tracingID
++
;
Links
.
push_back
(
Link
(
false
,
1
,
0
,
0
,
chainID
,
-
1
,
0
,
tracingID
,
startCenter
,
vT
));
cv
::
fillConvexPoly
(
tracingChainMap
,
vT
,
cv
::
Scalar
(
0
,
chainID
,
Links
.
back
().
iContCt
));
#endif
//标记计数
//标记计数
lbMat
.
ptr
<
uint8_t
>
(
cvRound
(
startCenter
.
y
))[
cvRound
(
startCenter
.
x
)]
=
255
;
lbMat
.
ptr
<
uint8_t
>
(
cvRound
(
startCenter
.
y
))[
cvRound
(
startCenter
.
x
)]
=
255
;
//标记当前位置
//标记当前位置
...
@@ -2489,8 +2537,6 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -2489,8 +2537,6 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
if
(
dChordL
<=
2.1
)
{
if
(
dChordL
<=
2.1
)
{
continue
;
continue
;
}
}
//20220307测试用:对每次追踪进行编号?然后呢。。。
//顺时针(是否并行取决于在windows下运行还是树莓派上)
//顺时针(是否并行取决于在windows下运行还是树莓派上)
{
{
//追踪中心
//追踪中心
...
@@ -2506,7 +2552,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -2506,7 +2552,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
do
do
{
{
bool
found
=
true
;
bool
trayEnd
=
false
;
bool
found
=
true
;
bool
trayEnd
=
false
;
std
::
vector
<
Track
>
vParts
;
std
::
vector
<
Track
>
vParts
;
cv
::
Point2f
predictCenter
;
//20220316新增测试用
for
(
double
t
=
trackAngle
+
(
trackOffset
+
partDist
-
trackOffset
/
12.0
);
t
<
trackAngle
+
(
trackOffset
+
partDist
-
trackOffset
/
12.0
)
+
trackOffset
/
6.0
;
t
+=
dMinorStep
)
for
(
double
t
=
trackAngle
+
(
trackOffset
+
partDist
-
trackOffset
/
12.0
);
t
<
trackAngle
+
(
trackOffset
+
partDist
-
trackOffset
/
12.0
)
+
trackOffset
/
6.0
;
t
+=
dMinorStep
)
{
{
cv
::
Point2f
predicPos
;
cv
::
Point2f
predicPos
;
...
@@ -2517,6 +2563,8 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -2517,6 +2563,8 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
trayEnd
=
true
;
trayEnd
=
true
;
break
;
break
;
}
}
//20220316新增测试用
predictCenter
=
cv
::
Point2f
(
predicPos
.
x
,
predicPos
.
y
);
//感兴趣区域(向外扩展了一个元件,防止中心定位出现偏差或者料盘本身变形导致的偏差)
//感兴趣区域(向外扩展了一个元件,防止中心定位出现偏差或者料盘本身变形导致的偏差)
cv
::
Point2f
predictBox
[
4
];
cv
::
Point2f
predictBox
[
4
];
calcRotateRect
(
predicPos
,
(
float
)(
trackAngle
+
(
trackOffset
+
partDist
)),
(
float
)
trackLength
+
(
float
)
trackLength
,
(
float
)
trackWidth
+
(
float
)
trackWidth
,
predictBox
);
calcRotateRect
(
predicPos
,
(
float
)(
trackAngle
+
(
trackOffset
+
partDist
)),
(
float
)
trackLength
+
(
float
)
trackLength
,
(
float
)
trackWidth
+
(
float
)
trackWidth
,
predictBox
);
...
@@ -2791,6 +2839,10 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -2791,6 +2839,10 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
}
}
//追踪终止,选取下一个起点
//追踪终止,选取下一个起点
if
(
trayEnd
)
{
if
(
trayEnd
)
{
#ifdef _DEBUG
Links
.
back
().
iStartOrEnd
=
1
;
cv
::
drawMarker
(
cc
,
predictCenter
,
cv
::
Scalar
(
0
,
0
,
255
,
255
),
cv
::
MARKER_TILTED_CROSS
,
10
,
1
);
#endif
break
;
break
;
}
}
//更新位置
//更新位置
...
@@ -2803,10 +2855,60 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -2803,10 +2855,60 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
trackOffset
=
(
2
*
asin
(
2
*
trackLength
/
(
2
*
trackRadius
)))
*
180.0
/
PI
;
trackOffset
=
(
2
*
asin
(
2
*
trackLength
/
(
2
*
trackRadius
)))
*
180.0
/
PI
;
//更新元件间角度
//更新元件间角度
partDist
=
(
2
*
asin
(
dChordL
/
(
2
*
trackRadius
)))
*
180.0
/
PI
;
partDist
=
(
2
*
asin
(
dChordL
/
(
2
*
trackRadius
)))
*
180.0
/
PI
;
//追踪到了
重复
的元件
//追踪到了
已经标记
的元件
if
((
trackCenter
.
x
<
0
||
trackCenter
.
x
>
X
-
1
||
if
((
trackCenter
.
x
<
0
||
trackCenter
.
x
>
X
-
1
||
trackCenter
.
y
<
0
||
trackCenter
.
y
>
Y
-
1
)
||
trackMat
.
ptr
<
uint8_t
>
(
cvRound
(
trackCenter
.
y
))[
cvRound
(
trackCenter
.
x
)]
==
255
)
{
trackCenter
.
y
<
0
||
trackCenter
.
y
>
Y
-
1
)
||
trackMat
.
ptr
<
uint8_t
>
(
cvRound
(
trackCenter
.
y
))[
cvRound
(
trackCenter
.
x
)]
==
255
)
{
found
=
false
;
found
=
false
;
#ifdef _DEBUG //<20220314:测试用,获取连接节点junction,大量偏离如何处理
auto
linkInfo
=
tracingChainMap
.
ptr
<
cv
::
Vec3s
>
(
cvRound
(
trackCenter
.
y
))[
cvRound
(
trackCenter
.
x
)];
//如果是反方向判断是junction,如果是同方向并且批次一样只能是偏离
if
(
linkInfo
[
0
]
==
-
1
)
{
//修改编号
Links
.
back
().
iContNxt
=
linkInfo
[
2
];
Links
.
back
().
bJunction
=
true
;
}
else
{
//同批次且方向相同,判断是偏离
if
(
chainID
==
linkInfo
[
1
])
{
//修改结束标志
found
=
true
;
//判断不是junction而是追踪偏离,后续可以在这里增加偏离处理
Links
.
back
().
iStartOrEnd
=
1
;
//判断为偏离,采用理论位置代替
trackCenter
=
cv
::
Point2f
(
predictCenter
.
x
,
predictCenter
.
y
);
//更新扫描半径
trackRadius
=
cv
::
norm
(
trackCenter
-
reelCenter
);
//更新扫描角度
trackAngle
=
atan2
((
double
)
trackCenter
.
y
-
(
double
)
reelCenter
.
y
,
(
double
)
trackCenter
.
x
-
(
double
)
reelCenter
.
x
)
*
180.0
/
PI
;
//更新偏移量(元件角度大小)
trackOffset
=
(
2.0
*
asin
(
2.0
*
trackLength
/
(
2.0
*
trackRadius
)))
*
180.0
/
PI
;
//更新元件间角度
partDist
=
(
2.0
*
asin
(
dChordL
/
(
2.0
*
trackRadius
)))
*
180.0
/
PI
;
//计算元件位置
cv
::
Point2f
pts
[
4
];
calcRotateRect
(
trackCenter
,
(
float
)
trackAngle
,
(
float
)
trackLength
,
(
float
)
trackWidth
,
pts
);
//标记计数
lbMat
.
ptr
<
uint8_t
>
(
cvRound
(
trackCenter
.
y
))[
cvRound
(
trackCenter
.
x
)]
=
255
;
//标记为已追踪过
std
::
vector
<
cv
::
Point
>
vT
=
{
cv
::
Point
(
pts
[
0
]),
cv
::
Point
(
pts
[
1
])
,
cv
::
Point
(
pts
[
2
])
,
cv
::
Point
(
pts
[
3
])
};
cv
::
fillConvexPoly
(
trackMat
,
vT
,
cv
::
Scalar
(
255
));
#ifdef _DEBUG //<20220314:测试用
tracingID
++
;
Links
.
push_back
(
Link
(
false
,
-
1
,
2
,
Links
.
back
().
iContNxt
,
chainID
,
Links
.
back
().
iContCt
,
Links
.
back
().
iContNxt
,
tracingID
,
trackCenter
,
vT
));
cv
::
fillConvexPoly
(
tracingChainMap
,
vT
,
cv
::
Scalar
(
-
1
,
chainID
,
Links
.
back
().
iContCt
));
#endif
//用于显示
cv
::
circle
(
cc
,
trackCenter
,
2
,
cv
::
Scalar
(
0
,
255
,
0
,
255
),
1
);
#ifdef _DEBUG
for
(
int
j
=
0
;
j
<
4
;
j
++
)
{
cv
::
line
(
cc
,
pts
[
j
],
pts
[(
j
+
1
)
%
4
],
cv
::
Scalar
(
102
,
205
,
0
,
255
),
1
);
}
#endif
}
}
#endif
}
}
else
{
else
{
//计算元件位置
//计算元件位置
...
@@ -2817,6 +2919,12 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -2817,6 +2919,12 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
//标记为已追踪过
//标记为已追踪过
std
::
vector
<
cv
::
Point
>
vT
=
{
cv
::
Point
(
pts
[
0
]),
cv
::
Point
(
pts
[
1
])
,
cv
::
Point
(
pts
[
2
])
,
cv
::
Point
(
pts
[
3
])
};
std
::
vector
<
cv
::
Point
>
vT
=
{
cv
::
Point
(
pts
[
0
]),
cv
::
Point
(
pts
[
1
])
,
cv
::
Point
(
pts
[
2
])
,
cv
::
Point
(
pts
[
3
])
};
cv
::
fillConvexPoly
(
trackMat
,
vT
,
cv
::
Scalar
(
255
));
cv
::
fillConvexPoly
(
trackMat
,
vT
,
cv
::
Scalar
(
255
));
#ifdef _DEBUG //<20220314:测试用 标记编号
tracingID
++
;
Links
.
push_back
(
Link
(
false
,
1
,
2
,
Links
.
back
().
iContNxt
,
chainID
,
Links
.
back
().
iContCt
,
Links
.
back
().
iContNxt
,
tracingID
,
trackCenter
,
vT
));
cv
::
fillConvexPoly
(
tracingChainMap
,
vT
,
cv
::
Scalar
(
1
,
chainID
,
Links
.
back
().
iContCt
));
#endif
//用于显示
//用于显示
cv
::
circle
(
cc
,
trackCenter
,
2
,
cv
::
Scalar
(
0
,
255
,
0
,
255
),
1
);
cv
::
circle
(
cc
,
trackCenter
,
2
,
cv
::
Scalar
(
0
,
255
,
0
,
255
),
1
);
#ifdef _DEBUG
#ifdef _DEBUG
...
@@ -2836,7 +2944,15 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -2836,7 +2944,15 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
trackEnd
=
(
!
found
);
trackEnd
=
(
!
found
);
}
while
(
!
trackEnd
);
}
while
(
!
trackEnd
);
}
}
#ifdef _DEBUG //<调转方向
for
(
auto
&
lk
:
Links
)
{
if
(
lk
.
iChainID
==
chainID
)
{
lk
.
iContPrev
=
tracingID
;
break
;
}
}
#endif
//逆时针
//逆时针
{
{
//追踪起点
//追踪起点
...
@@ -2853,7 +2969,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -2853,7 +2969,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
do
do
{
{
bool
found
=
true
;
bool
trayEnd
=
false
;
bool
found
=
true
;
bool
trayEnd
=
false
;
std
::
vector
<
Track
>
vParts
;
std
::
vector
<
Track
>
vParts
;
cv
::
Point2f
predictCenter
;
//20220316新增测试用
for
(
double
t
=
trackAngle
-
(
trackOffset
+
partDist
-
trackOffset
/
12.0
);
t
>
trackAngle
-
(
trackOffset
+
partDist
-
trackOffset
/
12.0
)
-
trackOffset
/
6.0
;
t
-=
dMinorStep
)
for
(
double
t
=
trackAngle
-
(
trackOffset
+
partDist
-
trackOffset
/
12.0
);
t
>
trackAngle
-
(
trackOffset
+
partDist
-
trackOffset
/
12.0
)
-
trackOffset
/
6.0
;
t
-=
dMinorStep
)
{
{
cv
::
Point2f
predicPos
;
cv
::
Point2f
predicPos
;
...
@@ -2864,6 +2980,8 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -2864,6 +2980,8 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
trayEnd
=
true
;
trayEnd
=
true
;
break
;
break
;
}
}
//20220316新增测试用
predictCenter
=
cv
::
Point2f
(
predicPos
.
x
,
predicPos
.
y
);
//感兴趣区域(向外扩展了一个元件,防止中心定位出现偏差或者料盘本身变形导致的偏差)
//感兴趣区域(向外扩展了一个元件,防止中心定位出现偏差或者料盘本身变形导致的偏差)
cv
::
Point2f
predicBox
[
4
];
cv
::
Point2f
predicBox
[
4
];
calcRotateRect
(
predicPos
,
(
float
)(
trackAngle
-
(
trackOffset
+
partDist
)),
(
float
)
trackLength
*
2.0
f
,
(
float
)
trackWidth
*
2.0
f
,
predicBox
);
calcRotateRect
(
predicPos
,
(
float
)(
trackAngle
-
(
trackOffset
+
partDist
)),
(
float
)
trackLength
*
2.0
f
,
(
float
)
trackWidth
*
2.0
f
,
predicBox
);
...
@@ -3128,6 +3246,10 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -3128,6 +3246,10 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
}
}
//接着下一个起点
//接着下一个起点
if
(
trayEnd
)
{
if
(
trayEnd
)
{
#ifdef _DEBUG //<修改结束标志
Links
.
back
().
iStartOrEnd
=
1
;
cv
::
drawMarker
(
cc
,
predictCenter
,
cv
::
Scalar
(
0
,
0
,
255
,
255
),
cv
::
MARKER_TILTED_CROSS
,
10
,
1
);
#endif
break
;
break
;
}
}
//更新位置
//更新位置
...
@@ -3144,6 +3266,59 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -3144,6 +3266,59 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
if
((
trackCenter
.
x
<
0
||
trackCenter
.
x
>
X
-
1
||
if
((
trackCenter
.
x
<
0
||
trackCenter
.
x
>
X
-
1
||
trackCenter
.
y
<
0
||
trackCenter
.
y
>
Y
-
1
)
||
trackMat
.
ptr
<
uint8_t
>
(
cvRound
(
trackCenter
.
y
))[
cvRound
(
trackCenter
.
x
)]
==
255
)
{
trackCenter
.
y
<
0
||
trackCenter
.
y
>
Y
-
1
)
||
trackMat
.
ptr
<
uint8_t
>
(
cvRound
(
trackCenter
.
y
))[
cvRound
(
trackCenter
.
x
)]
==
255
)
{
found
=
false
;
found
=
false
;
#ifdef _DEBUG //<20220315:增加测试用
auto
linkInfo
=
tracingChainMap
.
ptr
<
cv
::
Vec3s
>
(
cvRound
(
trackCenter
.
y
))[
cvRound
(
trackCenter
.
x
)];
//如果是反方向判断是junction,如果是同方向并且是同一批次只能是偏离,如果不同批次表明中间漏了许多但不能做处理
if
(
linkInfo
[
0
]
==
1
)
{
//判断为junction
auto
lk
=
Links
[
linkInfo
[
2
]];
auto
bk
=
Links
.
back
();
Links
.
back
().
iContNxt
=
linkInfo
[
2
];
Links
.
back
().
bJunction
=
true
;
}
else
{
//满足同方向并且是同批次的,说明一定是偏离
if
(
chainID
==
linkInfo
[
1
])
{
//修改结束标志
found
=
true
;
//判断不是junction而是追踪偏离,后续可以在这里增加偏离处理
Links
.
back
().
iStartOrEnd
=
1
;
//判断为偏离,采用理论位置代替
trackCenter
=
cv
::
Point2f
(
predictCenter
.
x
,
predictCenter
.
y
);
//更新扫描半径
trackRadius
=
cv
::
norm
(
trackCenter
-
reelCenter
);
//更新扫描角度
trackAngle
=
atan2
((
double
)
trackCenter
.
y
-
(
double
)
reelCenter
.
y
,
(
double
)
trackCenter
.
x
-
(
double
)
reelCenter
.
x
)
*
180.0
/
PI
;
//更新偏移量(元件角度大小)
trackOffset
=
(
2.0
*
asin
(
2.0
*
trackLength
/
(
2.0
*
trackRadius
)))
*
180.0
/
PI
;
//更新元件间角度
partDist
=
(
2.0
*
asin
(
dChordL
/
(
2.0
*
trackRadius
)))
*
180.0
/
PI
;
//计算元件位置
cv
::
Point2f
pts
[
4
];
calcRotateRect
(
trackCenter
,
(
float
)
trackAngle
,
(
float
)
trackLength
,
(
float
)
trackWidth
,
pts
);
//标记计数
lbMat
.
ptr
<
uint8_t
>
(
cvRound
(
trackCenter
.
y
))[
cvRound
(
trackCenter
.
x
)]
=
255
;
//标记为已追踪过
std
::
vector
<
cv
::
Point
>
vT
=
{
cv
::
Point
(
pts
[
0
]),
cv
::
Point
(
pts
[
1
])
,
cv
::
Point
(
pts
[
2
])
,
cv
::
Point
(
pts
[
3
])
};
cv
::
fillConvexPoly
(
trackMat
,
vT
,
cv
::
Scalar
(
255
));
#ifdef _DEBUG //<20220314:测试用
tracingID
++
;
Links
.
push_back
(
Link
(
false
,
-
1
,
2
,
Links
.
back
().
iContNxt
,
chainID
,
Links
.
back
().
iContCt
,
Links
.
back
().
iContNxt
,
tracingID
,
trackCenter
,
vT
));
cv
::
fillConvexPoly
(
tracingChainMap
,
vT
,
cv
::
Scalar
(
-
1
,
chainID
,
Links
.
back
().
iContCt
));
#endif
//用于显示
cv
::
circle
(
cc
,
trackCenter
,
2
,
cv
::
Scalar
(
0
,
255
,
0
,
255
),
1
);
#ifdef _DEBUG
for
(
int
j
=
0
;
j
<
4
;
j
++
)
{
cv
::
line
(
cc
,
pts
[
j
],
pts
[(
j
+
1
)
%
4
],
cv
::
Scalar
(
102
,
205
,
0
,
255
),
1
);
}
#endif
}
}
#endif
}
}
else
{
else
{
//计算元件位置
//计算元件位置
...
@@ -3154,6 +3329,12 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -3154,6 +3329,12 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
//标记为已追踪过
//标记为已追踪过
std
::
vector
<
cv
::
Point
>
vT
=
{
cv
::
Point
(
pts
[
0
]),
cv
::
Point
(
pts
[
1
])
,
cv
::
Point
(
pts
[
2
])
,
cv
::
Point
(
pts
[
3
])
};
std
::
vector
<
cv
::
Point
>
vT
=
{
cv
::
Point
(
pts
[
0
]),
cv
::
Point
(
pts
[
1
])
,
cv
::
Point
(
pts
[
2
])
,
cv
::
Point
(
pts
[
3
])
};
cv
::
fillConvexPoly
(
trackMat
,
vT
,
cv
::
Scalar
(
255
));
cv
::
fillConvexPoly
(
trackMat
,
vT
,
cv
::
Scalar
(
255
));
#ifdef _DEBUG //<20220314:测试用
tracingID
++
;
Links
.
push_back
(
Link
(
false
,
-
1
,
2
,
Links
.
back
().
iContNxt
,
chainID
,
Links
.
back
().
iContCt
,
Links
.
back
().
iContNxt
,
tracingID
,
trackCenter
,
vT
));
cv
::
fillConvexPoly
(
tracingChainMap
,
vT
,
cv
::
Scalar
(
-
1
,
chainID
,
Links
.
back
().
iContCt
));
#endif
//用于显示
//用于显示
cv
::
circle
(
cc
,
trackCenter
,
2
,
cv
::
Scalar
(
0
,
255
,
0
,
255
),
1
);
cv
::
circle
(
cc
,
trackCenter
,
2
,
cv
::
Scalar
(
0
,
255
,
0
,
255
),
1
);
#ifdef _DEBUG
#ifdef _DEBUG
...
@@ -3174,6 +3355,70 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -3174,6 +3355,70 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
}
while
(
!
trackEnd
);
}
while
(
!
trackEnd
);
}
}
}
}
#ifdef _DEBUG //<按顺序整理Links
std
::
vector
<
Link
>
srtLink
;
std
::
vector
<
std
::
vector
<
Link
>>
srtLinks
;
bool
found
=
false
;
int
nxt
=
-
1
;
for
(
auto
&
lk
:
Links
)
{
//第一步,确定终点(如果有多个终点如何处理)
if
(
lk
.
iStartOrEnd
==
1
&&
found
==
false
&&
lk
.
iDirect
==
1
)
{
found
=
true
;
nxt
=
lk
.
iContPrev
;
srtLink
.
push_back
(
lk
);
//第二步,从终点开始向起点排序
bool
trackEnd
=
false
;
do
{
auto
lks
=
Links
[
nxt
];
if
(
lks
.
iStartOrEnd
==
0
)
{
//到达起点位置
cv
::
Point
st
=
srtLink
.
back
().
ptCenter
;
srtLink
.
push_back
(
lks
);
cv
::
Point
ed
=
lks
.
ptCenter
;
//获取下一个位置
nxt
=
lks
.
iContPrev
;
//画图
cv
::
arrowedLine
(
cc
,
st
,
ed
,
cv
::
Scalar
(
30
,
105
,
210
,
255
),
1
);
}
else
if
(
lks
.
iStartOrEnd
==
1
)
{
//画图
cv
::
Point
st
=
srtLink
.
back
().
ptCenter
;
srtLink
.
push_back
(
lks
);
cv
::
Point
ed
=
lks
.
ptCenter
;
//获取下一个位置
nxt
=
lks
.
iContPrev
;
//画图
cv
::
arrowedLine
(
cc
,
st
,
ed
,
cv
::
Scalar
(
30
,
105
,
210
,
255
),
1
);
//追踪结束
found
=
false
;
trackEnd
=
true
;
}
if
(
lks
.
iStartOrEnd
==
2
&&
lks
.
iDirect
==
1
)
{
//到另一个终点,理论情况下到这里已经完全结束
cv
::
Point
st
=
srtLink
.
back
().
ptCenter
;
srtLink
.
push_back
(
lks
);
cv
::
Point
ed
=
lks
.
ptCenter
;
//获取下一个位置
nxt
=
lks
.
iContPrev
;
//画图
cv
::
arrowedLine
(
cc
,
st
,
ed
,
cv
::
Scalar
(
30
,
105
,
210
,
255
),
1
);
}
if
(
lks
.
iStartOrEnd
==
2
&&
lks
.
iDirect
==
-
1
)
{
cv
::
Point
st
=
srtLink
.
back
().
ptCenter
;
srtLink
.
push_back
(
lks
);
cv
::
Point
ed
=
lks
.
ptCenter
;
//获取下一个位置
nxt
=
lks
.
iContNxt
;
//画图
cv
::
arrowedLine
(
cc
,
st
,
ed
,
cv
::
Scalar
(
30
,
105
,
210
,
255
),
1
);
}
}
while
(
!
trackEnd
);
break
;
}
if
(
!
srtLink
.
empty
())
srtLinks
.
push_back
(
srtLink
);
}
//如果仅有一条链,判断零星的料距离起点和终点的理论位置是否相近,相近的话判断为料;如果有多条链,判断相邻链之间的位置(多条链生成顺序是不一定的。)
#endif
//计数
//计数
binary
=
lbMat
.
clone
();
binary
=
lbMat
.
clone
();
//释放资源
//释放资源
...
@@ -3301,14 +3546,14 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -3301,14 +3546,14 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
//获取最大轮廓
//获取最大轮廓
cv
::
findContours
(
image
,
contoursFilter
,
cv
::
RETR_EXTERNAL
,
cv
::
CHAIN_APPROX_NONE
);
cv
::
findContours
(
image
,
contoursFilter
,
cv
::
RETR_EXTERNAL
,
cv
::
CHAIN_APPROX_NONE
);
//定位内圈失败一般是仅剩一圈或者不足一圈的情况
//定位内圈失败一般是仅剩一圈或者不足一圈的情况
if
(
contoursFilter
.
size
()
<=
0
)
if
(
contoursFilter
.
empty
()
)
{
{
image
=
cv
::
Scalar
(
0
);
image
=
cv
::
Scalar
(
0
);
//当仅剩一圈的情况
//当仅剩一圈的情况
cv
::
Mat
srcPrevEx1
;
cv
::
Mat
srcPrevEx1
;
cv
::
morphologyEx
(
binary
,
srcPrevEx1
,
cv
::
MORPH_DILATE
,
cv
::
getStructuringElement
(
cv
::
MORPH_RECT
,
cv
::
Size
(
15
,
15
)));
cv
::
morphologyEx
(
binary
,
srcPrevEx1
,
cv
::
MORPH_DILATE
,
cv
::
getStructuringElement
(
cv
::
MORPH_RECT
,
cv
::
Size
(
31
,
31
)));
cv
::
findContours
(
srcPrevEx1
,
contoursFilter
,
cv
::
RETR_TREE
,
cv
::
CHAIN_APPROX_NONE
);
cv
::
findContours
(
srcPrevEx1
,
contoursFilter
,
cv
::
RETR_TREE
,
cv
::
CHAIN_APPROX_NONE
);
//闭合轮廓
//闭合轮廓
...
@@ -3329,7 +3574,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -3329,7 +3574,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
return
FUNC_CANNOT_CALC
;
return
FUNC_CANNOT_CALC
;
}
}
}
}
std
::
vector
<
cv
::
Point
>
contourMax
=
contoursFilter
[
0
];
std
::
vector
<
cv
::
Point
>
contourMax
=
contoursFilter
[
0
];
for
(
int
i
=
1
;
i
<
contoursFilter
.
size
();
i
++
)
for
(
int
i
=
1
;
i
<
contoursFilter
.
size
();
i
++
)
{
{
...
@@ -3341,6 +3586,9 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -3341,6 +3586,9 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
//计算最大外接圆半径
//计算最大外接圆半径
float
tFRadius
=
0
;
float
tFRadius
=
0
;
cv
::
minEnclosingCircle
(
contourMax
,
cv
::
Point2f
(),
tFRadius
);
cv
::
minEnclosingCircle
(
contourMax
,
cv
::
Point2f
(),
tFRadius
);
//
tFRadius
=
tFRadius
<
300
?
300
:
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
));
//画中心
//画中心
...
@@ -5923,61 +6171,128 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
...
@@ -5923,61 +6171,128 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
}
}
//最大值
//最大值
cv
::
minMaxLoc
(
tplMat
,
NULL
,
&
taMaxGray
);
cv
::
minMaxLoc
(
tplMat
,
NULL
,
&
taMaxGray
);
//20220302修改测试用,使用模板匹配增加追踪起点
const
float
icvDirections
[
4
]
=
{
0
,
90
,
180
,
-
90
};
//20220302修改测试用,使用模板匹配增加追踪起点,20220310,增加至八个方向
//用以计算元件中心
//正常四个方向
const
int
icvDirectionDeltas
[
4
][
2
]
=
{
{
tplMat
.
cols
/
2
,
tplMat
.
rows
/
2
},{
tplMat
.
rows
/
2
,
tplMat
.
cols
/
2
},{
tplMat
.
cols
/
2
,
tplMat
.
rows
/
2
},
\
{
tplMat
.
rows
/
2
,
tplMat
.
cols
/
2
}
};
//cv::parallel_for_(cv::Range(0, 4), [&](const cv::Range& range)->void {
for
(
int
tpl
=
0
/*range.start*/
;
tpl
<
4
/*range.end*/
;
tpl
++
)
{
{
//模板匹配(仅处理料盘区域以提高速度)
const
float
icvDirections
[
4
]
=
{
0
,
90
,
180
,
-
90
};
cv
::
Mat
tplResult0
;
//用以计算元件中心
cv
::
matchTemplate
(
srcPrev
(
mainZone
).
clone
(),
getTplMat
(
tplMat
,
icvDirections
[
tpl
],
fillVal
),
tplResult0
,
cv
::
TM_CCOEFF_NORMED
);
const
int
icvDirectionDeltas
[
4
][
2
]
=
{
{
tplMat
.
cols
/
2
,
tplMat
.
rows
/
2
},{
tplMat
.
rows
/
2
,
tplMat
.
cols
/
2
},{
tplMat
.
cols
/
2
,
tplMat
.
rows
/
2
},
\
{
tplMat
.
rows
/
2
,
tplMat
.
cols
/
2
}
};
cv
::
Mat
ki
=
getTplMat
(
tplMat
,
icvDirections
[
tpl
],
fillVal
);
for
(
int
tpl
=
0
;
tpl
<
4
;
tpl
++
)
{
//模板匹配(仅处理料盘区域以提高速度)
cv
::
Mat
tplResult0
;
cv
::
matchTemplate
(
srcPrev
(
mainZone
).
clone
(),
getTplMat
(
tplMat
,
icvDirections
[
tpl
],
fillVal
),
tplResult0
,
cv
::
TM_CCOEFF_NORMED
);
//分数大于一定分数才当作元件处理
cv
::
Mat
ki
=
getTplMat
(
tplMat
,
icvDirections
[
tpl
],
fillVal
);
tplResult0
=
cv
::
Mat
(
tplResult0
>
0.56
);
cv
::
Point
quard
[
4
]{
cv
::
Point
(
tplResult0
.
cols
,
0
),
cv
::
Point
(
0
,
0
),
cv
::
Point
(
0
,
tplResult0
.
rows
),
cv
::
Point
(
tplResult0
.
cols
,
tplResult0
.
rows
)
};
//分数大于一定分数才当作元件处理
tplResult0
=
cv
::
Mat
(
tplResult0
>
0.6
);
std
::
vector
<
cv
::
Point
>
pt
=
{
cv
::
Point
(
tplResult0
.
cols
/
2
,
tplResult0
.
rows
/
2
),
quard
[
tpl
],
quard
[(
tpl
+
1
)
%
4
]
};
cv
::
Point
quard
[
4
]{
cv
::
Point
(
tplResult0
.
cols
,
0
),
cv
::
Point
(
0
,
0
),
cv
::
Point
(
0
,
tplResult0
.
rows
),
cv
::
Point
(
tplResult0
.
cols
,
tplResult0
.
rows
)
};
std
::
vector
<
std
::
vector
<
cv
::
Point
>>
pts
;
std
::
vector
<
cv
::
Point
>
pt
=
{
cv
::
Point
(
tplResult0
.
cols
/
2
,
tplResult0
.
rows
/
2
),
quard
[
tpl
],
quard
[(
tpl
+
1
)
%
4
]
};
pts
.
push_back
(
pt
);
cv
::
Mat
dirMask
(
tplResult0
.
size
(),
CV_8UC1
,
cv
::
Scalar
(
0
));
std
::
vector
<
std
::
vector
<
cv
::
Point
>>
pts
;
pts
.
push_back
(
pt
);
cv
::
drawContours
(
dirMask
,
pts
,
0
,
cv
::
Scalar
(
255
),
-
1
);
cv
::
Mat
dirMask
(
tplResult0
.
size
(),
CV_8UC1
,
cv
::
Scalar
(
0
)
);
//除去非必要部分
cv
::
drawContours
(
dirMask
,
pts
,
0
,
cv
::
Scalar
(
255
),
-
1
);
cv
::
bitwise_and
(
tplResult0
,
dirMask
,
tplResult0
);
//连通域分析
//除去非必要部分
cv
::
Mat
labels
,
stats
,
centroids
;
cv
::
bitwise_and
(
tplResult0
,
dirMask
,
tplResult0
);
int
nccomps
=
cv
::
connectedComponentsWithStats
(
tplResult0
,
labels
,
stats
,
centroids
);
for
(
int
i
=
1
;
i
<
nccomps
;
i
++
)
{
//连通域分析
cv
::
Point
matchPt
(
cvRound
(
centroids
.
ptr
<
double
>
(
i
)[
0
])
+
icvDirectionDeltas
[
tpl
][
0
]
+
mainZone
.
x
,
\
cv
::
Mat
labels
,
stats
,
centroids
;
cvRound
(
centroids
.
ptr
<
double
>
(
i
)[
1
])
+
icvDirectionDeltas
[
tpl
][
1
]
+
mainZone
.
y
);
int
nccomps
=
cv
::
connectedComponentsWithStats
(
tplResult0
,
labels
,
stats
,
centroids
);
//判断是否位于有效区域
if
(
srcPrevEx0
.
ptr
<
uint8_t
>
(
matchPt
.
y
)[
matchPt
.
x
]
==
255
)
for
(
int
i
=
1
;
i
<
nccomps
;
i
++
)
{
{
cv
::
Point
matchPt
(
cvRound
(
centroids
.
ptr
<
double
>
(
i
)[
0
])
+
icvDirectionDeltas
[
tpl
][
0
]
+
mainZone
.
x
,
\
//计算初始角度
cvRound
(
centroids
.
ptr
<
double
>
(
i
)[
1
])
+
icvDirectionDeltas
[
tpl
][
1
]
+
mainZone
.
y
);
double
_trackAngle_
=
atan2
((
double
)
matchPt
.
y
-
(
double
)
reelCenter
.
y
,
(
double
)
matchPt
.
x
-
(
double
)
reelCenter
.
x
)
*
180.0
/
PI
;
//判断是否位于有效区域
cv
::
Point2f
pts_t
[
4
];
if
(
srcPrevEx0
.
ptr
<
uint8_t
>
(
matchPt
.
y
)[
matchPt
.
x
]
==
255
)
calcRotateRect
(
cv
::
Point2f
((
float
)
matchPt
.
x
,
(
float
)
matchPt
.
y
),
(
float
)
_trackAngle_
,
(
float
)
tplMat
.
cols
/
2.0
f
,
(
float
)
tplMat
.
rows
/
4.0
f
,
pts_t
);
{
//for (int j = 0; j < 4; j++)
//计算初始角度
//{
double
_trackAngle_
=
atan2
((
double
)
matchPt
.
y
-
(
double
)
reelCenter
.
y
,
(
double
)
matchPt
.
x
-
(
double
)
reelCenter
.
x
)
*
180.0
/
PI
;
// cv::line(cc, pts_t[j], pts_t[(j + 1) % 4], cv::Scalar(0, 0, 255, 255), 1);
cv
::
Point2f
pts_t
[
4
];
//}
calcRotateRect
(
cv
::
Point2f
((
float
)
matchPt
.
x
,
(
float
)
matchPt
.
y
),
(
float
)
_trackAngle_
,
(
float
)
tplMat
.
cols
/
2.0
f
,
(
float
)
tplMat
.
rows
/
4.0
f
,
pts_t
);
cv
::
RotatedRect
_rbox_
(
pts_t
[
0
],
pts_t
[
1
],
pts_t
[
2
]);
//for (int j = 0; j < 4; j++)
tracingAnchors
.
push_back
(
TracingAnchor
(
cv
::
Point2f
((
float
)
matchPt
.
x
,
(
float
)
matchPt
.
y
),
(
float
)
tplMat
.
cols
,
(
float
)
tplMat
.
rows
,
_rbox_
.
size
.
area
(),
_rbox_
));
//{
// cv::line(cc, pts_t[j], pts_t[(j + 1) % 4], cv::Scalar(0, 0, 255, 255), 1);
//}
cv
::
RotatedRect
_rbox_
(
pts_t
[
0
],
pts_t
[
1
],
pts_t
[
2
]);
tracingAnchors
.
push_back
(
TracingAnchor
(
cv
::
Point2f
((
float
)
matchPt
.
x
,
(
float
)
matchPt
.
y
),
(
float
)
tplMat
.
cols
,
(
float
)
tplMat
.
rows
,
_rbox_
.
size
.
area
(),
_rbox_
));
}
}
}
}
}
}
}
//});
//图像旋转后的四个方向
{
const
float
icvDirections
[
4
]
=
{
0
,
90
,
180
,
-
90
};
//用以计算元件中心
const
int
icvDirectionDeltas
[
4
][
2
]
=
{
{
tplMat
.
cols
/
2
,
tplMat
.
rows
/
2
},{
tplMat
.
rows
/
2
,
tplMat
.
cols
/
2
},{
tplMat
.
cols
/
2
,
tplMat
.
rows
/
2
},
\
{
tplMat
.
rows
/
2
,
tplMat
.
cols
/
2
}
};
float
matxv
[
4
];
cv
::
Mat
ttmp
=
getTrackMat
(
srcPrev
(
mainZone
).
clone
(),
45.0
,
0
,
matxv
);
for
(
int
tpl
=
0
;
tpl
<
4
;
tpl
++
)
{
//模板匹配(仅处理料盘区域以提高速度)
cv
::
Mat
tplResult0
;
cv
::
matchTemplate
(
ttmp
,
getTplMat
(
tplMat
,
icvDirections
[
tpl
],
fillVal
),
tplResult0
,
cv
::
TM_CCOEFF_NORMED
);
cv
::
Mat
ki
=
getTplMat
(
tplMat
,
icvDirections
[
tpl
],
fillVal
);
//分数大于一定分数才当作元件处理
tplResult0
=
cv
::
Mat
(
tplResult0
>
0.6
);
cv
::
Point
quard
[
4
]{
cv
::
Point
(
tplResult0
.
cols
,
0
),
cv
::
Point
(
0
,
0
),
cv
::
Point
(
0
,
tplResult0
.
rows
),
cv
::
Point
(
tplResult0
.
cols
,
tplResult0
.
rows
)
};
std
::
vector
<
cv
::
Point
>
pt
=
{
cv
::
Point
(
tplResult0
.
cols
/
2
,
tplResult0
.
rows
/
2
),
quard
[
tpl
],
quard
[(
tpl
+
1
)
%
4
]
};
std
::
vector
<
std
::
vector
<
cv
::
Point
>>
pts
;
pts
.
push_back
(
pt
);
cv
::
Mat
dirMask
(
tplResult0
.
size
(),
CV_8UC1
,
cv
::
Scalar
(
0
));
cv
::
drawContours
(
dirMask
,
pts
,
0
,
cv
::
Scalar
(
255
),
-
1
);
//除去非必要部分
cv
::
bitwise_and
(
tplResult0
,
dirMask
,
tplResult0
);
//连通域分析
cv
::
Mat
labels
,
stats
,
centroids
;
int
nccomps
=
cv
::
connectedComponentsWithStats
(
tplResult0
,
labels
,
stats
,
centroids
);
for
(
int
i
=
1
;
i
<
nccomps
;
i
++
)
{
cv
::
Point
matchPt
(
cvRound
(
centroids
.
ptr
<
double
>
(
i
)[
0
])
+
icvDirectionDeltas
[
tpl
][
0
],
\
cvRound
(
centroids
.
ptr
<
double
>
(
i
)[
1
])
+
icvDirectionDeltas
[
tpl
][
1
]);
//计算旋转前的位置
float
realX1
=
0.0
f
,
realY1
=
0.0
f
;
realX1
=
(
float
)
mainZone
.
tl
().
x
+
((
matchPt
.
x
-
matxv
[
2
])
*
matxv
[
4
]
-
(
matchPt
.
y
-
matxv
[
5
])
*
matxv
[
1
])
/
(
matxv
[
0
]
*
matxv
[
4
]
-
matxv
[
3
]
*
matxv
[
1
]);
realY1
=
(
float
)
mainZone
.
tl
().
y
+
((
matchPt
.
x
-
matxv
[
2
])
*
matxv
[
3
]
-
(
matchPt
.
y
-
matxv
[
5
])
*
matxv
[
0
])
/
(
matxv
[
1
]
*
matxv
[
3
]
-
matxv
[
4
]
*
matxv
[
0
]);
//判断是否位于有效区域
if
(
srcPrevEx0
.
ptr
<
uint8_t
>
(
cvRound
(
realY1
))[
cvRound
(
realX1
)]
==
255
)
{
//计算初始角度
double
_trackAngle_
=
atan2
((
double
)
realY1
-
(
double
)
reelCenter
.
y
,
(
double
)
realX1
-
(
double
)
reelCenter
.
x
)
*
180.0
/
PI
;
cv
::
Point2f
pts_t
[
4
];
calcRotateRect
(
cv
::
Point2f
((
float
)
realX1
,
(
float
)
realY1
),
(
float
)
_trackAngle_
,
(
float
)
tplMat
.
cols
/
2.0
f
,
(
float
)
tplMat
.
rows
/
4.0
f
,
pts_t
);
//for (int j = 0; j < 4; j++)
//{
// cv::line(cc, pts_t[j], pts_t[(j + 1) % 4], cv::Scalar(0, 0, 255, 255), 1);
//}
cv
::
RotatedRect
_rbox_
(
pts_t
[
0
],
pts_t
[
1
],
pts_t
[
2
]);
tracingAnchors
.
push_back
(
TracingAnchor
(
cv
::
Point2f
((
float
)
realX1
,
(
float
)
realY1
),
(
float
)
tplMat
.
cols
,
(
float
)
tplMat
.
rows
,
_rbox_
.
size
.
area
(),
_rbox_
));
}
}
}
}
}
}
//标记为已追踪过
//标记为已追踪过
std
::
vector
<
cv
::
Point
>
vT
=
{
cv
::
Point
(
_pts
[
0
]),
cv
::
Point
(
_pts
[
1
])
,
cv
::
Point
(
_pts
[
2
])
,
cv
::
Point
(
_pts
[
3
])
};
std
::
vector
<
cv
::
Point
>
vT
=
{
cv
::
Point
(
_pts
[
0
]),
cv
::
Point
(
_pts
[
1
])
,
cv
::
Point
(
_pts
[
2
])
,
cv
::
Point
(
_pts
[
3
])
};
...
@@ -7099,7 +7414,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
...
@@ -7099,7 +7414,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
trays
.
push_back
(
TrayPos
(
reelCenter
,
tray
,
false
,
backThresh
));
trays
.
push_back
(
TrayPos
(
reelCenter
,
tray
,
false
,
backThresh
));
}
}
//判断可能无料,不能100%判断
//判断可能无料,不能100%判断
if
(
trays
.
empty
())
{
if
(
trays
.
empty
())
{
//在这里empty的话只能 是单盘,没事,除非四盘都不满一圈。。。
//在这里增加继续判断是否是因为不满一圈的料,可能无法避免空料盘与空点问题,佳世达特供(无法用于多料盘而且佳世达一般多为小料没有那么多种类)
//在这里增加继续判断是否是因为不满一圈的料,可能无法避免空料盘与空点问题,佳世达特供(无法用于多料盘而且佳世达一般多为小料没有那么多种类)
{
{
cv
::
Mat
image8U
;
cv
::
Mat
image8U
;
...
@@ -7378,7 +7693,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
...
@@ -7378,7 +7693,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
//判断适用哪种算法
//判断适用哪种算法
if
(
!
useTrackMethod
)
if
(
!
useTrackMethod
)
{
{
const
int
filterSize
=
1
2
;
const
int
filterSize
=
1
5
;
//去掉料盘深色部分干扰
//去掉料盘深色部分干扰
const
int
winSize
=
sinPartSize
>
15
?
5
:
3
;
//对于部分器件过小的窗口会漏料
const
int
winSize
=
sinPartSize
>
15
?
5
:
3
;
//对于部分器件过小的窗口会漏料
cv
::
Mat
srcPrevEx
;
cv
::
Mat
srcPrevEx
;
...
@@ -7424,8 +7739,10 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
...
@@ -7424,8 +7739,10 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
// continue;
// continue;
//}
//}
//计算轮廓矩
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
));
//计算最大外接圆半径
//计算最大外接圆半径
float
tFRadius
=
0
;
float
tFRadius
=
0
;
cv
::
minEnclosingCircle
(
contourMax
,
cv
::
Point2f
(),
tFRadius
);
cv
::
minEnclosingCircle
(
contourMax
,
cv
::
Point2f
(),
tFRadius
);
...
@@ -7611,7 +7928,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
...
@@ -7611,7 +7928,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
image
=
cv
::
Scalar
(
0
);
image
=
cv
::
Scalar
(
0
);
//当仅剩一圈的情况
//当仅剩一圈的情况
cv
::
Mat
srcPrevEx1
;
cv
::
Mat
srcPrevEx1
;
cv
::
morphologyEx
(
binary
,
srcPrevEx1
,
cv
::
MORPH_DILATE
,
cv
::
getStructuringElement
(
cv
::
MORPH_RECT
,
cv
::
Size
(
15
,
15
)));
cv
::
morphologyEx
(
binary
,
srcPrevEx1
,
cv
::
MORPH_DILATE
,
cv
::
getStructuringElement
(
cv
::
MORPH_RECT
,
cv
::
Size
(
31
,
31
)));
cv
::
findContours
(
srcPrevEx1
,
contoursFilter
,
cv
::
RETR_TREE
,
cv
::
CHAIN_APPROX_NONE
);
cv
::
findContours
(
srcPrevEx1
,
contoursFilter
,
cv
::
RETR_TREE
,
cv
::
CHAIN_APPROX_NONE
);
//闭合轮廓
//闭合轮廓
...
@@ -9593,7 +9910,6 @@ int eyemCountObjectIrregularPartsMultiopt(EyemImage tpImage, EyemRect tpRoi, int
...
@@ -9593,7 +9910,6 @@ int eyemCountObjectIrregularPartsMultiopt(EyemImage tpImage, EyemRect tpRoi, int
cv
::
minMaxIdx
(
hist
,
NULL
,
NULL
,
NULL
,
maxIdx
);
cv
::
minMaxIdx
(
hist
,
NULL
,
NULL
,
NULL
,
maxIdx
);
//背景阈值
//背景阈值
int
backThresh
=
(
maxIdx
[
0
]
-
1
)
*
(
65536
/
histSize
);
int
backThresh
=
(
maxIdx
[
0
]
-
1
)
*
(
65536
/
histSize
);
//制作掩膜
//制作掩膜
cv
::
Mat
mask
(
Y
,
X
,
CV_8UC1
,
cv
::
Scalar
(
0
));
cv
::
Mat
mask
(
Y
,
X
,
CV_8UC1
,
cv
::
Scalar
(
0
));
cv
::
parallel_for_
(
cv
::
Range
(
0
,
Y
),
[
&
](
const
cv
::
Range
range
)
->
void
{
cv
::
parallel_for_
(
cv
::
Range
(
0
,
Y
),
[
&
](
const
cv
::
Range
range
)
->
void
{
...
@@ -9605,20 +9921,40 @@ int eyemCountObjectIrregularPartsMultiopt(EyemImage tpImage, EyemRect tpRoi, int
...
@@ -9605,20 +9921,40 @@ int eyemCountObjectIrregularPartsMultiopt(EyemImage tpImage, EyemRect tpRoi, int
}
}
}
}
});
});
//去掉干扰(可有可无)
cv
::
morphologyEx
(
mask
,
mask
,
cv
::
MORPH_OPEN
,
cv
::
getStructuringElement
(
cv
::
MORPH_RECT
,
cv
::
Size
(
9
,
9
)));
//制作背景
//像素重新排列
cv
::
Mat
mean
,
stddev
;
std
::
vector
<
uint16_t
>
data
;
cv
::
meanStdDev
(
src
,
mean
,
stddev
,
mask
);
for
(
int
y
=
0
;
y
<
Y
;
y
++
)
{
for
(
int
x
=
0
;
x
<
X
;
x
++
)
{
if
(
mask
.
ptr
<
uint8_t
>
(
y
)[
x
]
==
255
)
{
data
.
push_back
(
src
.
ptr
<
uint16_t
>
(
y
)[
x
]);
}
}
}
//随机打乱(让背景尽量显得自然一点)
std
::
random_shuffle
(
data
.
begin
(),
data
.
end
());
cv
::
Mat
rnd
(
Y
,
X
,
CV_16UC1
);
//拷贝指定部分
cv
::
randn
(
rnd
,
mean
,
stddev
);
const
int
dataSize
=
cvFloor
(
sqrt
((
int
)
data
.
size
()));
std
::
vector
<
uint16_t
>
pixVal
(
dataSize
*
dataSize
);
memcpy
(
&
pixVal
[
0
],
&
data
[
0
],
dataSize
*
dataSize
*
sizeof
(
uint16_t
));
//制作背景
cv
::
Mat
rnd
;
rnd
=
cv
::
Mat
(
dataSize
,
dataSize
,
CV_16UC1
,
&
pixVal
[
0
]);
//扩充到原尺寸
cv
::
resize
(
rnd
,
rnd
,
cv
::
Size
(
X
,
Y
));
//算法选项
//算法选项
std
::
string
sOptions
[
8
]
=
{
"IP_DEFAULT_PARTS"
,
"IP_SMALL_PARTS"
,
"IP_LARGE_PARTS"
,
"IP_LONG_PARTS"
,
"IP_SQUARE_PARTS"
,
""
,
"IP_DYNAMIC_SP1"
,
"IP_DYNAMIC_SP2"
};
std
::
string
sOptions
[
8
]
=
{
"IP_DEFAULT_PARTS"
,
"IP_SMALL_PARTS"
,
"IP_LARGE_PARTS"
,
"IP_LONG_PARTS"
,
"IP_SQUARE_PARTS"
,
""
,
"IP_DYNAMIC_SP1"
,
"IP_DYNAMIC_SP2"
};
//将各个料盘分别拷贝到背景里
//将各个料盘分别拷贝到背景里
std
::
vector
<
cv
::
Rect
>
q
=
{
cv
::
Rect
(
0
,
0
,
X
/
2
,
Y
/
2
),
cv
::
Rect
(
X
/
2
,
0
,
X
/
2
,
Y
/
2
)
std
::
vector
<
cv
::
Rect
>
q
=
{
cv
::
Rect
(
0
,
0
,
X
/
2
,
Y
/
2
),
cv
::
Rect
(
0
,
Y
/
2
,
X
/
2
,
Y
/
2
)
,
cv
::
Rect
(
0
,
Y
/
2
,
X
/
2
,
Y
/
2
),
cv
::
Rect
(
X
/
2
,
Y
/
2
,
X
/
2
,
Y
/
2
)
};
,
cv
::
Rect
(
X
/
2
,
Y
/
2
,
X
/
2
,
Y
/
2
),
cv
::
Rect
(
X
/
2
,
0
,
X
/
2
,
Y
/
2
)
};
std
::
vector
<
EyemImage
>
inputs
;
std
::
vector
<
EyemImage
>
inputs
;
for
(
auto
&
rect
:
q
)
for
(
auto
&
rect
:
q
)
...
@@ -9641,7 +9977,7 @@ int eyemCountObjectIrregularPartsMultiopt(EyemImage tpImage, EyemRect tpRoi, int
...
@@ -9641,7 +9977,7 @@ int eyemCountObjectIrregularPartsMultiopt(EyemImage tpImage, EyemRect tpRoi, int
}
}
//用于显示
//用于显示
cv
::
Mat
cc
(
Y
+
1
,
X
+
1
,
CV_8UC4
,
cv
::
Scalar
(
127
,
116
,
102
,
255
));
cv
::
Mat
cc
(
Y
+
1
,
X
+
1
,
CV_8UC4
,
cv
::
Scalar
(
127
,
116
,
102
,
255
));
//点料(左上、
右上、左下、右下
)
//点料(左上、
左下、右下、右上
)
#define OPTIMIZE true
#define OPTIMIZE true
#if OPTIMIZE
#if OPTIMIZE
cv
::
parallel_for_
(
cv
::
Range
(
0
,
4
),
[
&
](
const
cv
::
Range
range
)
->
void
{
cv
::
parallel_for_
(
cv
::
Range
(
0
,
4
),
[
&
](
const
cv
::
Range
range
)
->
void
{
...
@@ -9664,6 +10000,7 @@ int eyemCountObjectIrregularPartsMultiopt(EyemImage tpImage, EyemRect tpRoi, int
...
@@ -9664,6 +10000,7 @@ int eyemCountObjectIrregularPartsMultiopt(EyemImage tpImage, EyemRect tpRoi, int
if
(
ipReelNum_
[
j
]
!=
0
)
if
(
ipReelNum_
[
j
]
!=
0
)
{
{
ipReelNum
[
i
]
=
ipReelNum_
[
j
];
ipReelNum
[
i
]
=
ipReelNum_
[
j
];
break
;
}
}
}
}
//拼接图像
//拼接图像
...
@@ -9756,10 +10093,10 @@ int eyemCountObjectIrregularPartsMultiopt(EyemImage tpImage, EyemRect tpRoi, int
...
@@ -9756,10 +10093,10 @@ int eyemCountObjectIrregularPartsMultiopt(EyemImage tpImage, EyemRect tpRoi, int
int
baseLine
;
int
baseLine
;
cv
::
Size
labelSize
=
cv
::
getTextSize
(
"No Reel"
,
cv
::
FONT_HERSHEY_SIMPLEX
,
2.5
,
2
,
&
baseLine
);
cv
::
Size
labelSize
=
cv
::
getTextSize
(
"No Reel"
,
cv
::
FONT_HERSHEY_SIMPLEX
,
2.5
,
2
,
&
baseLine
);
cv
::
putText
(
cc
,
"No Reel"
,
cv
::
Point
(
reelPt
.
x
-
labelSize
.
width
/
2
,
reelPt
.
y
-
labelSize
.
height
),
cv
::
FONT_HERSHEY_SIMPLEX
,
2.5
,
cv
::
Scalar
(
0
,
0
,
238
,
255
),
2
);
cv
::
putText
(
cc
,
"No Reel"
,
cv
::
Point
(
reelPt
.
x
-
labelSize
.
width
/
2
,
reelPt
.
y
-
labelSize
.
height
),
cv
::
FONT_HERSHEY_SIMPLEX
,
2.5
,
cv
::
Scalar
(
0
,
0
,
238
,
255
),
2
);
}
}
//画网格
//画网格
cv
::
rectangle
(
cc
,
cv
::
Rect
(
q
[
i
].
x
,
q
[
i
].
y
,
q
[
i
].
width
,
q
[
i
].
height
),
cv
::
Scalar
(
0
,
0
,
255
,
255
),
4
);
cv
::
rectangle
(
cc
,
cv
::
Rect
(
q
[
i
].
x
,
q
[
i
].
y
,
q
[
i
].
width
,
q
[
i
].
height
),
cv
::
Scalar
(
0
,
0
,
255
,
255
),
4
);
}
}
#endif
#endif
//释放图像
//释放图像
for
(
auto
&
input
:
inputs
)
for
(
auto
&
input
:
inputs
)
...
@@ -9778,7 +10115,7 @@ int eyemCountObjectIrregularPartsMultiopt(EyemImage tpImage, EyemRect tpRoi, int
...
@@ -9778,7 +10115,7 @@ int eyemCountObjectIrregularPartsMultiopt(EyemImage tpImage, EyemRect tpRoi, int
//拷贝数据
//拷贝数据
memcpy
(
tpDstImg
->
vpImage
,
cc
.
data
,
_Size
);
memcpy
(
tpDstImg
->
vpImage
,
cc
.
data
,
_Size
);
return
FUNC_OK
;
return
FUNC_OK
;
}
}
int
eyemAchvMatchMat
(
EyemImage
tpImage
,
EyemRect
tpRoi
,
EyemImage
*
tpDstImg
)
int
eyemAchvMatchMat
(
EyemImage
tpImage
,
EyemRect
tpRoi
,
EyemImage
*
tpDstImg
)
{
{
...
@@ -12932,7 +13269,7 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg)
...
@@ -12932,7 +13269,7 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg)
#pragma endregion
#pragma endregion
sw
.
Stop
();
sw
.
Stop
();
std
::
cout
<<
"
TimeSpan
:"
<<
sw
.
ElapsedMilliseconds
()
<<
std
::
endl
;
std
::
cout
<<
"
时间花费
:"
<<
sw
.
ElapsedMilliseconds
()
<<
std
::
endl
;
////<输出结果图像
////<输出结果图像
//tpDstImg->iWidth = cc.cols; tpDstImg->iHeight = cc.rows; tpDstImg->iDepth = cc.depth(); tpDstImg->iChannels = cc.channels();
//tpDstImg->iWidth = cc.cols; tpDstImg->iHeight = cc.rows; tpDstImg->iDepth = cc.depth(); tpDstImg->iChannels = cc.channels();
////内存尺寸
////内存尺寸
...
...
编写
预览
支持
Markdown
格式
附加文件
你添加了
0
人
到此讨论。请谨慎行事。
Finish editing this message first!
Cancel
请
注册
或
登录
后发表评论