Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
张士柳
/
eyemLib
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
图表
网络
创建新的问题
提交
问题看板
文件
提交
网络
比较
分支
标签
Commit 9b0890d9
由
张士柳
编写于
2021-06-01 17:12:27 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
无
1 个父辈
900f2b4e
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
196 行增加
和
406 行删除
eyemLib/eyemDataCode.cpp
eyemLib/eyemDataCode.h
eyemLib/eyemGeneric.h
eyemLib/eyemMisc.h
eyemLib/eyemDataCode.cpp
查看文件 @
9b0890d
...
...
@@ -18,195 +18,195 @@ static void split(const std::string &cStrText, const std::string &cStrDelim, std
cpStr
=
NULL
;
}
static
void
filterByApriltag
(
cv
::
Mat
&
binary
,
cv
::
Mat
&
labels
,
std
::
vector
<
tMap
>
&
vPts
,
std
::
vector
<
uchar
>
&
colors
,
int
nccomps
,
double
dToleErr
=
0.5
)
{
//图像尺寸
int
X
=
binary
.
cols
,
Y
=
binary
.
rows
;
//背景
colors
[
0
]
=
255
;
std
::
vector
<
tMap
>
temp
;
//水平扫描
for
(
int
c
=
0
;
c
<
(
int
)
vPts
.
size
();
c
++
)
{
const
uint8_t
*
ptrRow
=
binary
.
ptr
<
uint8_t
>
(
vPts
[
c
].
Pt
.
y
);
//当前可能不是二维码区域
if
(
ptrRow
[
vPts
[
c
].
Pt
.
x
]
==
0
||
ptrRow
[
std
::
min
(
vPts
[
c
].
Pt
.
x
+
1
,
X
)]
==
0
||
ptrRow
[
std
::
max
(
vPts
[
c
].
Pt
.
x
-
1
,
0
)]
==
0
||
\
binary
.
ptr
<
uint8_t
>
(
std
::
max
(
vPts
[
c
].
Pt
.
y
-
1
,
0
))[
vPts
[
c
].
Pt
.
x
]
==
0
||
binary
.
ptr
<
uint8_t
>
(
std
::
min
(
vPts
[
c
].
Pt
.
y
+
1
,
Y
))[
vPts
[
c
].
Pt
.
x
]
==
0
)
{
colors
[
vPts
[
c
].
Label
]
=
0
;
continue
;
}
uint8_t
future_pixel_right
=
255
;
uint8_t
next_pixel
;
//终止条件
int
flags
=
0
;
double
test_line
[
6
]{
0
};
//0 中间那块;1那两块黑色;2外圈那两块
//向右扫描
for
(
int
x
=
vPts
[
c
].
Pt
.
x
+
1
;
x
<
X
-
1
;
x
++
)
{
//colors为0的不参与统计
if
((
colors
[
labels
.
ptr
<
int
>
(
vPts
[
c
].
Pt
.
y
)[
x
]]
==
0
))
{
continue
;
}
next_pixel
=
ptrRow
[
x
];
//统计黑白像素
test_line
[
flags
]
++
;
if
(
next_pixel
!=
future_pixel_right
)
{
flags
++
;
future_pixel_right
=
255
-
future_pixel_right
;
if
(
flags
==
3
)
{
break
;
}
}
}
uint8_t
future_pixel_left
=
255
;
//向左扫描
for
(
int
x
=
vPts
[
c
].
Pt
.
x
-
1
;
x
>=
1
;
x
--
)
{
//colors为0的不参与统计
if
((
colors
[
labels
.
ptr
<
int
>
(
vPts
[
c
].
Pt
.
y
)[
x
]]
==
0
))
{
continue
;
}
next_pixel
=
ptrRow
[
x
];
//统计黑白像素
test_line
[
flags
]
++
;
if
(
next_pixel
!=
future_pixel_left
)
{
flags
++
;
future_pixel_left
=
255
-
future_pixel_left
;
if
(
flags
==
6
)
{
break
;
};
}
}
//判断是否符合条件,[1]/[4]为1:1------[2]/[5]为1:1-----([1]+[4])/([0]+[3])-----约为0.67
double
rate
=
cv
::
min
(
test_line
[
1
],
test_line
[
4
])
/
cv
::
max
(
test_line
[
1
],
test_line
[
4
]);
if
((
rate
>=
(
1.
-
dToleErr
)
&&
rate
<=
(
1.
+
dToleErr
)))
{
rate
=
cv
::
min
(
test_line
[
2
],
test_line
[
5
])
/
cv
::
max
(
test_line
[
2
],
test_line
[
5
]);
if
((
rate
>=
(
1.
-
dToleErr
)
&&
rate
<=
(
1.
+
dToleErr
)))
{
rate
=
(
test_line
[
1
]
+
test_line
[
4
])
/
(
test_line
[
0
]
+
test_line
[
3
]);
//允许50%的误差
if
(
rate
>=
((
2.
/
3.
)
*
(
1.
-
dToleErr
))
&&
rate
<=
((
2.
/
3.
)
*
(
1.
+
dToleErr
)))
{
temp
.
push_back
(
vPts
[
c
]);
}
else
{
colors
[
vPts
[
c
].
Label
]
=
0
;
}
}
else
{
colors
[
vPts
[
c
].
Label
]
=
0
;
}
}
else
{
colors
[
vPts
[
c
].
Label
]
=
0
;
}
}
//垂直扫描
for
(
int
c
=
0
;
c
<
(
int
)
temp
.
size
();
c
++
)
{
uint8_t
future_pixel_down
=
255
;
uint8_t
next_pixel
;
//终止条件
int
flags
=
0
;
double
test_line
[
6
]{
0
};
//向下扫描
for
(
int
y
=
temp
[
c
].
Pt
.
y
+
1
;
y
<
Y
-
1
;
y
++
)
{
//colors为0的不参与统计
if
((
colors
[
labels
.
ptr
<
int
>
(
y
)[
temp
[
c
].
Pt
.
x
]]
==
0
))
{
continue
;
}
next_pixel
=
binary
.
ptr
<
uint8_t
>
(
y
)[
temp
[
c
].
Pt
.
x
];
//统计黑白像素
test_line
[
flags
]
++
;
if
(
next_pixel
!=
future_pixel_down
)
{
flags
++
;
future_pixel_down
=
255
-
future_pixel_down
;
if
(
flags
==
3
)
{
break
;
};
}
}
uint8_t
future_pixel_up
=
255
;
//向下扫描
for
(
int
y
=
temp
[
c
].
Pt
.
y
-
1
;
y
>=
1
;
y
--
)
{
//colors为0的不参与统计
if
((
colors
[
labels
.
ptr
<
int
>
(
y
)[
temp
[
c
].
Pt
.
x
]]
==
0
))
{
continue
;
}
next_pixel
=
binary
.
ptr
<
uint8_t
>
(
y
)[
temp
[
c
].
Pt
.
x
];
//统计黑白像素
test_line
[
flags
]
++
;
if
(
next_pixel
!=
future_pixel_up
)
{
flags
++
;
future_pixel_up
=
255
-
future_pixel_up
;
if
(
flags
==
6
)
{
break
;
};
}
}
//判断是否符合条件,[1]/[4]为1:1------[2]/[5]为1:1-----([1]+[4])/([0]+[3])-----约为0.67
double
rate
=
cv
::
min
(
test_line
[
1
],
test_line
[
4
])
/
cv
::
max
(
test_line
[
1
],
test_line
[
4
]);
if
(
rate
>=
(
1.
-
dToleErr
)
&&
rate
<=
(
1
+
dToleErr
))
{
rate
=
cv
::
min
(
test_line
[
2
],
test_line
[
5
])
/
cv
::
max
(
test_line
[
2
],
test_line
[
5
]);
if
(
rate
>=
(
1.
-
dToleErr
)
&&
rate
<=
(
1
+
dToleErr
))
{
rate
=
(
test_line
[
1
]
+
test_line
[
4
])
/
(
test_line
[
0
]
+
test_line
[
3
]);
//允许50%的误差
if
(
rate
>=
((
2.
/
3.
)
*
(
1.
-
dToleErr
))
&&
rate
<=
((
2.
/
3.
)
*
(
1.
+
dToleErr
)))
{
//大部分条件均满足,进入候选点
}
else
{
colors
[
temp
[
c
].
Label
]
=
0
;
}
}
else
{
colors
[
temp
[
c
].
Label
]
=
0
;
}
}
else
{
colors
[
temp
[
c
].
Label
]
=
0
;
}
}
colors
[
0
]
=
0
;
//过滤
cv
::
parallel_for_
(
cv
::
Range
(
0
,
Y
),
[
&
](
const
cv
::
Range
&
range
)
->
void
{
for
(
int
y
=
range
.
start
;
y
<
range
.
end
;
y
++
)
{
uint8_t
*
ptrRow
=
binary
.
ptr
<
uint8_t
>
(
y
);
for
(
int
x
=
0
;
x
<
X
;
x
++
)
{
int
label
=
labels
.
ptr
<
int
>
(
y
)[
x
];
CV_Assert
(
0
<=
label
&&
label
<=
nccomps
);
ptrRow
[
x
]
=
colors
[
label
];
}
}
});
}
//
static void filterByApriltag(cv::Mat &binary, cv::Mat &labels, std::vector<tMap> &vPts, std::vector<uchar> &colors, int nccomps, double dToleErr = 0.5)
//
{
//
//图像尺寸
//
int X = binary.cols, Y = binary.rows;
//
//背景
//
colors[0] = 255;
//
std::vector<tMap> temp;
//
//水平扫描
//
for (int c = 0; c < (int)vPts.size(); c++)
//
{
//
const uint8_t *ptrRow = binary.ptr<uint8_t>(vPts[c].Pt.y);
//
//
//当前可能不是二维码区域
//
if (ptrRow[vPts[c].Pt.x] == 0 || ptrRow[std::min(vPts[c].Pt.x + 1, X)] == 0 || ptrRow[std::max(vPts[c].Pt.x - 1, 0)] == 0 || \
//
binary.ptr<uint8_t>(std::max(vPts[c].Pt.y - 1, 0))[vPts[c].Pt.x] == 0 || binary.ptr<uint8_t>(std::min(vPts[c].Pt.y + 1, Y))[vPts[c].Pt.x] == 0)
//
{
//
colors[vPts[c].Label] = 0;
//
continue;
//
}
//
//
uint8_t future_pixel_right = 255;
//
//
uint8_t next_pixel;
//
//
//终止条件
//
int flags = 0;
//
//
double test_line[6]{ 0 };//0 中间那块;1那两块黑色;2外圈那两块
//
//向右扫描
//
for (int x = vPts[c].Pt.x + 1; x < X - 1; x++)
//
{
//
//colors为0的不参与统计
//
if ((colors[labels.ptr<int>(vPts[c].Pt.y)[x]] == 0))
//
{
//
continue;
//
}
//
next_pixel = ptrRow[x];
//
//统计黑白像素
//
test_line[flags]++;
//
if (next_pixel != future_pixel_right)
//
{
//
flags++;
//
future_pixel_right = 255 - future_pixel_right;
//
if (flags == 3) { break; }
//
}
//
}
//
uint8_t future_pixel_left = 255;
//
//
//向左扫描
//
for (int x = vPts[c].Pt.x - 1; x >= 1; x--)
//
{
//
//colors为0的不参与统计
//
if ((colors[labels.ptr<int>(vPts[c].Pt.y)[x]] == 0))
//
{
//
continue;
//
}
//
next_pixel = ptrRow[x];
//
//统计黑白像素
//
test_line[flags]++;
//
//
if (next_pixel != future_pixel_left)
//
{
//
flags++;
//
future_pixel_left = 255 - future_pixel_left;
//
if (flags == 6) { break; };
//
}
//
}
//
//判断是否符合条件,[1]/[4]为1:1------[2]/[5]为1:1-----([1]+[4])/([0]+[3])-----约为0.67
//
double rate = cv::min(test_line[1], test_line[4]) / cv::max(test_line[1], test_line[4]);
//
if ((rate >= (1. - dToleErr) && rate <= (1. + dToleErr)))
//
{
//
rate = cv::min(test_line[2], test_line[5]) / cv::max(test_line[2], test_line[5]);
//
if ((rate >= (1. - dToleErr) && rate <= (1. + dToleErr)))
//
{
//
rate = (test_line[1] + test_line[4]) / (test_line[0] + test_line[3]);
//
//允许50%的误差
//
if (rate >= ((2. / 3.)*(1. - dToleErr)) && rate <= ((2. / 3.)*(1. + dToleErr)))
//
{
//
temp.push_back(vPts[c]);
//
}
//
else
//
{
//
colors[vPts[c].Label] = 0;
//
}
//
}
//
else
//
{
//
colors[vPts[c].Label] = 0;
//
}
//
}
//
else
//
{
//
colors[vPts[c].Label] = 0;
//
}
//
}
//
//垂直扫描
//
for (int c = 0; c < (int)temp.size(); c++)
//
{
//
uint8_t future_pixel_down = 255;
//
//
uint8_t next_pixel;
//
//
//终止条件
//
int flags = 0;
//
//
double test_line[6]{ 0 };
//
//向下扫描
//
for (int y = temp[c].Pt.y + 1; y < Y - 1; y++)
//
{
//
//colors为0的不参与统计
//
if ((colors[labels.ptr<int>(y)[temp[c].Pt.x]] == 0))
//
{
//
continue;
//
}
//
next_pixel = binary.ptr<uint8_t>(y)[temp[c].Pt.x];
//
//统计黑白像素
//
test_line[flags]++;
//
if (next_pixel != future_pixel_down)
//
{
//
flags++;
//
future_pixel_down = 255 - future_pixel_down;
//
if (flags == 3) { break; };
//
}
//
}
//
//
uint8_t future_pixel_up = 255;
//
//
//向下扫描
//
for (int y = temp[c].Pt.y - 1; y >= 1; y--)
//
{
//
//colors为0的不参与统计
//
if ((colors[labels.ptr<int>(y)[temp[c].Pt.x]] == 0))
//
{
//
continue;
//
}
//
next_pixel = binary.ptr<uint8_t>(y)[temp[c].Pt.x];
//
//统计黑白像素
//
test_line[flags]++;
//
//
if (next_pixel != future_pixel_up)
//
{
//
flags++;
//
future_pixel_up = 255 - future_pixel_up;
//
if (flags == 6) { break; };
//
}
//
}
//
//判断是否符合条件,[1]/[4]为1:1------[2]/[5]为1:1-----([1]+[4])/([0]+[3])-----约为0.67
//
double rate = cv::min(test_line[1], test_line[4]) / cv::max(test_line[1], test_line[4]);
//
if (rate >= (1. - dToleErr) && rate <= (1 + dToleErr))
//
{
//
rate = cv::min(test_line[2], test_line[5]) / cv::max(test_line[2], test_line[5]);
//
if (rate >= (1. - dToleErr) && rate <= (1 + dToleErr))
//
{
//
rate = (test_line[1] + test_line[4]) / (test_line[0] + test_line[3]);
//
//允许50%的误差
//
if (rate >= ((2. / 3.)*(1. - dToleErr)) && rate <= ((2. / 3.)*(1. + dToleErr)))
//
{
//
//大部分条件均满足,进入候选点
//
}
//
else
//
{
//
colors[temp[c].Label] = 0;
//
}
//
}
//
else
//
{
//
colors[temp[c].Label] = 0;
//
}
//
}
//
else
//
{
//
colors[temp[c].Label] = 0;
//
}
//
}
//
colors[0] = 0;
//
//过滤
//
cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range& range)->void {
//
for (int y = range.start; y < range.end; y++)
//
{
//
uint8_t *ptrRow = binary.ptr<uint8_t>(y);
//
for (int x = 0; x < X; x++)
//
{
//
int label = labels.ptr<int>(y)[x];
//
CV_Assert(0 <= label && label <= nccomps);
//
ptrRow[x] = colors[label];
//
}
//
}
//
});
//
}
static
double
getThreshVal_Otsu_8u
(
const
cv
::
Mat
&
_src
)
{
...
...
@@ -284,8 +284,6 @@ static double getThreshVal_Otsu_8u(const cv::Mat& _src)
return
max_val
;
}
#pragma endregion
static
void
decodeMul
(
std
::
vector
<
WaitArea
>
&
waitAreas
,
std
::
vector
<
std
::
string
>
&
hints
,
cv
::
Mat
&
showMat
,
std
::
vector
<
DecodeResult
>
&
decodeResults
,
int
iBlockSize
,
const
int
iRangeC
,
double
dMinorStep
)
{
//进入线程锁
...
...
@@ -325,6 +323,8 @@ static void decodeMul(std::vector<WaitArea> &waitAreas, std::vector<std::string>
mtx
.
unlock
();
}
#pragma endregion
int
eyemDetectAndDecode
(
EyemImage
tpImage
,
EyemRect
tpRoi
,
const
char
*
ccFileName
,
const
char
*
ccCodeType
,
IntPtr
*
hObject
,
EyemBarCode
**
hResults
,
int
*
ipNum
,
bool
bUseNiBlack
,
int
iBlockSize
,
const
int
iRangeC
,
int
iSymbolMin
,
int
iSymbolMax
,
double
dScaleUpAndDown
,
double
dToleErr
,
double
dMinorStep
)
{
cv
::
Mat
src
=
cv
::
Mat
(
tpImage
.
iHeight
,
tpImage
.
iWidth
,
MAKETYPE
(
tpImage
.
iDepth
,
tpImage
.
iChannels
),
tpImage
.
vpImage
);
...
...
@@ -676,7 +676,7 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
tpResult
.
iCenterY
=
decodeResults
[
i
].
ptResult
.
y
;
tpResult
.
dAngle
=
decodeResults
[
i
].
dAngle
;
//分配内容所需内存
tpResult
.
lpszText
=
(
char
*
)
CoTaskMemAlloc
(
512
);
tpResult
.
lpszText
=
(
char
*
)
CoTaskMemAlloc
(
256
);
if
(
NULL
!=
tpResult
.
lpszText
)
{
char
file
[
512
]
=
{
0
};
...
...
@@ -685,7 +685,7 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
}
else
return
FUNC_NOT_ENOUGH_MEM
;
//分配码型所需内存
tpResult
.
lpszType
=
(
char
*
)
CoTaskMemAlloc
(
512
);
tpResult
.
lpszType
=
(
char
*
)
CoTaskMemAlloc
(
256
);
if
(
NULL
!=
tpResult
.
lpszType
)
{
char
file
[
512
]
=
{
0
};
...
...
@@ -700,203 +700,6 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
*
ipNum
=
static_cast
<
int
>
(
tpResults
->
size
());
*
hObject
=
reinterpret_cast
<
IntPtr
>
(
tpResults
);
return
FUNC_OK
;
////局部二值化
//cv::adaptiveThreshold(src, binary, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY_INV, iBlockSize, 2);
////去掉大部分干扰项
//binary &= mask;
////对二值图像过滤
//cv::Mat labels, stats, centroids;
//int nccomps = cv::connectedComponentsWithStats(binary, labels, stats, centroids, 4);
////过滤连通域面积及长/宽比例不符合的,允许50%误差
//std::vector<uchar> colors(nccomps + 1, 0);
//for (int i = 1; i < nccomps; i++) {
// colors[i] = 255;
// if ((stats.ptr<int>(i)[cv::CC_STAT_WIDTH] > iBlockSize * 15 * 1.414*(1. + dToleErr)) | (stats.ptr<int>(i)[cv::CC_STAT_HEIGHT] > iBlockSize * 15 * 1.414*(1. + dToleErr))\
// | (false))
// {
// colors[i] = 0;
// }
//}
////第一次过滤
//cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range& range)->void {
// for (int y = range.start; y < range.end; y++)
// {
// uint8_t *ptrRow = binary.ptr<uint8_t>(y);
// for (int x = 0; x < X; x++)
// {
// int label = labels.ptr<int>(y)[x];
// CV_Assert(0 <= label && label <= nccomps);
// ptrRow[x] = colors[label];
// }
// }
//});
////cv::cvtColor(binary, showMat, cv::COLOR_GRAY2BGR);
//const int iScanRadius = 35;
////最好还是用线扫描的方法,具体扫描全图还是按照中心点来扫看时间
////指定长度十字网格遍历是否满足条件黑白比例在1:1,考虑其他方式去扫描,可能速度上会慢一些,如果区分满足各自条件可能会好一些
////,这样可以将其他不必要的过滤掉,最后再合成一张图;2,扫描宽度,根据宽度流来确定是否属于条码、qr、datamatrix,黑白宽度;
////宽度打开都在一个很小变动范围内,允许50%的误差,宽度密度相较目前判断方式可也确定是否是黑白格分布,考虑到一维条码,八个方向只需满足一个方向即可
////这样可以过滤掉一些孤立长条
////vPts[0].Pt = cv::Point(3610, 2433);
//cv::Mat label(Y, X, CV_8UC1, cv::Scalar(0));
//cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range& range)->void {
// for (int y = range.start; y < range.end; y++)
// {
// for (int x = 0; x < X; x++)
// {
// uint8_t future_pixel = binary.ptr<uint8_t>(y)[x];
// if (!future_pixel)
// {
// continue;
// }
// bool iFlag = 0;
// //判断白色像素部分占整条线的比例
// for (double t = -180; t < 180; t += 45)
// {
// float xx = float(x + iScanRadius * cos(t* 0.01745));
// float yy = float(y + iScanRadius * sin(t* 0.01745));
// //防止越界
// if (xx < 0) xx = 0; if (xx >= X - 1) xx = X - 1; if (yy < 0) yy = 0; if (yy >= Y - 1) yy = Y - 1;
// cv::LineIterator it(binary, cv::Point(x, y), cv::Point(cvRound(xx), cvRound(yy)), 4);
// //扫描像素密度,比例接近1:1记录下来
// int length = 0;
// std::vector<double> test_lines;
// double test_line[2]{ 0 };
// for (int n = 0; n < it.count; n++, ++it)
// {
// //统计相邻由明到暗个数,并且查看均匀性
// uint8_t next_pixel = binary.ptr<uint8_t>(it.pos().y)[it.pos().x];
// test_line[next_pixel % 254]++;
// length++;
// if (next_pixel != future_pixel)
// {
// if (!next_pixel)
// {
// test_lines.push_back(length);
// }
// future_pixel = 255 - future_pixel;
// length = 0;
// }
// }
// if (cv::max(test_line[0], test_line[1]) <= 0) continue;
// //至少存在l个方向满足黑白1:1比例,并且满足黑白交替比例大概在1:1
// double dRate = cv::min(test_line[0], test_line[1]) / cv::max(test_line[0], test_line[1]);
// if (dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr))
// {
// //满足条件,再判断当前方向的宽度是否
// iFlag = true;
// //cv::putText(showMat, "OK", vPts[c].Pt, cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(0, 0, 255));
// //showMat.at<cv::Vec3b>(cv::Point(x, y)) = cv::Vec3b(0, 255, 0);
// label.ptr<uint8_t>(y)[x] = 255;
// break;
// }
// }
// }
// }
//});
//for (int c = 0; c < (int)vPts.size(); c++)
//{
// bool iFlag = 0;
// uint8_t future_pixel = binary.ptr<uint8_t>(vPts[c].Pt.y)[vPts[c].Pt.x];
// //判断白色像素部分占整条线的比例
// for (double t = -180; t < 180; t += 45)
// {
// float x = float(vPts[c].Pt.x + iScanRadius * cos(t* 0.01745));
// float y = float(vPts[c].Pt.y + iScanRadius * sin(t* 0.01745));
// //防止越界
// if (x < 0) x = 0; if (x >= X - 1) x = X - 1; if (y < 0) y = 0; if (y >= Y - 1) y = Y - 1;
// cv::LineIterator it(binary, vPts[c].Pt, cv::Point(cvRound(x), cvRound(y)), 4);
// //扫描像素密度,比例接近1:1记录下来
// //测试用
// std::vector<cv::Point> test_point;
// int length = 0;
// std::vector<double> test_lines;
// double test_line[2]{ 0 };
// for (int n = 0; n < it.count; n++, ++it)
// {
// //统计相邻由明到暗个数,并且查看均匀性
// uint8_t next_pixel = binary.ptr<uint8_t>(it.pos().y)[it.pos().x];
// test_line[next_pixel % 254]++;
// length++;
// if (next_pixel != future_pixel)
// {
// if (length > 1)
// {
// test_lines.push_back(length);
// }
// future_pixel = 255 - future_pixel;
// length = 0;
// }
// //test_point.push_back(it.pos());
// //showMat.at<cv::Vec3b>(it.pos()) = cv::Vec3b(0, 255, 0);
// }
// //至少存在l个方向满足黑白1:1比例,并且满足黑白交替比例大概在1:1
// double dRate = cv::min(test_line[0], test_line[1]) / cv::max(test_line[0], test_line[1]);
// if (dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr) && (test_lines.size() >= T))
// {
// //满足条件,再判断当前方向的宽度是否
// iFlag = true;
// //cv::putText(showMat, "OK", vPts[c].Pt, cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(0, 0, 255));
// //for (int n = 0; n < test_point.size(); n++)
// //{
// // showMat.at<cv::Vec3b>(test_point[n]) = cv::Vec3b(0, 0, 255);
// //}
// //std::cout << "xx" << std::endl;
// }
// }
// //对四个方向进行进一步进行过滤,黑白间隔跨度阈值限定
// if ((!iFlag))
// {
// colors[vPts[c].Label] = 0;
// }
//}
//二次过滤
//cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range& range)->void {
// for (int y = range.start; y < range.end; y++)
// {
// uint8_t *ptrRow = binary.ptr<uint8_t>(y);
// for (int x = 0; x < X; x++)
// {
// int label = labels.ptr<int>(y)[x];
// CV_Assert(0 <= label && label <= nccomps);
// ptrRow[x] = colors[label];
// }
// }
//});
//cv::Mat binPrev;
//cv::morphologyEx(label, binPrev, cv::MORPH_CLOSE, cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(iBlockSize, iBlockSize)));
////用于轮廓检测(最终过滤过的图)
//std::vector<cv::Vec4i> hierarchy;
//std::vector<std::vector<cv::Point>> contourAll, contourFilter;
//findContours(binPrev, contourAll, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
//for (int i = 0; i < static_cast<int>(contourAll.size()); i++)
//{
// cv::RotatedRect rect = cv::minAreaRect(contourAll[i]);
// double dRate = rect.size.width / rect.size.height;
// std::vector<cv::Point> approx;
// cv::approxPolyDP(cv::Mat(contourAll[i]), approx, cv::arcLength(cv::Mat(contourAll[i]), true)*0.02, true);
// //满足四边形条件
// if (dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr) && (approx.size() >= 4 && approx.size() < 8) && (cv::contourArea(contourAll[i]) > std::pow(iBlockSize * 12 * (1. - dToleErr), 2)))
// {
// contourFilter.push_back(contourAll[i]);
// }
//}
//if (contourFilter.size() < 1)
//{
// return FUNC_CANNOT_CALC;
//}
return
FUNC_OK
;
}
int
eyemDetectAndDecodeUseNN
(
EyemImage
tpImage
,
EyemRect
tpRoi
,
IntPtr
*
hObject
,
EyemBarCode
**
hResults
,
int
*
ipNum
,
EyemImage
*
tpDstImg
)
...
...
@@ -909,8 +712,6 @@ int eyemDetectAndDecodeUseNN(EyemImage tpImage, EyemRect tpRoi, IntPtr *hObject,
std
::
vector
<
cv
::
Rect
>
points
;
std
::
vector
<
cv
::
Rect
>
__points
;
auto
results
=
detector
->
detectAndDecode
(
image
,
points
,
__points
);
//std::string str(enumtoCharArr(EYEM_DIST_HUBER));
#pragma region discard
if
(
image
.
channels
()
==
1
)
{
cv
::
cvtColor
(
image
,
image
,
cv
::
COLOR_GRAY2BGR
);
...
...
@@ -986,7 +787,6 @@ int eyemDetectAndDecodeUseNN(EyemImage tpImage, EyemRect tpRoi, IntPtr *hObject,
//添加结果
tpResults
->
push_back
(
tpResult
);
}
__points
.
clear
();
*
hResults
=
tpResults
->
data
();
*
ipNum
=
static_cast
<
int
>
(
tpResults
->
size
());
*
hObject
=
reinterpret_cast
<
IntPtr
>
(
tpResults
);
...
...
@@ -1074,7 +874,6 @@ int eyemDetectAndDecodeBarcodeUseNN(EyemImage tpImage, EyemRect tpRoi, IntPtr *h
*
hResults
=
tpResults
->
data
();
*
ipNum
=
static_cast
<
int
>
(
tpResults
->
size
());
*
hObject
=
reinterpret_cast
<
IntPtr
>
(
tpResults
);
return
FUNC_OK
;
}
...
...
eyemLib/eyemDataCode.h
查看文件 @
9b0890d
...
...
@@ -10,18 +10,8 @@
std
::
mutex
mtx
;
#define enumtoCharArr(val) #val
cv
::
Ptr
<
NNDetector
>
detector
;
//
struct
tMap
{
int
Label
;
cv
::
Point
Pt
;
tMap
(
int
Label
,
cv
::
Point
Pt
)
:
Label
(
Label
),
Pt
(
Pt
)
{}
};
//预处理区域
struct
WaitArea
{
...
...
eyemLib/eyemGeneric.h
查看文件 @
9b0890d
...
...
@@ -7,5 +7,6 @@
#include "eyemLib.h"
#define enumtoCharArr(val) #val
#endif
/* __EYEM_GENERIC_H */
\ No newline at end of file
eyemLib/eyemMisc.h
查看文件 @
9b0890d
...
...
@@ -12,10 +12,10 @@
#include <tbb\tbb.h>
constexpr
double
c
=
PI
/
180
.;
extern
Logger
logger
;
constexpr
double
c
=
PI
/
180
.;
extern
int
killProcessID
;
#endif
/* __EYEM_MISC_H */
编写
预览
支持
Markdown
格式
附加文件
你添加了
0
人
到此讨论。请谨慎行事。
Finish editing this message first!
Cancel
请
注册
或
登录
后发表评论