Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
张士柳
/
eyemLib
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
图表
网络
创建新的问题
提交
问题看板
文件
提交
网络
比较
分支
标签
Commit 5d868695
由
张士柳
编写于
2021-07-20 17:02:33 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
无
1 个父辈
c28b0fea
隐藏空白字符变更
内嵌
并排
正在显示
18 个修改的文件
包含
379 行增加
和
273 行删除
eyemLib-Sharp/EyemLib.cs
eyemLib-Sharp/Program.cs
eyemLib/eyemBin.cpp
eyemLib/eyemClp2d.cpp
eyemLib/nnDetector.cpp → eyemLib/eyemCodeDetector.cpp
eyemLib/nnDetector.h → eyemLib/eyemCodeDetector.h
eyemLib/eyemDataCode.cpp
eyemLib/eyemDataCode.h
eyemLib/eyemEdge.cpp
eyemLib/eyemFit.cpp
eyemLib/eyemLib.h
eyemLib/eyemLib.rc
eyemLib/eyemLib.vcxproj
eyemLib/eyemLib.vcxproj.filters
eyemLib/eyemNNDetector.cpp
eyemLib/eyemNNDetector.h
eyemLib/yoloWrapper.cpp
eyemLib/yoloWrapper.h
eyemLib-Sharp/EyemLib.cs
查看文件 @
5d86869
...
...
@@ -6,6 +6,7 @@ using System.Collections.Generic;
using
System.Drawing
;
using
System.Drawing.Imaging
;
using
System.Threading
;
using
System.IO
;
namespace
eyemLib_Sharp
{
...
...
@@ -342,6 +343,14 @@ namespace eyemLib_Sharp
public
double
dVar
;
// 某种可能会使用的值
}
[
StructLayout
(
LayoutKind
.
Sequential
)]
public
struct
BboxContainer
{
//最多支持100个目标
[
MarshalAs
(
UnmanagedType
.
ByValArray
,
SizeConst
=
100
)]
public
EyemRect
[]
bboxes
;
}
///////////////////////////////////////////////////////////////////////////////
// Orthogonal Coordinate System
...
...
@@ -1020,6 +1029,25 @@ namespace eyemLib_Sharp
private
static
extern
int
eyemClp2dTangentPointToCircle
(
EyemOcsDXY
tpPoint
,
EyemOcsDXYR
tpCircle
,
ref
EyemOcsDABC
tpTangent1
,
ref
EyemOcsDXY
tpContact1
,
ref
EyemOcsDABC
tpTangent2
,
ref
EyemOcsDXY
tpContact2
);
#
endregion
#
region
深度学习目标检测器
/// <summary>
/// 初始化检测器
/// </summary>
/// <param name="detectorConfigPath">配置文件</param>
/// <param name="detectorModelPath">模型文件</param>
/// <returns></returns>
[
DllImport
(
"eyemLib.dll"
,
CharSet
=
CharSet
.
None
,
CallingConvention
=
CallingConvention
.
Cdecl
)]
private
static
extern
int
eyemInitNNDetector
(
string
detectorConfigPath
,
string
detectorModelPath
);
/// <summary>
/// 目标检测器
/// </summary>
/// <param name="tpImage">输入图像</param>
/// <returns></returns>
[
DllImport
(
"eyemLib.dll"
,
CharSet
=
CharSet
.
None
,
CallingConvention
=
CallingConvention
.
Cdecl
)]
private
static
extern
int
eyemNNDetector
(
EyemImage
tpImage
,
out
int
ipNum
,
ref
BboxContainer
container
);
#
endregion
#
region
项目
//普通器件(仍采用旧的算法)
[
DllImport
(
"eyemLib.dll"
,
CharSet
=
CharSet
.
None
,
CallingConvention
=
CallingConvention
.
Cdecl
)]
...
...
@@ -1356,6 +1384,14 @@ namespace eyemLib_Sharp
//eyemEdgesPixel(ucpImage, 15);
#
endregion
#
region
Test
NNDetector
//eyemInitNNDetector(".\\darknet\\detect-tiny-label.cfg", ".\\darknet\\detect-tiny-label.weights");
//int ipNum = 0;
//BboxContainer container = new BboxContainer();
//eyemNNDetector(image, out ipNum, ref container);
#
endregion
EyemRect
tpRoi
=
new
EyemRect
();
tpRoi
.
iXs
=
200
;
tpRoi
.
iYs
=
150
;
...
...
@@ -1700,6 +1736,44 @@ namespace eyemLib_Sharp
eyemImageFree
(
ref
image
);
}
#
region
文件重新命名
public
static
void
eyemRenameFile
(
string
filePath
)
{
List
<
string
>
fileNames
=
new
List
<
string
>();
getAllFiles
(
filePath
,
ref
fileNames
);
//批量重命名
for
(
int
index
=
0
;
index
<
fileNames
.
Count
;
index
++)
{
string
destFileNmae
=
"D://标签识别//"
+
index
.
ToString
().
PadLeft
(
5
,
'0'
)
+
".png"
;
File
.
Move
(
fileNames
[
index
],
destFileNmae
);
}
}
static
void
getAllFiles
(
string
filePath
,
ref
List
<
string
>
fileNames
)
{
getDirectory
(
filePath
,
ref
fileNames
);
}
public
static
void
getFileName
(
string
path
,
ref
List
<
string
>
fileNames
)
{
DirectoryInfo
root
=
new
DirectoryInfo
(
path
);
foreach
(
FileInfo
f
in
root
.
GetFiles
())
{
fileNames
.
Add
(
f
.
FullName
);
}
}
public
static
void
getDirectory
(
string
path
,
ref
List
<
string
>
fileNames
)
{
getFileName
(
path
,
ref
fileNames
);
DirectoryInfo
root
=
new
DirectoryInfo
(
path
);
foreach
(
DirectoryInfo
d
in
root
.
GetDirectories
())
{
getDirectory
(
d
.
FullName
,
ref
fileNames
);
}
}
#
endregion
#
region
EyemImage
与
Bitmap
相互转换
public
static
Bitmap
eyemCvtToBitmap
(
EyemImage
tpImage
)
{
...
...
eyemLib-Sharp/Program.cs
查看文件 @
5d86869
...
...
@@ -16,6 +16,8 @@ namespace eyemLib_Sharp
di
.
Create
();
}
//EyemLib.eyemRenameFile(@"D:\新建文件夹");
//初始化
EyemLib
.
Init
();
...
...
eyemLib/eyemBin.cpp
查看文件 @
5d86869
...
...
@@ -987,30 +987,24 @@ static double getThreshVal_Otsu_8u(const cv::Mat& _src)
int
eyemBinThreshold
(
EyemImage
tpSrcImg
,
int
iLightDark
,
double
dThresh
,
double
dMaxVal
,
EyemImage
*
tpDstImg
)
{
cv
::
Mat
image
=
cv
::
Mat
(
tpSrcImg
.
iHeight
,
tpSrcImg
.
iWidth
,
MAKETYPE
(
tpSrcImg
.
iDepth
,
tpSrcImg
.
iChannels
),
tpSrcImg
.
vpImage
).
clone
();
if
(
image
.
empty
())
{
return
FUNC_IMAGE_NOT_EXIST
;
}
cv
::
Mat
binary
;
//执行二值化操作
cv
::
threshold
(
image
,
binary
,
dThresh
,
dMaxVal
,
iLightDark
);
tpDstImg
->
iWidth
=
binary
.
cols
;
tpDstImg
->
iHeight
=
binary
.
rows
;
tpDstImg
->
iDepth
=
binary
.
depth
();
tpDstImg
->
iChannels
=
binary
.
channels
();
//输出结果图像
{
tpDstImg
->
iWidth
=
binary
.
cols
;
tpDstImg
->
iHeight
=
binary
.
rows
;
tpDstImg
->
iDepth
=
binary
.
depth
();
tpDstImg
->
iChannels
=
binary
.
channels
();
//内存尺寸
int
_Size
=
tpDstImg
->
iWidth
*
tpDstImg
->
iHeight
*
tpDstImg
->
iChannels
*
sizeof
(
uint8_t
);
//分配初始化内存
tpDstImg
->
vpImage
=
(
uint8_t
*
)
malloc
(
_Size
);
if
(
NULL
==
tpDstImg
->
vpImage
)
return
FUNC_NOT_ENOUGH_MEM
;
memset
(
tpDstImg
->
vpImage
,
0
,
_Size
);
//内存尺寸
int
_Size
=
tpDstImg
->
iWidth
*
tpDstImg
->
iHeight
*
tpDstImg
->
iChannels
*
sizeof
(
uint8_t
);
//分配初始化内存
tpDstImg
->
vpImage
=
(
uint8_t
*
)
malloc
(
_Size
);
if
(
NULL
==
tpDstImg
->
vpImage
)
return
FUNC_NOT_ENOUGH_MEM
;
memset
(
tpDstImg
->
vpImage
,
0
,
_Size
);
//拷贝数据
memcpy
(
tpDstImg
->
vpImage
,
binary
.
data
,
_Size
);
//拷贝数据
memcpy
(
tpDstImg
->
vpImage
,
binary
.
data
,
_Size
);
}
return
FUNC_OK
;
}
...
...
@@ -1272,7 +1266,7 @@ int eyemBinClosing(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDst
int
eyemBinBlob
(
EyemImage
tpImage
,
IntPtr
*
hObject
,
int
iAreaThrs
,
EyemBinBlob
**
tpResult
,
int
*
ipNum
,
EyemImage
*
tpDstImg
)
{
cv
::
Mat
image
(
tpImage
.
iHeight
,
tpImage
.
iWidth
,
MAKETYPE
(
tpImage
.
iDepth
,
tpImage
.
iChannels
),
tpImage
.
vpImage
);
cv
::
Mat
image
=
cv
::
Mat
(
tpImage
.
iHeight
,
tpImage
.
iWidth
,
MAKETYPE
(
tpImage
.
iDepth
,
tpImage
.
iChannels
),
tpImage
.
vpImage
).
clone
(
);
if
(
image
.
empty
())
{
return
FUNC_IMAGE_NOT_EXIST
;
...
...
eyemLib/eyemClp2d.cpp
查看文件 @
5d86869
...
...
@@ -126,13 +126,14 @@ void eyemClp2dAreaTriangle(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDXY
int
eyemClp2dCircleThreePoints
(
EyemOcsDXY
tpPoint1
,
EyemOcsDXY
tpPoint2
,
EyemOcsDXY
tpPoint3
,
EyemOcsDXYR
&
tpCircle
)
{
//计算系数
double
sa
[
9
],
sb
[
3
];
double
sa
[
9
],
sb
[
3
]
,
sx
[
3
]
;
cv
::
Mat
a
=
cv
::
Mat
(
3
,
3
,
CV_64F
,
sa
),
b
=
cv
::
Mat
(
3
,
1
,
CV_64F
,
sb
);
//系数矩阵A*X=B;
cv
::
Mat
x
=
cv
::
Mat
(
3
,
1
,
CV_64F
);
cv
::
Mat
x
=
cv
::
Mat
(
3
,
1
,
CV_64F
,
sx
);
std
::
memset
(
sa
,
0
,
sizeof
(
sa
));
std
::
memset
(
sb
,
0
,
sizeof
(
sb
));
std
::
memset
(
sx
,
0
,
sizeof
(
sx
));
sa
[
0
]
=
-
2.0
*
tpPoint1
.
dX
,
sa
[
1
]
=
-
2.0
*
tpPoint1
.
dY
,
sa
[
2
]
=
1.
;
sa
[
3
]
=
-
2.0
*
tpPoint2
.
dX
,
sa
[
4
]
=
-
2.0
*
tpPoint2
.
dY
,
sa
[
5
]
=
1.
;
...
...
@@ -144,9 +145,9 @@ int eyemClp2dCircleThreePoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcs
//solve
cv
::
solve
(
a
,
b
,
x
,
cv
::
DECOMP_SVD
);
tpCircle
.
dX
=
x
.
ptr
<
double
>
(
0
)
[
0
];
tpCircle
.
dY
=
x
.
ptr
<
double
>
(
1
)[
0
];
tpCircle
.
dR
=
sqrt
(
pow
(
x
.
ptr
<
double
>
(
0
)[
0
],
2
)
+
pow
(
x
.
ptr
<
double
>
(
1
)[
0
],
2
)
-
(
x
.
ptr
<
double
>
(
2
)[
0
]));
tpCircle
.
dX
=
sx
[
0
];
tpCircle
.
dY
=
sx
[
1
];
tpCircle
.
dR
=
sqrt
(
pow
(
sx
[
0
],
2
)
+
pow
(
sx
[
1
],
2
)
-
(
sx
[
2
]));
return
FUNC_OK
;
}
...
...
eyemLib/
nn
Detector.cpp
→
eyemLib/
eyemCode
Detector.cpp
查看文件 @
5d86869
#include "
nn
Detector.h"
#include "
eyemCode
Detector.h"
#include "yoloWrapper.h"
#include "barcodeDetector.h"
class
NN
Detector
::
Impl
{
class
Code
Detector
::
Impl
{
public
:
Impl
()
{}
~
Impl
()
{}
...
...
@@ -26,11 +26,11 @@ public:
std
::
shared_ptr
<
BarcodeDetector
>
bardetector_
;
};
NNDetector
::
NN
Detector
(
const
std
::
string
&
detector_config_path
,
CodeDetector
::
Code
Detector
(
const
std
::
string
&
detector_config_path
,
const
std
::
string
&
detector_model_path
,
const
std
::
string
&
super_resolution_prototxt_path
,
const
std
::
string
&
super_resolution_caffe_model_path
)
{
p
=
cv
::
makePtr
<
NN
Detector
::
Impl
>
();
p
=
cv
::
makePtr
<
Code
Detector
::
Impl
>
();
if
(
!
detector_config_path
.
empty
()
&&
!
detector_model_path
.
empty
())
{
p
->
detector_
=
std
::
make_shared
<
YoloWrapper
>
();
p
->
detector_
->
init
(
detector_config_path
,
detector_model_path
);
...
...
@@ -42,7 +42,7 @@ NNDetector::NNDetector(const std::string & detector_config_path,
//TODO:初始化超分辨率图像模型
}
std
::
vector
<
std
::
string
>
NN
Detector
::
detectAndDecode
(
cv
::
InputArray
img
,
std
::
vector
<
cv
::
Rect
>
&
points
,
std
::
vector
<
cv
::
Rect
>
&
__points
)
{
std
::
vector
<
std
::
string
>
Code
Detector
::
detectAndDecode
(
cv
::
InputArray
img
,
std
::
vector
<
cv
::
Rect
>
&
points
,
std
::
vector
<
cv
::
Rect
>
&
__points
)
{
CV_Assert
(
!
img
.
empty
());
if
(
img
.
cols
()
<=
20
||
img
.
rows
()
<=
20
)
{
...
...
@@ -78,11 +78,11 @@ std::vector<std::string> NNDetector::detectAndDecode(cv::InputArray img, std::ve
return
results
;
}
std
::
vector
<
cv
::
Rect
>
NN
Detector
::
Impl
::
detect
(
const
cv
::
Mat
&
img
)
{
std
::
vector
<
cv
::
Rect
>
Code
Detector
::
Impl
::
detect
(
const
cv
::
Mat
&
img
)
{
return
detector_
->
forward
(
img
);
}
std
::
vector
<
std
::
string
>
NN
Detector
::
Impl
::
decode
(
const
cv
::
Mat
&
img
,
std
::
vector
<
cv
::
Rect
>&
bboxes
,
std
::
vector
<
cv
::
Rect
>&
points
)
{
std
::
vector
<
std
::
string
>
Code
Detector
::
Impl
::
decode
(
const
cv
::
Mat
&
img
,
std
::
vector
<
cv
::
Rect
>&
bboxes
,
std
::
vector
<
cv
::
Rect
>&
points
)
{
if
(
bboxes
.
size
()
==
0
)
{
logger
.
t
(
"__eyemDetectAndDecodeUseNN__detectAndDecode__decode__:未识别到二维码"
);
return
std
::
vector
<
std
::
string
>
();
...
...
@@ -138,7 +138,7 @@ std::vector<std::string> NNDetector::Impl::decode(const cv::Mat& img, std::vecto
return
decode_results
;
}
std
::
vector
<
std
::
string
>
NN
Detector
::
detectAndDecodeBarcode
(
cv
::
InputArray
img
,
cv
::
Mat
&
showMat
,
std
::
vector
<
cv
::
Point
>
&
points
)
{
std
::
vector
<
std
::
string
>
Code
Detector
::
detectAndDecodeBarcode
(
cv
::
InputArray
img
,
cv
::
Mat
&
showMat
,
std
::
vector
<
cv
::
Point
>
&
points
)
{
CV_Assert
(
!
img
.
empty
());
...
...
@@ -230,13 +230,13 @@ std::vector<std::string> NNDetector::detectAndDecodeBarcode(cv::InputArray img,
return
results
;
}
std
::
vector
<
float
>
NN
Detector
::
Impl
::
getScaleList
(
const
int
width
,
const
int
height
)
{
std
::
vector
<
float
>
Code
Detector
::
Impl
::
getScaleList
(
const
int
width
,
const
int
height
)
{
if
(
width
<
320
||
height
<
320
)
return
{
1.0
,
2.0
,
0.5
};
if
(
width
<
640
&&
height
<
640
)
return
{
1.0
,
0.5
};
return
{
0.5
,
1.0
};
}
cv
::
Mat
NN
Detector
::
Impl
::
processImageScale
(
const
cv
::
Mat
&
src
,
float
scale
)
{
cv
::
Mat
Code
Detector
::
Impl
::
processImageScale
(
const
cv
::
Mat
&
src
,
float
scale
)
{
cv
::
Mat
sr
=
src
;
if
(
scale
==
1.0
)
{
return
sr
;
...
...
eyemLib/
nn
Detector.h
→
eyemLib/
eyemCode
Detector.h
查看文件 @
5d86869
#pragma once
//
//
detectAndDecode2d
¡¤±êÍ·
//
eyemCodeDetector
¡¤±êÍ·
//
#ifndef __
NN
DETECTOR_H
#define __
NN
DETECTOR_H
#ifndef __
EYEMCODE
DETECTOR_H
#define __
EYEMCODE
DETECTOR_H
#include "opencv2/core.hpp"
#include "libdecode.h"
...
...
@@ -11,13 +11,13 @@
extern
Logger
logger
;
class
NN
Detector
{
class
Code
Detector
{
public
:
NN
Detector
(
const
std
::
string
&
detector_config_path
=
""
,
Code
Detector
(
const
std
::
string
&
detector_config_path
=
""
,
const
std
::
string
&
detector_model_path
=
""
,
const
std
::
string
&
super_resolution_config_path
=
""
,
const
std
::
string
&
super_resolution_model_path
=
""
);
NN
Detector
()
{};
Code
Detector
()
{};
std
::
vector
<
std
::
string
>
detectAndDecode
(
cv
::
InputArray
img
,
std
::
vector
<
cv
::
Rect
>
&
points
=
std
::
vector
<
cv
::
Rect
>
(),
std
::
vector
<
cv
::
Rect
>
&
allpoints
=
std
::
vector
<
cv
::
Rect
>
());
...
...
@@ -30,5 +30,5 @@ protected:
class
Impl
;
cv
::
Ptr
<
Impl
>
p
;
};
#endif
/* __
NN
DETECTOR_H */
#endif
/* __
EYEMCODE
DETECTOR_H */
eyemLib/eyemDataCode.cpp
查看文件 @
5d86869
...
...
@@ -522,7 +522,7 @@ int eyemDetectAndDecodeUseNN(EyemImage tpImage, EyemRect tpRoi, IntPtr *hObject,
logger
.
t
(
"__eyemDetectAndDecodeUseNN__:开始识别并解码二维码"
);
//识别并解码
std
::
vector
<
cv
::
Rect
>
points
;
std
::
vector
<
cv
::
Rect
>
__points
;
auto
results
=
d
etector
->
detectAndDecode
(
image
,
points
,
__points
);
auto
results
=
pCodeD
etector
->
detectAndDecode
(
image
,
points
,
__points
);
#pragma region discard
//if (image.channels() == 1) {
...
...
@@ -553,7 +553,7 @@ int eyemDetectAndDecodeUseNN(EyemImage tpImage, EyemRect tpRoi, IntPtr *hObject,
// cv::putText(showMat, label, cv::Point(points[c].tl().x, points[c].tl().y - baseLine), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0), 1);
//}
////
/
<输出结果图像
////<输出结果图像
//{
// tpDstImg->iWidth = showMat.cols; tpDstImg->iHeight = showMat.rows; tpDstImg->iDepth = showMat.depth(); tpDstImg->iChannels = showMat.channels();
...
...
@@ -623,7 +623,7 @@ int eyemDetectAndDecodeBarcodeUseNN(EyemImage tpImage, EyemRect tpRoi, IntPtr *h
cv
::
Mat
showMat
=
image
.
clone
();
//识别并解码
std
::
vector
<
cv
::
Point
>
points
;
auto
results
=
d
etector
->
detectAndDecodeBarcode
(
image
,
showMat
,
points
);
auto
results
=
pCodeD
etector
->
detectAndDecodeBarcode
(
image
,
showMat
,
points
);
#pragma region discard
...
...
@@ -638,7 +638,7 @@ int eyemDetectAndDecodeBarcodeUseNN(EyemImage tpImage, EyemRect tpRoi, IntPtr *h
// cv::putText(showMat, label, cv::Point(points[c].x, points[c].y - baseLine), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0), 1);
//}
////
/
<输出结果图像
////<输出结果图像
//{
// tpDstImg->iWidth = showMat.cols; tpDstImg->iHeight = showMat.rows; tpDstImg->iDepth = showMat.depth(); tpDstImg->iChannels = showMat.channels();
...
...
@@ -692,12 +692,10 @@ int eyemDetectAndDecodeBarcodeUseNN(EyemImage tpImage, EyemRect tpRoi, IntPtr *h
int
eyemInitNNDataCodeModel
(
const
char
*
detectorConfigPath
,
const
char
*
detectorModelPath
,
const
char
*
superResolutionConfigPath
,
const
char
*
superResolutionModelPath
)
{
try
{
detector
=
cv
::
makePtr
<
NNDetector
>
(
detectorConfigPath
,
detectorModelPath
,
superResolutionConfigPath
,
superResolutionModelPath
);
try
{
pCodeDetector
=
cv
::
makePtr
<
CodeDetector
>
(
detectorConfigPath
,
detectorModelPath
,
superResolutionConfigPath
,
superResolutionModelPath
);
}
catch
(
const
std
::
exception
&
e
)
{
catch
(
const
std
::
exception
&
e
)
{
std
::
cout
<<
e
.
what
()
<<
std
::
endl
;
return
FUNC_CANNOT_CALC
;
}
...
...
eyemLib/eyemDataCode.h
查看文件 @
5d86869
...
...
@@ -13,11 +13,11 @@
#endif
#include "eyemLib.h"
#include "
nn
Detector.h"
#include "
eyemCode
Detector.h"
std
::
mutex
mtx
;
cv
::
Ptr
<
NNDetector
>
d
etector
;
cv
::
Ptr
<
CodeDetector
>
pCodeD
etector
;
extern
Logger
logger
;
...
...
eyemLib/eyemEdge.cpp
查看文件 @
5d86869
#
include
"eyemEdge.h"
void
thinningIteration
(
cv
::
Mat
&
img
,
int
iter
)
int
eyemEdgesPixel
(
EyemImage
tpImage
,
double
dThreshold
)
{
CV_Assert
(
img
.
channels
()
==
1
);
CV_Assert
(
img
.
depth
()
!=
sizeof
(
uchar
));
CV_Assert
(
img
.
rows
>
3
&&
img
.
cols
>
3
);
cv
::
Mat
marker
=
cv
::
Mat
::
zeros
(
img
.
size
(),
CV_8UC1
);
int
nRows
=
img
.
rows
;
int
nCols
=
img
.
cols
;
if
(
img
.
isContinuous
())
{
nCols
*=
nRows
;
nRows
=
1
;
}
int
x
,
y
;
uchar
*
pAbove
;
uchar
*
pCurr
;
uchar
*
pBelow
;
uchar
*
nw
,
*
no
,
*
ne
;
// north (pAbove)
uchar
*
we
,
*
me
,
*
ea
;
uchar
*
sw
,
*
so
,
*
se
;
// south (pBelow)
uchar
*
pDst
;
// initialize row pointers
pAbove
=
NULL
;
pCurr
=
img
.
ptr
<
uchar
>
(
0
);
pBelow
=
img
.
ptr
<
uchar
>
(
1
);
for
(
y
=
1
;
y
<
img
.
rows
-
1
;
++
y
)
{
// shift the rows up by one
pAbove
=
pCurr
;
pCurr
=
pBelow
;
pBelow
=
img
.
ptr
<
uchar
>
(
y
+
1
);
pDst
=
marker
.
ptr
<
uchar
>
(
y
);
// initialize col pointers
no
=
&
(
pAbove
[
0
]);
ne
=
&
(
pAbove
[
1
]);
me
=
&
(
pCurr
[
0
]);
ea
=
&
(
pCurr
[
1
]);
so
=
&
(
pBelow
[
0
]);
se
=
&
(
pBelow
[
1
]);
for
(
x
=
1
;
x
<
img
.
cols
-
1
;
++
x
)
{
// shift col pointers left by one (scan left to right)
nw
=
no
;
no
=
ne
;
ne
=
&
(
pAbove
[
x
+
1
]);
we
=
me
;
me
=
ea
;
ea
=
&
(
pCurr
[
x
+
1
]);
sw
=
so
;
so
=
se
;
se
=
&
(
pBelow
[
x
+
1
]);
int
A
=
(
*
no
==
0
&&
*
ne
==
1
)
+
(
*
ne
==
0
&&
*
ea
==
1
)
+
(
*
ea
==
0
&&
*
se
==
1
)
+
(
*
se
==
0
&&
*
so
==
1
)
+
(
*
so
==
0
&&
*
sw
==
1
)
+
(
*
sw
==
0
&&
*
we
==
1
)
+
(
*
we
==
0
&&
*
nw
==
1
)
+
(
*
nw
==
0
&&
*
no
==
1
);
int
B
=
*
no
+
*
ne
+
*
ea
+
*
se
+
*
so
+
*
sw
+
*
we
+
*
nw
;
int
m1
=
iter
==
0
?
(
*
no
*
*
ea
*
*
so
)
:
(
*
no
*
*
ea
*
*
we
);
int
m2
=
iter
==
0
?
(
*
ea
*
*
so
*
*
we
)
:
(
*
no
*
*
so
*
*
we
);
if
(
A
==
1
&&
(
B
>=
2
&&
B
<=
6
)
&&
m1
==
0
&&
m2
==
0
)
pDst
[
x
]
=
1
;
}
}
img
&=
~
marker
;
}
static
void
thinning
(
const
cv
::
Mat
&
src
,
cv
::
Mat
&
dst
)
{
dst
=
src
.
clone
();
dst
/=
255
;
// convert to binary image
cv
::
Mat
prev
=
cv
::
Mat
::
zeros
(
dst
.
size
(),
CV_8UC1
);
cv
::
Mat
diff
;
do
{
thinningIteration
(
dst
,
0
);
thinningIteration
(
dst
,
1
);
cv
::
absdiff
(
dst
,
prev
,
diff
);
dst
.
copyTo
(
prev
);
}
while
(
cv
::
countNonZero
(
diff
)
>
0
);
dst
*=
255
;
}
int
eyemEdgesPixel
(
EyemImage
tpImage
,
double
dThresh
)
{
cv
::
Mat
image
(
tpImage
.
iHeight
,
tpImage
.
iWidth
,
CV_8UC1
,
tpImage
.
vpImage
);
cv
::
Mat
image
=
cv
::
Mat
(
tpImage
.
iHeight
,
tpImage
.
iWidth
,
MAKETYPE
(
tpImage
.
iDepth
,
tpImage
.
iChannels
),
tpImage
.
vpImage
).
clone
();
if
(
image
.
empty
())
{
return
FUNC_IMAGE_NOT_EXIST
;
}
int
X
=
image
.
cols
,
Y
=
image
.
rows
;
uchar
*
upF
=
image
.
data
;
/*计算偏导*/
double
*
dpFx
=
(
double
*
)
malloc
(
X
*
Y
*
sizeof
(
double
));
double
*
dpFy
=
(
double
*
)
malloc
(
X
*
Y
*
sizeof
(
double
));
...
...
@@ -111,10 +16,8 @@ int eyemEdgesPixel(EyemImage tpImage, double dThresh)
double
*
dpMag
=
(
double
*
)
malloc
(
X
*
Y
*
sizeof
(
double
));
cv
::
parallel_for_
(
cv
::
Range
(
1
,
Y
-
1
),
[
&
](
const
cv
::
Range
&
range
)
->
void
{
for
(
int
y
=
range
.
start
;
y
<
range
.
end
;
y
++
)
{
for
(
int
x
=
1
;
x
<
X
-
1
;
x
++
)
{
for
(
int
y
=
range
.
start
;
y
<
range
.
end
;
y
++
)
{
for
(
int
x
=
1
;
x
<
X
-
1
;
x
++
)
{
dpFx
[(
x
)
+
(
y
)
*
X
]
=
0.5
*
((
double
)(
upF
[(
x
+
1
)
+
(
y
)
*
X
])
-
(
double
)(
upF
[(
x
-
1
)
+
(
y
)
*
X
]));
dpFy
[(
x
)
+
(
y
)
*
X
]
=
0.5
*
((
double
)(
upF
[(
x
)
+
(
y
+
1
)
*
X
])
-
(
double
)(
upF
[(
x
)
+
(
y
-
1
)
*
X
]));
dpMag
[(
x
)
+
(
y
)
*
X
]
=
sqrt
(
dpFx
[(
x
)
+
(
y
)
*
X
]
*
dpFx
[(
x
)
+
(
y
)
*
X
]
+
dpFy
[(
x
)
+
(
y
)
*
X
]
*
dpFy
[(
x
)
+
(
y
)
*
X
]);
...
...
@@ -128,43 +31,34 @@ int eyemEdgesPixel(EyemImage tpImage, double dThresh)
cv
::
parallel_for_
(
cv
::
Range
(
1
,
Y
-
1
),
[
&
](
const
cv
::
Range
&
range
)
->
void
{
for
(
int
y
=
range
.
start
;
y
<
range
.
end
;
y
++
)
for
(
int
x
=
1
;
x
<
(
X
-
1
);
x
++
)
{
if
(
dpMag
[(
x
)
+
(
y
)
*
X
]
>
dThresh
)
{
for
(
int
x
=
1
;
x
<
(
X
-
1
);
x
++
)
{
if
(
dpMag
[(
x
)
+
(
y
)
*
X
]
>
dThreshold
)
{
//判断边缘
if
(
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
>=
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
&&
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
>=
abs
(
dpFy
[(
x
)
+
(
y
-
1
)
*
X
])
&&
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
>
abs
(
dpFy
[(
x
)
+
(
y
+
1
)
*
X
]))
{
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
>=
abs
(
dpFy
[(
x
)
+
(
y
-
1
)
*
X
])
&&
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
>
abs
(
dpFy
[(
x
)
+
(
y
+
1
)
*
X
]))
{
ucpLabel
[(
x
)
+
(
y
)
*
X
]
=
255
;
//垂直边缘-2
}
else
if
(
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
>
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
&&
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
>=
abs
(
dpFx
[(
x
-
1
)
+
(
y
)
*
X
])
&&
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
>
abs
(
dpFx
[(
x
+
1
)
+
(
y
)
*
X
]))
{
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
>=
abs
(
dpFx
[(
x
-
1
)
+
(
y
)
*
X
])
&&
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
>
abs
(
dpFx
[(
x
+
1
)
+
(
y
)
*
X
]))
{
ucpLabel
[(
x
)
+
(
y
)
*
X
]
=
255
;
//水平边缘-1
}
}
}
});
//标记连通域
//标记连通域
,根据不同连通域显示不同颜色
cv
::
Mat
labels
;
int
ilabel
=
cv
::
connectedComponents
(
label
,
labels
);
//绘制连通域
std
::
vector
<
cv
::
Vec3b
>
labelColor
(
ilabel
);
for
(
int
i
=
0
;
i
<
ilabel
;
i
++
)
{
for
(
int
i
=
0
;
i
<
ilabel
;
i
++
)
{
labelColor
[
i
]
=
cv
::
Vec3b
(
rand
()
%
256
,
rand
()
%
256
,
rand
()
%
256
);
}
cv
::
Mat
labelImage
;
cv
::
cvtColor
(
image
,
labelImage
,
cv
::
COLOR_GRAY2BGR
);
for
(
int
y
=
1
;
y
<
Y
-
1
;
y
++
)
{
for
(
int
x
=
1
;
x
<
X
-
1
;
x
++
)
{
for
(
int
y
=
1
;
y
<
Y
-
1
;
y
++
)
{
for
(
int
x
=
1
;
x
<
X
-
1
;
x
++
)
{
int
lb
=
labels
.
at
<
int
>
(
y
,
x
);
if
(
lb
!=
0
)
{
if
(
lb
!=
0
)
{
labelImage
.
at
<
cv
::
Vec3b
>
(
y
,
x
)
=
labelColor
[
lb
];
}
}
...
...
@@ -179,16 +73,13 @@ int eyemEdgesPixel(EyemImage tpImage, double dThresh)
int
eyemEdgesSubpixel
(
EyemImage
tpImage
,
int
iFilter
,
int
iLow
,
int
iHigh
)
{
cv
::
Mat
image
(
tpImage
.
iHeight
,
tpImage
.
iWidth
,
CV_8UC1
,
tpImage
.
vpImage
);
cv
::
Mat
image
=
cv
::
Mat
(
tpImage
.
iHeight
,
tpImage
.
iWidth
,
MAKETYPE
(
tpImage
.
iDepth
,
tpImage
.
iChannels
),
tpImage
.
vpImage
).
clone
();
if
(
image
.
empty
())
{
return
FUNC_IMAGE_NOT_EXIST
;
}
int
X
=
image
.
cols
,
Y
=
image
.
rows
;
uchar
*
upF
=
image
.
data
;
/*计算偏导*/
double
*
dpFx
=
(
double
*
)
malloc
(
X
*
Y
*
sizeof
(
double
));
double
*
dpFy
=
(
double
*
)
malloc
(
X
*
Y
*
sizeof
(
double
));
...
...
@@ -196,10 +87,8 @@ int eyemEdgesSubpixel(EyemImage tpImage, int iFilter, int iLow, int iHigh)
double
*
dpMag
=
(
double
*
)
malloc
(
X
*
Y
*
sizeof
(
double
));
cv
::
parallel_for_
(
cv
::
Range
(
1
,
Y
-
1
),
[
&
](
const
cv
::
Range
&
range
)
->
void
{
for
(
int
y
=
range
.
start
;
y
<
range
.
end
;
y
++
)
{
for
(
int
x
=
1
;
x
<
X
-
1
;
x
++
)
{
for
(
int
y
=
range
.
start
;
y
<
range
.
end
;
y
++
)
{
for
(
int
x
=
1
;
x
<
X
-
1
;
x
++
)
{
dpFx
[(
x
)
+
(
y
)
*
X
]
=
0.5
*
((
double
)(
upF
[(
x
+
1
)
+
(
y
)
*
X
])
-
(
double
)(
upF
[(
x
-
1
)
+
(
y
)
*
X
]));
dpFy
[(
x
)
+
(
y
)
*
X
]
=
0.5
*
((
double
)(
upF
[(
x
)
+
(
y
+
1
)
*
X
])
-
(
double
)(
upF
[(
x
)
+
(
y
-
1
)
*
X
]));
dpMag
[(
x
)
+
(
y
)
*
X
]
=
sqrt
(
dpFx
[(
x
)
+
(
y
)
*
X
]
*
dpFx
[(
x
)
+
(
y
)
*
X
]
+
dpFy
[(
x
)
+
(
y
)
*
X
]
*
dpFy
[(
x
)
+
(
y
)
*
X
]);
...
...
@@ -213,81 +102,55 @@ int eyemEdgesSubpixel(EyemImage tpImage, int iFilter, int iLow, int iHigh)
cv
::
parallel_for_
(
cv
::
Range
(
1
,
Y
-
1
),
[
&
](
const
cv
::
Range
&
range
)
->
void
{
for
(
int
y
=
range
.
start
;
y
<
range
.
end
;
y
++
)
for
(
int
x
=
1
;
x
<
(
X
-
1
);
x
++
)
{
if
(
dpMag
[(
x
)
+
(
y
)
*
X
]
>
25
)
{
for
(
int
x
=
1
;
x
<
(
X
-
1
);
x
++
)
{
if
(
dpMag
[(
x
)
+
(
y
)
*
X
]
>
25
)
{
//判断边缘
if
(
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
>=
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
&&
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
>=
abs
(
dpFy
[(
x
)
+
(
y
-
1
)
*
X
])
&&
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
>
abs
(
dpFy
[(
x
)
+
(
y
+
1
)
*
X
]))
{
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
>=
abs
(
dpFy
[(
x
)
+
(
y
-
1
)
*
X
])
&&
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
>
abs
(
dpFy
[(
x
)
+
(
y
+
1
)
*
X
]))
{
ucpLabel
[(
x
)
+
(
y
)
*
X
]
=
255
;
//垂直边缘-2
}
else
if
(
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
>
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
&&
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
>=
abs
(
dpFx
[(
x
-
1
)
+
(
y
)
*
X
])
&&
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
>
abs
(
dpFx
[(
x
+
1
)
+
(
y
)
*
X
]))
{
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
>=
abs
(
dpFx
[(
x
-
1
)
+
(
y
)
*
X
])
&&
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
>
abs
(
dpFx
[(
x
+
1
)
+
(
y
)
*
X
]))
{
ucpLabel
[(
x
)
+
(
y
)
*
X
]
=
255
;
//水平边缘-1
}
}
}
});
cv
::
Mat
labels
;
cv
::
connectedComponents
(
label
,
labels
);
//所有边缘
EyemOcsDXY
temp
;
EyemOcsDXY
edge
;
std
::
vector
<
EyemOcsDXY
>
edges
;
cv
::
parallel_for_
(
cv
::
Range
(
1
,
Y
-
1
),
[
&
](
const
cv
::
Range
&
range
)
->
void
{
for
(
int
y
=
range
.
start
;
y
<
range
.
end
;
y
++
)
for
(
int
x
=
1
;
x
<
(
X
-
1
);
x
++
)
{
if
(
ucpLabel
[(
x
)
+
(
y
)
*
X
]
!=
0
)
{
for
(
int
x
=
1
;
x
<
(
X
-
1
);
x
++
)
{
if
(
ucpLabel
[(
x
)
+
(
y
)
*
X
]
!=
0
)
{
//判断边缘
if
(
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
>=
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
&&
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
>=
abs
(
dpFy
[(
x
)
+
(
y
-
1
)
*
X
])
&&
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
>
abs
(
dpFy
[(
x
)
+
(
y
+
1
)
*
X
]))
{
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
>=
abs
(
dpFy
[(
x
)
+
(
y
-
1
)
*
X
])
&&
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
>
abs
(
dpFy
[(
x
)
+
(
y
+
1
)
*
X
]))
{
//垂直边缘
double
a
,
b
,
c
,
u
;
a
=
dpMag
[(
x
)
+
(
y
-
1
)
*
X
];
b
=
dpMag
[(
x
)
+
(
y
)
*
X
];
c
=
dpMag
[(
x
)
+
(
y
+
1
)
*
X
];
u
=
0.5
*
(
a
-
c
)
/
(
a
-
b
-
b
+
c
);
temp
.
dX
=
(
float
)
x
+
0.5
f
;
temp
.
dY
=
(
float
)
y
+
0.5
f
+
(
float
)
u
;
edges
.
push_back
(
temp
);
edge
.
dX
=
(
float
)
x
+
0.5
f
;
edge
.
dY
=
(
float
)
y
+
0.5
f
+
(
float
)
u
;
edges
.
push_back
(
edge
);
}
else
if
(
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
>
abs
(
dpFy
[(
x
)
+
(
y
)
*
X
])
&&
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
>=
abs
(
dpFx
[(
x
-
1
)
+
(
y
)
*
X
])
&&
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
>
abs
(
dpFx
[(
x
+
1
)
+
(
y
)
*
X
]))
{
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
>=
abs
(
dpFx
[(
x
-
1
)
+
(
y
)
*
X
])
&&
abs
(
dpFx
[(
x
)
+
(
y
)
*
X
])
>
abs
(
dpFx
[(
x
+
1
)
+
(
y
)
*
X
]))
{
//水平边缘
double
a
,
b
,
c
,
u
;
a
=
dpMag
[(
x
-
1
)
+
(
y
)
*
X
];
b
=
dpMag
[(
x
)
+
(
y
)
*
X
];
c
=
dpMag
[(
x
+
1
)
+
(
y
)
*
X
];
u
=
0.5
*
(
a
-
c
)
/
(
a
-
b
-
b
+
c
);
temp
.
dX
=
(
float
)
x
+
0.5
f
+
(
float
)
u
;
temp
.
dY
=
(
float
)
y
+
0.5
f
;
edges
.
push_back
(
temp
);
edge
.
dX
=
(
float
)
x
+
0.5
f
+
(
float
)
u
;
edge
.
dY
=
(
float
)
y
+
0.5
f
;
edges
.
push_back
(
edge
);
}
}
}
});
//cv::RNG rng;
//cv::Mat show;
//cv::cvtColor(image.clone(), show, cv::COLOR_GRAY2BGR);
//int cnt = 0;
//for (int i = 0; i < contours.size(); i++)
//{
// cv::Vec3b color = cv::Vec3b(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
// for (int j = 0; j < contours[i].size(); j++)
// {
// cnt++;
// show.at<cv::Vec3b>(contours[i][j]) = color;
// }
// //drawContours(show, contours, i, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3);
//}
//释放资源
free
((
void
*
)
ucpLabel
);
free
((
void
*
)
dpFx
);
...
...
@@ -319,7 +182,6 @@ int eyemSkeleton(EyemImage tpImage, cv::Mat &skeleton)
if
(
image
.
empty
())
{
return
FUNC_IMAGE_NOT_EXIST
;
}
thinning
(
image
,
skeleton
);
return
FUNC_OK
;
}
...
...
eyemLib/eyemFit.cpp
查看文件 @
5d86869
...
...
@@ -168,8 +168,7 @@ static void fitLine2D_wods(int iPtnNum, const EyemOcsDXY *taPoints, float *weigh
std
::
memset
(
sa
,
0
,
sizeof
(
sa
));
std
::
memset
(
sb
,
0
,
sizeof
(
sb
));
std
::
memset
(
sx
,
0
,
sizeof
(
sx
));
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
sa
[
0
]
+=
weights
[
i
];
sa
[
1
]
+=
weights
[
i
]
*
taPoints
[
i
].
dX
;
sa
[
3
]
+=
weights
[
i
]
*
taPoints
[
i
].
dX
*
taPoints
[
i
].
dX
;
...
...
@@ -185,7 +184,6 @@ static void fitLine2D_wods(int iPtnNum, const EyemOcsDXY *taPoints, float *weigh
//solve ax=b
bool
solved
=
cv
::
solve
(
a
,
b
,
x
,
cv
::
DECOMP_SVD
);
if
(
!
solved
)
return
;
...
...
@@ -247,8 +245,7 @@ int eyemRobustFitLine(int iPtnNum, EyemOcsDXY *taPoints, int iCalcMode, double d
break
;
}
for
(
int
it
=
0
;
it
<
50
;
it
++
)
{
for
(
int
n
=
0
;
n
<
50
;
n
++
)
{
float
sum_dist
=
.0
,
sum_w
=
.0
;
/*calculate parameter*/
...
...
@@ -260,8 +257,7 @@ int eyemRobustFitLine(int iPtnNum, EyemOcsDXY *taPoints, int iCalcMode, double d
cv
::
AutoBuffer
<
float
>
dist
(
iPtnNum
);
/*calculate distance*/
for
(
int
k
=
0
;
k
<
iPtnNum
;
k
++
)
{
for
(
int
k
=
0
;
k
<
iPtnNum
;
k
++
)
{
dist
[
k
]
=
fabs
(
nx
*
(
float
)
taPoints
[
k
].
dX
+
ny
*
(
float
)
taPoints
[
k
].
dY
-
(
nx
*
px
+
ny
*
py
))
/
sqrt
(
nx
*
nx
+
ny
*
ny
);
sum_dist
+=
dist
[
k
];
}
...
...
@@ -290,10 +286,8 @@ int eyemRobustFitLine(int iPtnNum, EyemOcsDXY *taPoints, int iCalcMode, double d
static
void
fitLine2D_wods
(
int
iPtnNum
,
const
EyemOcsDXY2D
*
taPoints
,
EyemOcsDABC
&
tpLine
)
{
std
::
vector
<
cv
::
Point2f
>
points
;
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
if
(
taPoints
[
i
].
bValid
)
{
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
if
(
taPoints
[
i
].
bValid
)
{
points
.
push_back
(
cv
::
Point2f
((
float
)
taPoints
[
i
].
dX
,
(
float
)
taPoints
[
i
].
dY
));
}
}
...
...
@@ -316,8 +310,7 @@ int eyemFitLine(int iPtnNum, EyemOcsDXY *taPoint, int numToIgnore, EyemOcsDABC &
}
auto
taPoints
=
std
::
vector
<
EyemOcsDXY2D
>
(
iPtnNum
);
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
taPoints
[
i
].
bValid
=
true
;
taPoints
[
i
].
dX
=
taPoint
[
i
].
dX
;
taPoints
[
i
].
dY
=
taPoint
[
i
].
dY
;
...
...
@@ -328,29 +321,24 @@ int eyemFitLine(int iPtnNum, EyemOcsDXY *taPoint, int numToIgnore, EyemOcsDABC &
//Initialize the parameters with Robust method
fitLine2D_wods
(
iPtnNum
,
&
taPoints
[
0
],
tpLine
);
for
(
int
it
=
0
;
it
<
50
;
it
++
)
{
for
(
int
n
=
0
;
n
<
50
;
n
++
)
{
double
sr
=
0.0
,
r
=
0.0
;
/* calculate distances */
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
taPoints
[
i
].
bValid
=
true
;
taPoints
[
i
].
dE
=
std
::
pow
(
calcDist2D
(
taPoints
[
i
],
tpLine
.
dA
,
tpLine
.
dB
,
tpLine
.
dC
),
2
);
}
//sort by dE
std
::
sort
(
taPoints
.
begin
(),
taPoints
.
end
(),
std
::
less
<
EyemOcsDXY2D
>
());
for
(
int
i
=
(
iPtnNum
-
numToIgnore
);
i
<
iPtnNum
;
i
++
)
{
for
(
int
i
=
(
iPtnNum
-
numToIgnore
);
i
<
iPtnNum
;
i
++
)
{
taPoints
[
i
].
bValid
=
false
;
}
/* Run again... */
fitLine2D_wods
(
iPtnNum
,
&
taPoints
[
0
],
tpLine
);
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
if
(
taPoints
[
i
].
bValid
)
{
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
if
(
taPoints
[
i
].
bValid
)
{
r
=
std
::
pow
(
calcDist2D
(
taPoints
[
i
],
tpLine
.
dA
,
tpLine
.
dB
,
tpLine
.
dC
),
2
);
sr
+=
r
;
}
...
...
@@ -361,7 +349,6 @@ int eyemFitLine(int iPtnNum, EyemOcsDXY *taPoint, int numToIgnore, EyemOcsDABC &
if
(
std
::
abs
(
err
-
min_err
)
<
EPS
)
break
;
min_err
=
err
;
}
return
FUNC_OK
;
...
...
@@ -372,10 +359,8 @@ static void fitCircle2D_wods(int iPtnNum, const EyemOcsDXY2D *taPoints, EyemOcsD
return
;
}
std
::
vector
<
cv
::
Point2d
>
points
;
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
if
(
taPoints
[
i
].
bValid
)
{
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
if
(
taPoints
[
i
].
bValid
)
{
points
.
push_back
(
cv
::
Point2d
(
taPoints
[
i
].
dX
,
taPoints
[
i
].
dY
));
}
}
...
...
@@ -386,8 +371,7 @@ static void fitCircle2D_wods(int iPtnNum, const EyemOcsDXY2D *taPoints, EyemOcsD
cv
::
Mat
x
=
cv
::
Mat
(
3
,
1
,
CV_64F
);
memset
(
sa
,
0
,
sizeof
(
sa
));
memset
(
sb
,
0
,
sizeof
(
sb
));
for
(
size_t
i
=
0
;
i
<
points
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
points
.
size
();
i
++
)
{
sa
[
0
]
+=
(
double
)
points
[
i
].
x
;
sa
[
1
]
+=
(
double
)
points
[
i
].
y
;
sa
[
2
]
+=
1.0
;
...
...
@@ -425,25 +409,21 @@ int eyemFitCircle(int iPtnNum, EyemOcsDXY *taPoint, int numToIgnore, double &RMS
double
rms
=
.0
;
fitCircle2D_wods
(
iPtnNum
,
&
taPoints
[
0
],
tpCircle
);
//迭代计算
for
(
int
it
=
0
;
it
<
50
;
it
++
)
{
for
(
int
n
=
0
;
n
<
50
;
n
++
)
{
double
sr
=
0.0
,
r
=
0.0
;
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
taPoints
[
i
].
bValid
=
true
;
taPoints
[
i
].
dE
=
std
::
pow
(
calcDist
(
taPoints
[
i
],
tpCircle
)
-
tpCircle
.
dR
,
2
);
}
//排序
std
::
sort
(
taPoints
.
begin
(),
taPoints
.
end
(),
std
::
less
<
EyemOcsDXY2D
>
());
//忽略的点
for
(
int
i
=
iPtnNum
-
numToIgnore
;
i
<
iPtnNum
;
i
++
)
{
for
(
int
i
=
iPtnNum
-
numToIgnore
;
i
<
iPtnNum
;
i
++
)
{
taPoints
[
i
].
bValid
=
false
;
}
fitCircle2D_wods
(
iPtnNum
,
&
taPoints
[
0
],
tpCircle
);
//计算RMS
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
if
(
taPoints
[
i
].
bValid
)
{
r
=
std
::
pow
(
calcDist
(
taPoints
[
i
],
tpCircle
)
-
tpCircle
.
dR
,
2
);
...
...
@@ -459,3 +439,65 @@ int eyemFitCircle(int iPtnNum, EyemOcsDXY *taPoint, int numToIgnore, double &RMS
return
FUNC_OK
;
}
static
void
fitCircle2D_wods
(
int
iPtnNum
,
const
EyemOcsDXY
*
taPoints
,
float
*
weights
,
float
*
circle
)
{
//计算系数
double
sa
[
9
],
sb
[
3
];
cv
::
Mat
a
=
cv
::
Mat
(
3
,
3
,
CV_64F
,
sa
),
b
=
cv
::
Mat
(
3
,
1
,
CV_64F
,
sb
);
//系数矩阵A*X=B;
cv
::
Mat
x
=
cv
::
Mat
(
3
,
1
,
CV_64F
);
memset
(
sa
,
0
,
sizeof
(
sa
));
memset
(
sb
,
0
,
sizeof
(
sb
));
for
(
int
i
=
0
;
i
<
iPtnNum
;
i
++
)
{
sa
[
0
]
+=
(
double
)
weights
[
i
]
*
taPoints
[
i
].
dX
;
sa
[
1
]
+=
(
double
)
weights
[
i
]
*
taPoints
[
i
].
dY
;
sa
[
2
]
+=
(
double
)
weights
[
i
];
sa
[
3
]
+=
(
double
)
weights
[
i
]
*
taPoints
[
i
].
dX
*
taPoints
[
i
].
dX
;
sa
[
4
]
+=
(
double
)
weights
[
i
]
*
taPoints
[
i
].
dX
*
taPoints
[
i
].
dY
;
sa
[
7
]
+=
(
double
)
weights
[
i
]
*
taPoints
[
i
].
dY
*
taPoints
[
i
].
dY
;
sb
[
1
]
+=
(
double
)
weights
[
i
]
*
taPoints
[
i
].
dX
*
(
-
taPoints
[
i
].
dX
*
taPoints
[
i
].
dX
-
taPoints
[
i
].
dY
*
taPoints
[
i
].
dY
);
sb
[
2
]
+=
(
double
)
weights
[
i
]
*
taPoints
[
i
].
dY
*
(
-
taPoints
[
i
].
dX
*
taPoints
[
i
].
dX
-
taPoints
[
i
].
dY
*
taPoints
[
i
].
dY
);
}
sa
[
5
]
=
sa
[
0
];
sa
[
6
]
=
sa
[
4
];
sa
[
8
]
=
sa
[
1
];
sb
[
0
]
=
-
(
sa
[
3
]
+
sa
[
7
]);
cv
::
solve
(
a
,
b
,
x
,
cv
::
DECOMP_SVD
);
//tpCircle.dX = -x.ptr<double_t>(0)[0] / 2.0;
//tpCircle.dY = -x.ptr<double_t>(1)[0] / 2.0;
//tpCircle.dR = sqrt(pow(x.ptr<double_t>(0)[0], 2) + pow(x.ptr<double_t>(1)[0], 2) - 4.0*(x.ptr<double_t>(2)[0])) / 2.0;
}
int
eyemRobustFitCircle
(
int
iPtnNum
,
EyemOcsDXY
*
taPoints
,
int
iCalcMode
,
double
dRobustCoef
,
EyemOcsDXYR
&
tpCircle
)
{
return
FUNC_OK
;
}
int
eyemRobustFitPlane
(
int
iPtnNum
,
EyemOcsDXYZ
*
taPoint
,
int
iCalcMode
,
double
dRobustCoef
,
EyemOcsDABCD
&
tpPlane
)
{
return
FUNC_OK
;
}
int
eyemFitPlane
(
int
iPtnNum
,
EyemOcsDXYZ
*
taPoint
,
int
numToIgnore
,
double
&
dRMS
,
EyemOcsDABCD
&
tpPlane
)
{
return
FUNC_OK
;
}
int
eyemFitLineRANSAC
(
int
iPtnNum
,
EyemOcsDXY
*
taPoint
,
EyemOcsDABC
&
tpLine
)
{
return
FUNC_OK
;
}
int
eyemFitCircleRANSAC
(
int
iPtnNum
,
EyemOcsDXY
*
taPoint
,
EyemOcsDXYR
&
tpCircle
)
{
return
FUNC_OK
;
}
eyemLib/eyemLib.h
查看文件 @
5d86869
...
...
@@ -7,7 +7,6 @@
#include <opencv.hpp>
#ifndef EXPORTS
#define EXPORTS __declspec(dllexport)
#endif
...
...
@@ -431,7 +430,7 @@ extern "C" {
// 函数接口
EXPORTS
int
eyemFitLine
(
int
iPtnNum
,
EyemOcsDXY
*
taPoint
,
int
numToIgnore
,
EyemOcsDABC
&
tpLine
);
EXPORTS
int
eyemRobustFitLine
(
int
iPtnNum
,
EyemOcsDXY
*
taPoint
,
int
iCalcMode
,
double
dRobustCoef
,
EyemOcsDABC
&
tpLine
);
EXPORTS
int
eyemFitPlane
(
int
,
EyemOcsDXYZ
[],
int
,
double
,
EyemOcsDABCD
*
);
EXPORTS
int
eyemFitPlane
(
int
,
EyemOcsDXYZ
[],
int
,
double
,
EyemOcsDABCD
&
);
EXPORTS
int
eyemFitCircle
(
int
iPtnNum
,
EyemOcsDXY
*
taPoint
,
int
numToIgnore
,
double
&
RMS
,
EyemOcsDXYR
&
tpCircle
);
EXPORTS
int
eyemFitEllipse
(
int
,
EyemOcsDXY
[],
int
,
double
,
EyemOcsDXYLSQ
*
);
EXPORTS
int
eyemFitEllipseC
(
int
,
EyemOcsDXY
[],
int
,
double
,
double
[]);
...
...
@@ -659,7 +658,7 @@ extern "C" {
#endif
// 函数接口
EXPORTS
int
eyemEdgesPixel
(
EyemImage
tpImage
,
double
dThresh
);
EXPORTS
int
eyemEdgesPixel
(
EyemImage
tpImage
,
double
dThresh
old
);
EXPORTS
int
eyemEdgesSubpixel
(
EyemImage
tpImage
,
IntPtr
*
hObject
,
EyemOcsDXY
**
tpEdges
,
int
iFilter
,
int
iLow
,
int
iHigh
);
EXPORTS
int
eyemSkeleton
(
EyemImage
tpImage
,
EyemImage
&
skeleton
);
EXPORTS
int
eyemSobelAmp
(
EyemImage
tpImage
,
EyemImage
&
ImaAmp
);
...
...
@@ -790,6 +789,27 @@ extern "C" {
//////////////////////////////////////////////////////////////////////////////////////////////
// 深度学习目标检测器(eyemNNDetector.cpp)
//
typedef
struct
{
EyemRect
bboxes
[
100
];
}
BboxContainer
;
#ifdef __cplusplus
extern
"C"
{
#endif
// 函数接口
EXPORTS
int
eyemInitNNDetector
(
const
char
*
detectorConfigPath
,
const
char
*
detectorModelPath
);
EXPORTS
int
eyemNNDetector
(
EyemImage
tpImage
,
int
*
ipNum
,
BboxContainer
&
container
);
#ifdef __cplusplus
}
#endif
//////////////////////////////////////////////////////////////////////////////////////////////
// 其他工具(eyemMisc.cpp)
//
...
...
eyemLib/eyemLib.rc
查看文件 @
5d86869
此文件类型无法预览
eyemLib/eyemLib.vcxproj
查看文件 @
5d86869
...
...
@@ -177,8 +177,9 @@
<ClInclude Include="eyemMat.h" />
<ClInclude Include="eyemMath.h" />
<ClInclude Include="eyemMisc.h" />
<ClInclude Include="eyemNNDetector.h" />
<ClInclude Include="eyemSmooth.h" />
<ClInclude Include="
nn
Detector.h" />
<ClInclude Include="
eyemCode
Detector.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="yoloWrapper.h" />
</ItemGroup>
...
...
@@ -199,8 +200,9 @@
<ClCompile Include="eyemMatch.cpp" />
<ClCompile Include="eyemMath.cpp" />
<ClCompile Include="eyemMisc.cpp" />
<ClCompile Include="eyemNNDetector.cpp" />
<ClCompile Include="eyemSmooth.cpp" />
<ClCompile Include="
nn
Detector.cpp" />
<ClCompile Include="
eyemCode
Detector.cpp" />
<ClCompile Include="libopencv.cpp" />
<ClCompile Include="yoloWrapper.cpp" />
</ItemGroup>
...
...
eyemLib/eyemLib.vcxproj.filters
查看文件 @
5d86869
...
...
@@ -57,15 +57,18 @@
<ClInclude Include="yoloWrapper.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="nnDetector.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="barcodeDetector.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemDataCode.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemCodeDetector.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemNNDetector.h">
<Filter>源文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="eyemLib.cpp">
...
...
@@ -119,15 +122,18 @@
<ClCompile Include="libopencv.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="nnDetector.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="barcodeDetector.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemDataCode.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemCodeDetector.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemNNDetector.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="eyemLib.rc">
...
...
eyemLib/eyemNNDetector.cpp
0 → 100644
查看文件 @
5d86869
#include "eyemNNDetector.h"
#include "yoloWrapper.h"
class
NNDetector
::
Impl
{
public
:
Impl
()
{}
~
Impl
()
{}
//目标检测
std
::
vector
<
cv
::
Rect
>
detect
(
const
cv
::
Mat
&
img
);
//目标检测器
std
::
shared_ptr
<
YoloWrapper
>
detector_
;
};
NNDetector
::
NNDetector
(
const
std
::
string
&
detector_config_path
,
const
std
::
string
&
detector_model_path
)
{
p
=
cv
::
makePtr
<
NNDetector
::
Impl
>
();
if
(
!
detector_config_path
.
empty
()
&&
!
detector_model_path
.
empty
())
{
p
->
detector_
=
std
::
make_shared
<
YoloWrapper
>
();
p
->
detector_
->
init
(
detector_config_path
,
detector_model_path
);
}
else
{
p
->
detector_
=
NULL
;
}
}
std
::
vector
<
cv
::
Rect
>
NNDetector
::
detect
(
cv
::
InputArray
img
)
{
CV_Assert
(
!
img
.
empty
());
cv
::
Mat
input
;
int
incn
=
img
.
channels
();
if
(
incn
==
4
)
{
cv
::
cvtColor
(
img
,
input
,
cv
::
COLOR_BGRA2BGR
);
}
else
if
(
incn
==
1
)
{
cv
::
cvtColor
(
img
,
input
,
cv
::
COLOR_GRAY2BGR
);
//根据配置支持三通道图像
}
else
{
input
=
img
.
getMat
();
}
return
p
->
detect
(
input
);
}
std
::
vector
<
cv
::
Rect
>
NNDetector
::
Impl
::
detect
(
const
cv
::
Mat
&
img
)
{
return
detector_
->
forward
(
img
);
}
int
eyemInitNNDetector
(
const
char
*
detectorConfigPath
,
const
char
*
detectorModelPath
)
{
try
{
pNNDetector
=
cv
::
makePtr
<
NNDetector
>
(
detectorConfigPath
,
detectorModelPath
);
}
catch
(
const
std
::
exception
&
e
)
{
std
::
cout
<<
e
.
what
()
<<
std
::
endl
;
return
FUNC_CANNOT_CALC
;
}
std
::
unique_ptr
<
NNDetector
>
dd
;
dd
.
reset
(
new
NNDetector
(
detectorConfigPath
,
detectorModelPath
));
dd
->
detect
(
cv
::
Mat
());
dd
.
reset
();
return
FUNC_OK
;
}
int
eyemNNDetector
(
EyemImage
tpImage
,
int
*
ipNum
,
BboxContainer
&
container
)
{
cv
::
Mat
src
=
cv
::
Mat
(
tpImage
.
iHeight
,
tpImage
.
iWidth
,
MAKETYPE
(
tpImage
.
iDepth
,
tpImage
.
iChannels
),
tpImage
.
vpImage
).
clone
();
if
(
src
.
empty
())
{
return
FUNC_IMAGE_NOT_EXIST
;
}
auto
target
=
pNNDetector
->
detect
(
src
);
//结果
for
(
int
i
=
0
;
i
<
target
.
size
()
&&
i
<
100
;
++
i
)
{
EyemRect
bbox
;
bbox
.
iXs
=
target
[
i
].
x
;
bbox
.
iYs
=
target
[
i
].
y
;
bbox
.
iWidth
=
target
[
i
].
width
;
bbox
.
iHeight
=
target
[
i
].
height
;
container
.
bboxes
[
i
]
=
bbox
;
}
*
ipNum
=
static_cast
<
int
>
(
target
.
size
());
return
FUNC_OK
;
}
eyemLib/eyemNNDetector.h
0 → 100644
查看文件 @
5d86869
#pragma once
//
// eyemNNDetector¡¤±êÍ·
//
#ifndef __EYEMNNDETECTOR_H
#define __EYEMNNDETECTOR_H
#include "eyemLib.h"
class
NNDetector
{
public
:
NNDetector
(
const
std
::
string
&
detector_config_path
=
""
,
const
std
::
string
&
detector_model_path
=
""
);
NNDetector
()
{};
std
::
vector
<
cv
::
Rect
>
detect
(
cv
::
InputArray
img
);
protected
:
class
Impl
;
cv
::
Ptr
<
Impl
>
p
;
};
cv
::
Ptr
<
NNDetector
>
pNNDetector
;
#endif
/* __EYEMNNDETECTOR_H */
\ No newline at end of file
eyemLib/yoloWrapper.cpp
查看文件 @
5d86869
#include "yoloWrapper.h"
int
YoloWrapper
::
init
(
const
cv
::
S
tring
&
detector_config_path
,
const
cv
::
S
tring
&
detector_model_path
)
{
int
YoloWrapper
::
init
(
const
std
::
s
tring
&
detector_config_path
,
const
std
::
s
tring
&
detector_model_path
)
{
if
(
!
detector_config_path
.
empty
()
&&
!
detector_model_path
.
empty
())
{
//加载并初始化网络
net_
=
cv
::
dnn
::
readNet
(
detector_config_path
,
detector_model_path
);
...
...
@@ -62,11 +62,9 @@ std::vector<cv::Rect> YoloWrapper::forward(cv::Mat img) {
}
}
}
std
::
vector
<
int
>
indices
;
//非极大值抑制
cv
::
dnn
::
NMSBoxes
(
bboxes
,
confidences
,
0.01
f
,
0.05
f
,
indices
);
//裁剪区域
auto
points
=
std
::
vector
<
cv
::
Rect
>
();
for
(
int
i
=
0
;
i
<
indices
.
size
();
i
++
)
{
...
...
eyemLib/yoloWrapper.h
查看文件 @
5d86869
...
...
@@ -13,7 +13,6 @@ class YoloWrapper
{
public
:
YoloWrapper
()
{};
~
YoloWrapper
()
{};
int
init
(
const
std
::
string
&
config_path
,
const
std
::
string
&
model_path
);
std
::
vector
<
cv
::
Rect
>
forward
(
cv
::
Mat
img
);
private
:
...
...
编写
预览
支持
Markdown
格式
附加文件
你添加了
0
人
到此讨论。请谨慎行事。
Finish editing this message first!
Cancel
请
注册
或
登录
后发表评论