Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
1fb7ee0e
Commit
1fb7ee0e
authored
Aug 07, 2018
by
Alexander Nesterov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Optimiaztion search template lines and added sample
parent
d7885ed8
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
354 additions
and
139 deletions
+354
-139
qrcode.cpp
modules/objdetect/src/qrcode.cpp
+182
-137
test_qrcode.cpp
modules/objdetect/test/test_qrcode.cpp
+2
-2
live_detect_qrcode.cpp
samples/cpp/live_detect_qrcode.cpp
+170
-0
No files found.
modules/objdetect/src/qrcode.cpp
View file @
1fb7ee0e
...
@@ -16,19 +16,18 @@ namespace cv
...
@@ -16,19 +16,18 @@ namespace cv
{
{
using
std
::
vector
;
using
std
::
vector
;
class
QRDe
code
class
QRDe
tect
{
{
public
:
public
:
void
init
(
Mat
src
,
double
eps_vertical_
=
0.2
,
double
eps_horizontal_
=
0.1
);
void
init
(
const
Mat
&
src
,
double
eps_vertical_
=
0.2
,
double
eps_horizontal_
=
0.1
);
bool
localization
();
bool
localization
();
bool
transformation
();
bool
computeTransformationPoints
();
Mat
getBinBarcode
()
{
return
bin_barcode
;
}
Mat
getBinBarcode
()
{
return
bin_barcode
;
}
Mat
getStraightBarcode
()
{
return
straight_barcode
;
}
Mat
getStraightBarcode
()
{
return
straight_barcode
;
}
vector
<
Point2f
>
getTransformationPoints
()
{
return
transformation_points
;
}
vector
<
Point2f
>
getTransformationPoints
()
{
return
transformation_points
;
}
protected
:
protected
:
bool
computeTransformationPoints
();
vector
<
Vec3d
>
searchHorizontalLines
();
vector
<
Vec3d
>
searchVerticalLines
();
vector
<
Point2f
>
separateVerticalLines
(
const
vector
<
Vec3d
>
&
list_lines
);
vector
<
Point2f
>
separateHorizontalLines
(
vector
<
Vec3d
>
list_lines
);
void
fixationPoints
(
vector
<
Point2f
>
&
local_point
);
void
fixationPoints
(
vector
<
Point2f
>
&
local_point
);
Point2f
intersectionLines
(
Point2f
a1
,
Point2f
a2
,
Point2f
b1
,
Point2f
b2
);
Point2f
intersectionLines
(
Point2f
a1
,
Point2f
a2
,
Point2f
b1
,
Point2f
b2
);
vector
<
Point2f
>
getQuadrilateral
(
vector
<
Point2f
>
angle_list
);
vector
<
Point2f
>
getQuadrilateral
(
vector
<
Point2f
>
angle_list
);
...
@@ -41,131 +40,144 @@ protected:
...
@@ -41,131 +40,144 @@ protected:
};
};
void
QRDe
code
::
init
(
Mat
src
,
double
eps_vertical_
,
double
eps_horizontal_
)
void
QRDe
tect
::
init
(
const
Mat
&
src
,
double
eps_vertical_
,
double
eps_horizontal_
)
{
{
double
min_side
=
std
::
min
(
src
.
size
().
width
,
src
.
size
().
height
);
CV_Assert
(
!
src
.
empty
());
const
double
min_side
=
std
::
min
(
src
.
size
().
width
,
src
.
size
().
height
);
if
(
min_side
<
512.0
)
if
(
min_side
<
512.0
)
{
{
coeff_expansion
=
512.0
/
min_side
;
coeff_expansion
=
512.0
/
min_side
;
int
width
=
static_cast
<
int
>
(
src
.
size
().
width
*
coeff_expansion
);
const
int
width
=
cvRound
(
src
.
size
().
width
*
coeff_expansion
);
int
height
=
static_cast
<
int
>
(
src
.
size
().
height
*
coeff_expansion
);
const
int
height
=
cvRound
(
src
.
size
().
height
*
coeff_expansion
);
Size
new_size
(
width
,
height
);
Size
new_size
(
width
,
height
);
resize
(
src
,
barcode
,
new_size
);
resize
(
src
,
barcode
,
new_size
,
0
,
0
,
INTER_LINEAR
);
}
}
else
else
{
{
coeff_expansion
=
1.0
;
coeff_expansion
=
1.0
;
barcode
=
src
;
barcode
=
src
;
}
}
eps_vertical
=
eps_vertical_
;
eps_vertical
=
eps_vertical_
;
eps_horizontal
=
eps_horizontal_
;
eps_horizontal
=
eps_horizontal_
;
adaptiveThreshold
(
barcode
,
bin_barcode
,
255
,
ADAPTIVE_THRESH_GAUSSIAN_C
,
THRESH_BINARY
,
71
,
2
);
adaptiveThreshold
(
barcode
,
bin_barcode
,
255
,
ADAPTIVE_THRESH_GAUSSIAN_C
,
THRESH_BINARY
,
83
,
2
);
}
}
vector
<
Vec3d
>
QRDe
code
::
searchVertic
alLines
()
vector
<
Vec3d
>
QRDe
tect
::
searchHorizont
alLines
()
{
{
vector
<
Vec3d
>
result
;
vector
<
Vec3d
>
result
;
int
temp_length
=
0
;
const
int
height_bin_barcode
=
bin_barcode
.
rows
;
uint8_t
next_pixel
,
future_pixel
;
const
int
width_bin_barcode
=
bin_barcode
.
cols
;
vector
<
double
>
test_lines
;
const
size_t
test_lines_size
=
5
;
double
test_lines
[
test_lines_size
];
const
size_t
count_pixels_position
=
1024
;
size_t
pixels_position
[
count_pixels_position
];
size_t
index
=
0
;
for
(
int
x
=
0
;
x
<
bin_barcode
.
rows
;
x
++
)
for
(
int
y
=
0
;
y
<
height_bin_barcode
;
y
++
)
{
{
for
(
int
y
=
0
;
y
<
bin_barcode
.
cols
;
y
++
)
const
uint8_t
*
bin_barcode_row
=
bin_barcode
.
ptr
<
uint8_t
>
(
y
);
{
if
(
bin_barcode
.
at
<
uint8_t
>
(
x
,
y
)
>
0
)
{
continue
;
}
// --------------- Search vertical lines --------------- //
int
pos
=
0
;
for
(;
pos
<
width_bin_barcode
;
pos
++
)
{
if
(
bin_barcode_row
[
pos
]
==
0
)
break
;
}
if
(
pos
==
width_bin_barcode
)
{
continue
;
}
test_lines
.
clear
();
index
=
0
;
future_pixel
=
255
;
pixels_position
[
index
]
=
pixels_position
[
index
+
1
]
=
pixels_position
[
index
+
2
]
=
pos
;
index
+=
3
;
for
(
int
i
=
x
;
i
<
bin_barcode
.
rows
-
1
;
i
++
)
uint8_t
future_pixel
=
255
;
for
(
int
x
=
pos
;
x
<
width_bin_barcode
;
x
++
)
{
{
next_pixel
=
bin_barcode
.
at
<
uint8_t
>
(
i
+
1
,
y
);
if
(
bin_barcode_row
[
x
]
==
future_pixel
)
temp_length
++
;
if
(
next_pixel
==
future_pixel
)
{
{
future_pixel
=
255
-
future_pixel
;
future_pixel
=
255
-
future_pixel
;
test_lines
.
push_back
(
temp_length
);
pixels_position
[
index
]
=
x
;
temp_length
=
0
;
index
++
;
if
(
test_lines
.
size
()
==
5
)
{
break
;
}
}
}
}
}
pixels_position
[
index
]
=
width_bin_barcode
-
1
;
// --------------- Compute vertical lines --------------- //
index
++
;
for
(
size_t
i
=
2
;
i
<
index
-
4
;
i
+=
2
)
if
(
test_lines
.
size
()
==
5
)
{
{
test_lines
[
0
]
=
static_cast
<
double
>
(
pixels_position
[
i
-
1
]
-
pixels_position
[
i
-
2
]);
test_lines
[
1
]
=
static_cast
<
double
>
(
pixels_position
[
i
]
-
pixels_position
[
i
-
1
]);
test_lines
[
2
]
=
static_cast
<
double
>
(
pixels_position
[
i
+
1
]
-
pixels_position
[
i
]);
test_lines
[
3
]
=
static_cast
<
double
>
(
pixels_position
[
i
+
2
]
-
pixels_position
[
i
+
1
]);
test_lines
[
4
]
=
static_cast
<
double
>
(
pixels_position
[
i
+
3
]
-
pixels_position
[
i
+
2
]);
double
length
=
0.0
,
weight
=
0.0
;
double
length
=
0.0
,
weight
=
0.0
;
for
(
size_t
i
=
0
;
i
<
test_lines
.
size
();
i
++
)
{
length
+=
test_lines
[
i
];
}
for
(
size_t
j
=
0
;
j
<
test_lines_size
;
j
++
)
{
length
+=
test_lines
[
j
];
}
CV_Assert
(
length
>
0
);
if
(
length
==
0
)
{
continue
;
}
for
(
size_t
i
=
0
;
i
<
test_lines
.
size
();
i
++
)
for
(
size_t
j
=
0
;
j
<
test_lines_size
;
j
++
)
{
{
if
(
i
==
2
)
{
weight
+=
fabs
((
test_lines
[
i
]
/
length
)
-
3.0
/
7.0
);
}
if
(
j
==
2
)
{
weight
+=
fabs
((
test_lines
[
j
]
/
length
)
-
3.0
/
7.0
);
}
else
{
weight
+=
fabs
((
test_lines
[
i
]
/
length
)
-
1.0
/
7.0
);
}
else
{
weight
+=
fabs
((
test_lines
[
j
]
/
length
)
-
1.0
/
7.0
);
}
}
}
if
(
weight
<
eps_vertical
)
if
(
weight
<
eps_vertical
)
{
{
Vec3d
line
;
Vec3d
line
;
line
[
0
]
=
x
;
line
[
1
]
=
y
,
line
[
2
]
=
length
;
line
[
0
]
=
static_cast
<
double
>
(
pixels_position
[
i
-
2
]);
line
[
1
]
=
y
;
line
[
2
]
=
length
;
result
.
push_back
(
line
);
result
.
push_back
(
line
);
}
}
}
}
}
}
}
return
result
;
return
result
;
}
}
vector
<
Point2f
>
QRDe
code
::
separateHorizontalLines
(
vector
<
Vec3d
>
list_lines
)
vector
<
Point2f
>
QRDe
tect
::
separateVerticalLines
(
const
vector
<
Vec3d
>
&
list_lines
)
{
{
vector
<
Vec3d
>
result
;
vector
<
Vec3d
>
result
;
int
temp_length
=
0
;
int
temp_length
=
0
;
uint8_t
next_pixel
,
future_pixel
;
uint8_t
next_pixel
;
vector
<
double
>
test_lines
;
vector
<
double
>
test_lines
;
for
(
size_t
pnt
=
0
;
pnt
<
list_lines
.
size
();
pnt
++
)
for
(
size_t
pnt
=
0
;
pnt
<
list_lines
.
size
();
pnt
++
)
{
{
int
x
=
static_cast
<
int
>
(
list_lines
[
pnt
][
0
]
+
list_lines
[
pnt
][
2
]
*
0.5
);
const
int
x
=
cvRound
(
list_lines
[
pnt
][
0
]
+
list_lines
[
pnt
][
2
]
*
0.5
);
int
y
=
static_cast
<
int
>
(
list_lines
[
pnt
][
1
]);
const
int
y
=
cvRound
(
list_lines
[
pnt
][
1
]);
// --------------- Search vertical up-lines --------------- //
// --------------- Search horizontal up-lines --------------- //
test_lines
.
clear
();
test_lines
.
clear
();
future_pixel
=
255
;
uint8_t
future_pixel_up
=
255
;
for
(
int
j
=
y
;
j
<
bin_barcode
.
col
s
-
1
;
j
++
)
for
(
int
j
=
y
;
j
<
bin_barcode
.
row
s
-
1
;
j
++
)
{
{
next_pixel
=
bin_barcode
.
at
<
uint8_t
>
(
x
,
j
+
1
);
next_pixel
=
bin_barcode
.
at
<
uint8_t
>
(
j
+
1
,
x
);
temp_length
++
;
temp_length
++
;
if
(
next_pixel
==
future_pixel
)
if
(
next_pixel
==
future_pixel
_up
)
{
{
future_pixel
=
255
-
future_pixel
;
future_pixel
_up
=
255
-
future_pixel_up
;
test_lines
.
push_back
(
temp_length
);
test_lines
.
push_back
(
temp_length
);
temp_length
=
0
;
temp_length
=
0
;
if
(
test_lines
.
size
()
==
3
)
{
break
;
}
if
(
test_lines
.
size
()
==
3
)
{
break
;
}
}
}
}
}
// --------------- Search horizontal down-lines --------------- //
// --------------- Search vertical down-lines --------------- //
future_pixel
=
255
;
uint8_t
future_pixel_down
=
255
;
for
(
int
j
=
y
;
j
>=
1
;
j
--
)
for
(
int
j
=
y
;
j
>=
1
;
j
--
)
{
{
next_pixel
=
bin_barcode
.
at
<
uint8_t
>
(
x
,
j
-
1
);
next_pixel
=
bin_barcode
.
at
<
uint8_t
>
(
j
-
1
,
x
);
temp_length
++
;
temp_length
++
;
if
(
next_pixel
==
future_pixel
)
if
(
next_pixel
==
future_pixel
_down
)
{
{
future_pixel
=
255
-
future_pixel
;
future_pixel
_down
=
255
-
future_pixel_down
;
test_lines
.
push_back
(
temp_length
);
test_lines
.
push_back
(
temp_length
);
temp_length
=
0
;
temp_length
=
0
;
if
(
test_lines
.
size
()
==
6
)
{
break
;
}
if
(
test_lines
.
size
()
==
6
)
{
break
;
}
}
}
}
}
// --------------- Compute
horizont
al lines --------------- //
// --------------- Compute
vertic
al lines --------------- //
if
(
test_lines
.
size
()
==
6
)
if
(
test_lines
.
size
()
==
6
)
{
{
...
@@ -192,34 +204,98 @@ vector<Point2f> QRDecode::separateHorizontalLines(vector<Vec3d> list_lines)
...
@@ -192,34 +204,98 @@ vector<Point2f> QRDecode::separateHorizontalLines(vector<Vec3d> list_lines)
for
(
size_t
i
=
0
;
i
<
result
.
size
();
i
++
)
for
(
size_t
i
=
0
;
i
<
result
.
size
();
i
++
)
{
{
point2f_result
.
push_back
(
point2f_result
.
push_back
(
Point2f
(
static_cast
<
float
>
(
result
[
i
][
1
]
),
Point2f
(
static_cast
<
float
>
(
result
[
i
][
0
]
+
result
[
i
][
2
]
*
0.5
),
static_cast
<
float
>
(
result
[
i
][
0
]
+
result
[
i
][
2
]
*
0.5
)));
static_cast
<
float
>
(
result
[
i
][
1
]
)));
}
}
return
point2f_result
;
return
point2f_result
;
}
}
void
QRDe
code
::
fixationPoints
(
vector
<
Point2f
>
&
local_point
)
void
QRDe
tect
::
fixationPoints
(
vector
<
Point2f
>
&
local_point
)
{
{
double
cos_angles
[
3
],
norm_triangl
[
3
];
double
cos_angles
[
3
],
norm_triangl
[
3
];
norm_triangl
[
0
]
=
norm
(
local_point
[
1
]
-
local_point
[
2
]);
norm_triangl
[
0
]
=
norm
(
local_point
[
1
]
-
local_point
[
2
]);
norm_triangl
[
1
]
=
norm
(
local_point
[
0
]
-
local_point
[
2
]);
norm_triangl
[
1
]
=
norm
(
local_point
[
0
]
-
local_point
[
2
]);
norm_triangl
[
2
]
=
norm
(
local_point
[
1
]
-
local_point
[
0
]);
norm_triangl
[
2
]
=
norm
(
local_point
[
1
]
-
local_point
[
0
]);
cos_angles
[
0
]
=
(
pow
(
norm_triangl
[
1
],
2
)
+
pow
(
norm_triangl
[
2
],
2
)
-
pow
(
norm_triangl
[
0
],
2
))
cos_angles
[
0
]
=
(
norm_triangl
[
1
]
*
norm_triangl
[
1
]
+
norm_triangl
[
2
]
*
norm_triangl
[
2
]
/
(
2
*
norm_triangl
[
1
]
*
norm_triangl
[
2
]);
-
norm_triangl
[
0
]
*
norm_triangl
[
0
])
/
(
2
*
norm_triangl
[
1
]
*
norm_triangl
[
2
]);
cos_angles
[
1
]
=
(
pow
(
norm_triangl
[
0
],
2
)
+
pow
(
norm_triangl
[
2
],
2
)
-
pow
(
norm_triangl
[
1
],
2
))
cos_angles
[
1
]
=
(
norm_triangl
[
0
]
*
norm_triangl
[
0
]
+
norm_triangl
[
2
]
*
norm_triangl
[
2
]
/
(
2
*
norm_triangl
[
0
]
*
norm_triangl
[
2
]);
-
norm_triangl
[
1
]
*
norm_triangl
[
1
])
/
(
2
*
norm_triangl
[
0
]
*
norm_triangl
[
2
]);
cos_angles
[
2
]
=
(
pow
(
norm_triangl
[
0
],
2
)
+
pow
(
norm_triangl
[
1
],
2
)
-
pow
(
norm_triangl
[
2
],
2
))
cos_angles
[
2
]
=
(
norm_triangl
[
0
]
*
norm_triangl
[
0
]
+
norm_triangl
[
1
]
*
norm_triangl
[
1
]
/
(
2
*
norm_triangl
[
0
]
*
norm_triangl
[
1
]);
-
norm_triangl
[
2
]
*
norm_triangl
[
2
])
/
(
2
*
norm_triangl
[
0
]
*
norm_triangl
[
1
]);
const
double
angle_barrier
=
0.85
;
if
(
fabs
(
cos_angles
[
0
])
>
angle_barrier
||
fabs
(
cos_angles
[
1
])
>
angle_barrier
||
fabs
(
cos_angles
[
2
])
>
angle_barrier
)
{
local_point
.
clear
();
return
;
}
size_t
i_min_cos
=
size_t
i_min_cos
=
(
cos_angles
[
0
]
<
cos_angles
[
1
]
&&
cos_angles
[
0
]
<
cos_angles
[
2
])
?
0
:
(
cos_angles
[
0
]
<
cos_angles
[
1
]
&&
cos_angles
[
0
]
<
cos_angles
[
2
])
?
0
:
(
cos_angles
[
1
]
<
cos_angles
[
0
]
&&
cos_angles
[
1
]
<
cos_angles
[
2
])
?
1
:
2
;
(
cos_angles
[
1
]
<
cos_angles
[
0
]
&&
cos_angles
[
1
]
<
cos_angles
[
2
])
?
1
:
2
;
std
::
swap
(
local_point
[
0
],
local_point
[
i_min_cos
]);
size_t
index_max
=
0
;
double
max_area
=
std
::
numeric_limits
<
double
>::
min
();
for
(
size_t
i
=
0
;
i
<
local_point
.
size
();
i
++
)
{
const
size_t
current_index
=
i
%
3
;
const
size_t
left_index
=
(
i
+
1
)
%
3
;
const
size_t
right_index
=
(
i
+
2
)
%
3
;
const
Point2f
current_point
(
local_point
[
current_index
]),
left_point
(
local_point
[
left_index
]),
right_point
(
local_point
[
right_index
]),
central_point
(
intersectionLines
(
current_point
,
Point2f
(
static_cast
<
float
>
((
local_point
[
left_index
].
x
+
local_point
[
right_index
].
x
)
*
0.5
),
static_cast
<
float
>
((
local_point
[
left_index
].
y
+
local_point
[
right_index
].
y
)
*
0.5
)),
Point2f
(
0
,
static_cast
<
float
>
(
bin_barcode
.
rows
-
1
)),
Point2f
(
static_cast
<
float
>
(
bin_barcode
.
cols
-
1
),
static_cast
<
float
>
(
bin_barcode
.
rows
-
1
))));
Point2f
rpt
=
local_point
[
0
],
bpt
=
local_point
[
1
],
gpt
=
local_point
[
2
];
vector
<
Point2f
>
list_area_pnt
;
list_area_pnt
.
push_back
(
current_point
);
vector
<
LineIterator
>
list_line_iter
;
list_line_iter
.
push_back
(
LineIterator
(
bin_barcode
,
current_point
,
left_point
));
list_line_iter
.
push_back
(
LineIterator
(
bin_barcode
,
current_point
,
central_point
));
list_line_iter
.
push_back
(
LineIterator
(
bin_barcode
,
current_point
,
right_point
));
for
(
size_t
k
=
0
;
k
<
list_line_iter
.
size
();
k
++
)
{
uint8_t
future_pixel
=
255
,
count_index
=
0
;
for
(
int
j
=
0
;
j
<
list_line_iter
[
k
].
count
;
j
++
,
++
list_line_iter
[
k
])
{
if
(
list_line_iter
[
k
].
pos
().
x
>=
bin_barcode
.
cols
||
list_line_iter
[
k
].
pos
().
y
>=
bin_barcode
.
rows
)
{
break
;
}
const
uint8_t
value
=
bin_barcode
.
at
<
uint8_t
>
(
list_line_iter
[
k
].
pos
());
if
(
value
==
future_pixel
)
{
future_pixel
=
255
-
future_pixel
;
count_index
++
;
if
(
count_index
==
3
)
{
list_area_pnt
.
push_back
(
list_line_iter
[
k
].
pos
());
break
;
}
}
}
}
const
double
temp_check_area
=
contourArea
(
list_area_pnt
);
if
(
temp_check_area
>
max_area
)
{
index_max
=
current_index
;
max_area
=
temp_check_area
;
}
}
if
(
index_max
==
i_min_cos
)
{
std
::
swap
(
local_point
[
0
],
local_point
[
index_max
]);
}
else
{
local_point
.
clear
();
return
;
}
const
Point2f
rpt
=
local_point
[
0
],
bpt
=
local_point
[
1
],
gpt
=
local_point
[
2
];
Matx22f
m
(
rpt
.
x
-
bpt
.
x
,
rpt
.
y
-
bpt
.
y
,
gpt
.
x
-
rpt
.
x
,
gpt
.
y
-
rpt
.
y
);
Matx22f
m
(
rpt
.
x
-
bpt
.
x
,
rpt
.
y
-
bpt
.
y
,
gpt
.
x
-
rpt
.
x
,
gpt
.
y
-
rpt
.
y
);
if
(
determinant
(
m
)
>
0
)
if
(
determinant
(
m
)
>
0
)
{
{
...
@@ -227,19 +303,18 @@ void QRDecode::fixationPoints(vector<Point2f> &local_point)
...
@@ -227,19 +303,18 @@ void QRDecode::fixationPoints(vector<Point2f> &local_point)
}
}
}
}
bool
QRDe
code
::
localization
()
bool
QRDe
tect
::
localization
()
{
{
Point2f
begin
,
end
;
Point2f
begin
,
end
;
vector
<
Vec3d
>
list_lines_x
=
search
Vertic
alLines
();
vector
<
Vec3d
>
list_lines_x
=
search
Horizont
alLines
();
if
(
list_lines_x
.
empty
()
)
{
return
false
;
}
if
(
list_lines_x
.
empty
()
)
{
return
false
;
}
vector
<
Point2f
>
list_lines_y
=
separate
Horizont
alLines
(
list_lines_x
);
vector
<
Point2f
>
list_lines_y
=
separate
Vertic
alLines
(
list_lines_x
);
if
(
list_lines_y
.
empty
()
)
{
return
false
;
}
if
(
list_lines_y
.
size
()
<
3
)
{
return
false
;
}
vector
<
Point2f
>
centers
;
vector
<
Point2f
>
centers
;
Mat
labels
;
Mat
labels
;
if
(
list_lines_y
.
size
()
<
3
)
{
return
false
;
}
kmeans
(
list_lines_y
,
3
,
labels
,
kmeans
(
list_lines_y
,
3
,
labels
,
TermCriteria
(
TermCriteria
::
EPS
+
TermCriteria
::
COUNT
,
10
,
1.0
),
TermCriteria
(
TermCriteria
::
EPS
+
TermCriteria
::
COUNT
,
10
,
0.1
),
3
,
KMEANS_PP_CENTERS
,
localization_points
);
3
,
KMEANS_PP_CENTERS
,
localization_points
);
fixationPoints
(
localization_points
);
fixationPoints
(
localization_points
);
...
@@ -247,11 +322,11 @@ bool QRDecode::localization()
...
@@ -247,11 +322,11 @@ bool QRDecode::localization()
if
(
coeff_expansion
>
1.0
)
if
(
coeff_expansion
>
1.0
)
{
{
int
width
=
static_cast
<
int
>
(
bin_barcode
.
size
().
width
/
coeff_expansion
);
const
int
width
=
cvRound
(
bin_barcode
.
size
().
width
/
coeff_expansion
);
int
height
=
static_cast
<
int
>
(
bin_barcode
.
size
().
height
/
coeff_expansion
);
const
int
height
=
cvRound
(
bin_barcode
.
size
().
height
/
coeff_expansion
);
Size
new_size
(
width
,
height
);
Size
new_size
(
width
,
height
);
Mat
intermediate
;
Mat
intermediate
=
Mat
::
zeros
(
new_size
,
CV_8UC1
)
;
resize
(
bin_barcode
,
intermediate
,
new_size
);
resize
(
bin_barcode
,
intermediate
,
new_size
,
0
,
0
,
INTER_LINEAR
);
bin_barcode
=
intermediate
.
clone
();
bin_barcode
=
intermediate
.
clone
();
for
(
size_t
i
=
0
;
i
<
localization_points
.
size
();
i
++
)
for
(
size_t
i
=
0
;
i
<
localization_points
.
size
();
i
++
)
{
{
...
@@ -273,7 +348,7 @@ bool QRDecode::localization()
...
@@ -273,7 +348,7 @@ bool QRDecode::localization()
}
}
bool
QRDe
code
::
computeTransformationPoints
()
bool
QRDe
tect
::
computeTransformationPoints
()
{
{
if
(
localization_points
.
size
()
!=
3
)
{
return
false
;
}
if
(
localization_points
.
size
()
!=
3
)
{
return
false
;
}
...
@@ -283,11 +358,11 @@ bool QRDecode::computeTransformationPoints()
...
@@ -283,11 +358,11 @@ bool QRDecode::computeTransformationPoints()
{
{
Mat
mask
=
Mat
::
zeros
(
bin_barcode
.
rows
+
2
,
bin_barcode
.
cols
+
2
,
CV_8UC1
);
Mat
mask
=
Mat
::
zeros
(
bin_barcode
.
rows
+
2
,
bin_barcode
.
cols
+
2
,
CV_8UC1
);
uint8_t
next_pixel
,
future_pixel
=
255
;
uint8_t
next_pixel
,
future_pixel
=
255
;
int
count_test_lines
=
0
,
index
=
static_cast
<
int
>
(
localization_points
[
i
].
x
);
int
count_test_lines
=
0
,
index
=
cvRound
(
localization_points
[
i
].
x
);
for
(;
index
<
bin_barcode
.
cols
-
1
;
index
++
)
for
(;
index
<
bin_barcode
.
cols
-
1
;
index
++
)
{
{
next_pixel
=
bin_barcode
.
at
<
uint8_t
>
(
next_pixel
=
bin_barcode
.
at
<
uint8_t
>
(
static_cast
<
int
>
(
localization_points
[
i
].
y
),
index
+
1
);
cvRound
(
localization_points
[
i
].
y
),
index
+
1
);
if
(
next_pixel
==
future_pixel
)
if
(
next_pixel
==
future_pixel
)
{
{
future_pixel
=
255
-
future_pixel
;
future_pixel
=
255
-
future_pixel
;
...
@@ -295,7 +370,7 @@ bool QRDecode::computeTransformationPoints()
...
@@ -295,7 +370,7 @@ bool QRDecode::computeTransformationPoints()
if
(
count_test_lines
==
2
)
if
(
count_test_lines
==
2
)
{
{
floodFill
(
bin_barcode
,
mask
,
floodFill
(
bin_barcode
,
mask
,
Point
(
index
+
1
,
static_cast
<
int
>
(
localization_points
[
i
].
y
)),
255
,
Point
(
index
+
1
,
cvRound
(
localization_points
[
i
].
y
)),
255
,
0
,
Scalar
(),
Scalar
(),
FLOODFILL_MASK_ONLY
);
0
,
Scalar
(),
Scalar
(),
FLOODFILL_MASK_ONLY
);
break
;
break
;
}
}
...
@@ -397,7 +472,7 @@ bool QRDecode::computeTransformationPoints()
...
@@ -397,7 +472,7 @@ bool QRDecode::computeTransformationPoints()
return
true
;
return
true
;
}
}
Point2f
QRDe
code
::
intersectionLines
(
Point2f
a1
,
Point2f
a2
,
Point2f
b1
,
Point2f
b2
)
Point2f
QRDe
tect
::
intersectionLines
(
Point2f
a1
,
Point2f
a2
,
Point2f
b1
,
Point2f
b2
)
{
{
Point2f
result_square_angle
(
Point2f
result_square_angle
(
((
a1
.
x
*
a2
.
y
-
a1
.
y
*
a2
.
x
)
*
(
b1
.
x
-
b2
.
x
)
-
((
a1
.
x
*
a2
.
y
-
a1
.
y
*
a2
.
x
)
*
(
b1
.
x
-
b2
.
x
)
-
...
@@ -413,7 +488,7 @@ Point2f QRDecode::intersectionLines(Point2f a1, Point2f a2, Point2f b1, Point2f
...
@@ -413,7 +488,7 @@ Point2f QRDecode::intersectionLines(Point2f a1, Point2f a2, Point2f b1, Point2f
}
}
// test function (if true then ------> else <------ )
// test function (if true then ------> else <------ )
bool
QRDe
code
::
testBypassRoute
(
vector
<
Point2f
>
hull
,
int
start
,
int
finish
)
bool
QRDe
tect
::
testBypassRoute
(
vector
<
Point2f
>
hull
,
int
start
,
int
finish
)
{
{
int
index_hull
=
start
,
next_index_hull
,
hull_size
=
(
int
)
hull
.
size
();
int
index_hull
=
start
,
next_index_hull
,
hull_size
=
(
int
)
hull
.
size
();
double
test_length
[
2
]
=
{
0.0
,
0.0
};
double
test_length
[
2
]
=
{
0.0
,
0.0
};
...
@@ -439,7 +514,7 @@ bool QRDecode::testBypassRoute(vector<Point2f> hull, int start, int finish)
...
@@ -439,7 +514,7 @@ bool QRDecode::testBypassRoute(vector<Point2f> hull, int start, int finish)
if
(
test_length
[
0
]
<
test_length
[
1
])
{
return
true
;
}
else
{
return
false
;
}
if
(
test_length
[
0
]
<
test_length
[
1
])
{
return
true
;
}
else
{
return
false
;
}
}
}
vector
<
Point2f
>
QRDe
code
::
getQuadrilateral
(
vector
<
Point2f
>
angle_list
)
vector
<
Point2f
>
QRDe
tect
::
getQuadrilateral
(
vector
<
Point2f
>
angle_list
)
{
{
size_t
angle_size
=
angle_list
.
size
();
size_t
angle_size
=
angle_list
.
size
();
uint8_t
value
,
mask_value
;
uint8_t
value
,
mask_value
;
...
@@ -467,8 +542,8 @@ vector<Point2f> QRDecode::getQuadrilateral(vector<Point2f> angle_list)
...
@@ -467,8 +542,8 @@ vector<Point2f> QRDecode::getQuadrilateral(vector<Point2f> angle_list)
for
(
size_t
i
=
0
;
i
<
angle_list
.
size
();
i
++
)
for
(
size_t
i
=
0
;
i
<
angle_list
.
size
();
i
++
)
{
{
int
x
=
static_cast
<
int
>
(
angle_list
[
i
].
x
);
int
x
=
cvRound
(
angle_list
[
i
].
x
);
int
y
=
static_cast
<
int
>
(
angle_list
[
i
].
y
);
int
y
=
cvRound
(
angle_list
[
i
].
y
);
locations
.
push_back
(
Point
(
x
,
y
));
locations
.
push_back
(
Point
(
x
,
y
));
}
}
...
@@ -478,8 +553,8 @@ vector<Point2f> QRDecode::getQuadrilateral(vector<Point2f> angle_list)
...
@@ -478,8 +553,8 @@ vector<Point2f> QRDecode::getQuadrilateral(vector<Point2f> angle_list)
vector
<
Point2f
>
hull
(
hull_size
);
vector
<
Point2f
>
hull
(
hull_size
);
for
(
int
i
=
0
;
i
<
hull_size
;
i
++
)
for
(
int
i
=
0
;
i
<
hull_size
;
i
++
)
{
{
float
x
=
s
tatic
_cast
<
float
>
(
integer_hull
[
i
].
x
);
float
x
=
s
aturate
_cast
<
float
>
(
integer_hull
[
i
].
x
);
float
y
=
s
tatic
_cast
<
float
>
(
integer_hull
[
i
].
y
);
float
y
=
s
aturate
_cast
<
float
>
(
integer_hull
[
i
].
y
);
hull
[
i
]
=
Point2f
(
x
,
y
);
hull
[
i
]
=
Point2f
(
x
,
y
);
}
}
...
@@ -516,7 +591,6 @@ vector<Point2f> QRDecode::getQuadrilateral(vector<Point2f> angle_list)
...
@@ -516,7 +591,6 @@ vector<Point2f> QRDecode::getQuadrilateral(vector<Point2f> angle_list)
Point
result_side_begin
[
4
],
result_side_end
[
4
];
Point
result_side_begin
[
4
],
result_side_end
[
4
];
bool
bypass_orientation
=
testBypassRoute
(
hull
,
start_line
[
0
],
finish_line
[
0
]);
bool
bypass_orientation
=
testBypassRoute
(
hull
,
start_line
[
0
],
finish_line
[
0
]);
bool
extra_bypass_orientation
;
min_norm
=
std
::
numeric_limits
<
double
>::
max
();
min_norm
=
std
::
numeric_limits
<
double
>::
max
();
index_hull
=
start_line
[
0
];
index_hull
=
start_line
[
0
];
...
@@ -593,12 +667,12 @@ vector<Point2f> QRDecode::getQuadrilateral(vector<Point2f> angle_list)
...
@@ -593,12 +667,12 @@ vector<Point2f> QRDecode::getQuadrilateral(vector<Point2f> angle_list)
}
}
bypass_orientation
=
testBypassRoute
(
hull
,
start_line
[
0
],
unstable_pnt
);
bypass_orientation
=
testBypassRoute
(
hull
,
start_line
[
0
],
unstable_pnt
);
extra_bypass_orientation
=
testBypassRoute
(
hull
,
finish_line
[
1
],
unstable_pnt
);
const
bool
extra_bypass_orientation
=
testBypassRoute
(
hull
,
finish_line
[
1
],
unstable_pnt
);
vector
<
Point2f
>
result_angle_list
(
4
),
test_result_angle_list
(
4
);
vector
<
Point2f
>
result_angle_list
(
4
),
test_result_angle_list
(
4
);
double
min_diff_area
=
std
::
numeric_limits
<
double
>::
max
()
,
test_diff_area
;
double
min_diff_area
=
std
::
numeric_limits
<
double
>::
max
();
index_hull
=
start_line
[
0
];
index_hull
=
start_line
[
0
];
double
standart_norm
=
std
::
max
(
const
double
standart_norm
=
std
::
max
(
norm
(
result_side_begin
[
0
]
-
result_side_end
[
0
]),
norm
(
result_side_begin
[
0
]
-
result_side_end
[
0
]),
norm
(
result_side_begin
[
1
]
-
result_side_end
[
1
]));
norm
(
result_side_begin
[
1
]
-
result_side_end
[
1
]));
do
do
...
@@ -637,7 +711,8 @@ vector<Point2f> QRDecode::getQuadrilateral(vector<Point2f> angle_list)
...
@@ -637,7 +711,8 @@ vector<Point2f> QRDecode::getQuadrilateral(vector<Point2f> angle_list)
=
intersectionLines
(
hull
[
index_hull
],
hull
[
next_index_hull
],
=
intersectionLines
(
hull
[
index_hull
],
hull
[
next_index_hull
],
result_side_begin
[
0
],
result_side_end
[
0
]);
result_side_begin
[
0
],
result_side_end
[
0
]);
test_diff_area
=
fabs
(
fabs
(
contourArea
(
test_result_angle_list
))
-
experimental_area
);
const
double
test_diff_area
=
fabs
(
fabs
(
contourArea
(
test_result_angle_list
))
-
experimental_area
);
if
(
min_diff_area
>
test_diff_area
)
if
(
min_diff_area
>
test_diff_area
)
{
{
min_diff_area
=
test_diff_area
;
min_diff_area
=
test_diff_area
;
...
@@ -655,10 +730,17 @@ vector<Point2f> QRDecode::getQuadrilateral(vector<Point2f> angle_list)
...
@@ -655,10 +730,17 @@ vector<Point2f> QRDecode::getQuadrilateral(vector<Point2f> angle_list)
}
}
while
(
index_hull
!=
unstable_pnt
);
while
(
index_hull
!=
unstable_pnt
);
// check label points
if
(
norm
(
result_angle_list
[
0
]
-
angle_list
[
1
])
>
2
)
{
result_angle_list
[
0
]
=
angle_list
[
1
];
}
if
(
norm
(
result_angle_list
[
0
]
-
angle_list
[
1
])
>
2
)
{
result_angle_list
[
0
]
=
angle_list
[
1
];
}
if
(
norm
(
result_angle_list
[
1
]
-
angle_list
[
0
])
>
2
)
{
result_angle_list
[
1
]
=
angle_list
[
0
];
}
if
(
norm
(
result_angle_list
[
1
]
-
angle_list
[
0
])
>
2
)
{
result_angle_list
[
1
]
=
angle_list
[
0
];
}
if
(
norm
(
result_angle_list
[
3
]
-
angle_list
[
2
])
>
2
)
{
result_angle_list
[
3
]
=
angle_list
[
2
];
}
if
(
norm
(
result_angle_list
[
3
]
-
angle_list
[
2
])
>
2
)
{
result_angle_list
[
3
]
=
angle_list
[
2
];
}
// check calculation point
if
(
norm
(
result_angle_list
[
2
]
-
angle_list
[
3
])
>
(
norm
(
result_angle_list
[
0
]
-
result_angle_list
[
1
])
+
norm
(
result_angle_list
[
0
]
-
result_angle_list
[
3
]))
*
0.5
)
{
result_angle_list
[
2
]
=
angle_list
[
3
];
}
return
result_angle_list
;
return
result_angle_list
;
}
}
...
@@ -667,48 +749,11 @@ vector<Point2f> QRDecode::getQuadrilateral(vector<Point2f> angle_list)
...
@@ -667,48 +749,11 @@ vector<Point2f> QRDecode::getQuadrilateral(vector<Point2f> angle_list)
// / |
// / |
// a/ | c
// a/ | c
inline
double
QRDe
code
::
getCosVectors
(
Point2f
a
,
Point2f
b
,
Point2f
c
)
inline
double
QRDe
tect
::
getCosVectors
(
Point2f
a
,
Point2f
b
,
Point2f
c
)
{
{
return
((
a
-
b
).
x
*
(
c
-
b
).
x
+
(
a
-
b
).
y
*
(
c
-
b
).
y
)
/
(
norm
(
a
-
b
)
*
norm
(
c
-
b
));
return
((
a
-
b
).
x
*
(
c
-
b
).
x
+
(
a
-
b
).
y
*
(
c
-
b
).
y
)
/
(
norm
(
a
-
b
)
*
norm
(
c
-
b
));
}
}
bool
QRDecode
::
transformation
()
{
if
(
!
computeTransformationPoints
())
{
return
false
;
}
double
max_length_norm
=
-
1
;
size_t
transform_size
=
transformation_points
.
size
();
for
(
size_t
i
=
0
;
i
<
transform_size
;
i
++
)
{
double
len_norm
=
norm
(
transformation_points
[
i
%
transform_size
]
-
transformation_points
[(
i
+
1
)
%
transform_size
]);
max_length_norm
=
std
::
max
(
max_length_norm
,
len_norm
);
}
Point2f
transformation_points_
[]
=
{
transformation_points
[
0
],
transformation_points
[
1
],
transformation_points
[
2
],
transformation_points
[
3
]
};
Point2f
perspective_points
[]
=
{
Point2f
(
0.
f
,
0.
f
),
Point2f
(
0.
f
,
(
float
)
max_length_norm
),
Point2f
((
float
)
max_length_norm
,
(
float
)
max_length_norm
),
Point2f
((
float
)
max_length_norm
,
0.
f
)
};
Mat
H
=
getPerspectiveTransform
(
transformation_points_
,
perspective_points
);
warpPerspective
(
bin_barcode
,
straight_barcode
,
H
,
Size
(
static_cast
<
int
>
(
max_length_norm
),
static_cast
<
int
>
(
max_length_norm
)));
return
true
;
}
struct
QRCodeDetector
::
Impl
struct
QRCodeDetector
::
Impl
{
{
public
:
public
:
...
@@ -729,11 +774,11 @@ bool QRCodeDetector::detect(InputArray in, OutputArray points) const
...
@@ -729,11 +774,11 @@ bool QRCodeDetector::detect(InputArray in, OutputArray points) const
Mat
inarr
=
in
.
getMat
();
Mat
inarr
=
in
.
getMat
();
CV_Assert
(
!
inarr
.
empty
());
CV_Assert
(
!
inarr
.
empty
());
CV_Assert
(
inarr
.
type
()
==
CV_8UC1
);
CV_Assert
(
inarr
.
type
()
==
CV_8UC1
);
QRDe
code
qrdec
;
QRDe
tect
qrdet
;
qrde
c
.
init
(
inarr
,
p
->
epsX
,
p
->
epsY
);
qrde
t
.
init
(
inarr
,
p
->
epsX
,
p
->
epsY
);
if
(
!
qrde
c
.
localization
())
{
return
false
;
}
if
(
!
qrde
t
.
localization
())
{
return
false
;
}
if
(
!
qrde
c
.
transformation
())
{
return
false
;
}
if
(
!
qrde
t
.
computeTransformationPoints
())
{
return
false
;
}
vector
<
Point2f
>
pnts2f
=
qrde
c
.
getTransformationPoints
();
vector
<
Point2f
>
pnts2f
=
qrde
t
.
getTransformationPoints
();
Mat
(
pnts2f
).
convertTo
(
points
,
points
.
fixedType
()
?
points
.
type
()
:
CV_32FC2
);
Mat
(
pnts2f
).
convertTo
(
points
,
points
.
fixedType
()
?
points
.
type
()
:
CV_32FC2
);
return
true
;
return
true
;
}
}
...
...
modules/objdetect/test/test_qrcode.cpp
View file @
1fb7ee0e
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
namespace
opencv_test
{
namespace
{
namespace
opencv_test
{
namespace
{
std
::
string
qrcode_images_name
[]
=
{
std
::
string
qrcode_images_name
[]
=
{
"20110817_030.jpg"
,
//
"20110817_030.jpg",
"20110817_048.jpg"
,
"20110817_048.jpg"
,
"img_20120226_161648.jpg"
,
"img_20120226_161648.jpg"
,
"img_2714.jpg"
,
"img_2714.jpg"
,
...
@@ -63,7 +63,7 @@ TEST_P(Objdetect_QRCode, regression)
...
@@ -63,7 +63,7 @@ TEST_P(Objdetect_QRCode, regression)
ASSERT_FALSE
(
src
.
empty
())
<<
"Can't read image: "
<<
image_path
;
ASSERT_FALSE
(
src
.
empty
())
<<
"Can't read image: "
<<
image_path
;
std
::
vector
<
Point
>
corners
;
std
::
vector
<
Point
>
corners
;
EXPEC
T_TRUE
(
detectQRCode
(
src
,
corners
));
ASSER
T_TRUE
(
detectQRCode
(
src
,
corners
));
const
std
::
string
dataset_config
=
findDataFile
(
root
+
"dataset_config.json"
,
false
);
const
std
::
string
dataset_config
=
findDataFile
(
root
+
"dataset_config.json"
,
false
);
FileStorage
file_config
(
dataset_config
,
FileStorage
::
READ
);
FileStorage
file_config
(
dataset_config
,
FileStorage
::
READ
);
...
...
samples/cpp/live_detect_qrcode.cpp
0 → 100644
View file @
1fb7ee0e
#include "opencv2/objdetect.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <string>
#include <iostream>
using
namespace
std
;
using
namespace
cv
;
void
getMatWithQRCodeContour
(
Mat
&
color_image
,
vector
<
Point
>
transform
);
void
getMatWithFPS
(
Mat
&
color_image
,
double
fps
);
int
liveQRCodeDetect
();
int
showImageQRCodeDetect
(
string
in
,
string
out
);
int
main
(
int
argc
,
char
*
argv
[])
{
const
string
keys
=
"{h help ? | | print help messages }"
"{i in | | input path to file for detect (with parameter - show image, otherwise - camera)}"
"{o out | | output path to file (save image, work with -i parameter) }"
;
CommandLineParser
cmd_parser
(
argc
,
argv
,
keys
);
cmd_parser
.
about
(
"This program detects the QR-codes from camera or images using the OpenCV library."
);
if
(
cmd_parser
.
has
(
"help"
))
{
cmd_parser
.
printMessage
();
return
0
;
}
string
in_file_name
=
cmd_parser
.
get
<
string
>
(
"in"
);
// input path to image
string
out_file_name
=
cmd_parser
.
get
<
string
>
(
"out"
);
// output path to image
if
(
!
cmd_parser
.
check
())
{
cmd_parser
.
printErrors
();
return
-
1
;
}
int
return_code
=
0
;
if
(
in_file_name
.
empty
())
{
return_code
=
liveQRCodeDetect
();
}
else
{
return_code
=
showImageQRCodeDetect
(
in_file_name
,
out_file_name
);
}
return
return_code
;
}
void
getMatWithQRCodeContour
(
Mat
&
color_image
,
vector
<
Point
>
transform
)
{
if
(
!
transform
.
empty
())
{
double
show_radius
=
(
color_image
.
rows
>
color_image
.
cols
)
?
(
2.813
*
color_image
.
rows
)
/
color_image
.
cols
:
(
2.813
*
color_image
.
cols
)
/
color_image
.
rows
;
double
contour_radius
=
show_radius
*
0.4
;
vector
<
vector
<
Point
>
>
contours
;
contours
.
push_back
(
transform
);
drawContours
(
color_image
,
contours
,
0
,
Scalar
(
211
,
0
,
148
),
cvRound
(
contour_radius
));
RNG
rng
(
1000
);
for
(
size_t
i
=
0
;
i
<
4
;
i
++
)
{
Scalar
color
=
Scalar
(
rng
.
uniform
(
0
,
255
),
rng
.
uniform
(
0
,
255
),
rng
.
uniform
(
0
,
255
));
circle
(
color_image
,
transform
[
i
],
cvRound
(
show_radius
),
color
,
-
1
);
}
}
}
void
getMatWithFPS
(
Mat
&
color_image
,
double
fps
)
{
ostringstream
convert
;
convert
<<
cvRound
(
fps
)
<<
" FPS."
;
putText
(
color_image
,
convert
.
str
(),
Point
(
25
,
25
),
FONT_HERSHEY_DUPLEX
,
1
,
Scalar
(
0
,
0
,
255
),
2
);
}
int
liveQRCodeDetect
()
{
VideoCapture
cap
(
0
);
if
(
!
cap
.
isOpened
())
{
cout
<<
"Cannot open a camera"
<<
'\n'
;
return
-
4
;
}
TickMeter
total
;
for
(;;)
{
Mat
frame
,
src
;
vector
<
Point
>
transform
;
cap
>>
frame
;
if
(
frame
.
empty
())
{
break
;
}
cvtColor
(
frame
,
src
,
COLOR_BGR2GRAY
);
total
.
start
();
bool
result_detection
=
detectQRCode
(
src
,
transform
);
total
.
stop
();
double
fps
=
1
/
total
.
getTimeSec
();
total
.
reset
();
if
(
result_detection
)
{
getMatWithQRCodeContour
(
frame
,
transform
);
}
getMatWithFPS
(
frame
,
fps
);
imshow
(
"Live detect QR code"
,
frame
);
if
(
waitKey
(
30
)
>
0
)
{
break
;
}
}
return
0
;
}
int
showImageQRCodeDetect
(
string
in
,
string
out
)
{
Mat
src
=
imread
(
in
,
IMREAD_GRAYSCALE
);
vector
<
Point
>
transform
;
const
int
count_experiments
=
10
;
double
transform_time
=
0.0
;
bool
result_detection
=
false
;
TickMeter
total
;
for
(
size_t
i
=
0
;
i
<
count_experiments
;
i
++
)
{
total
.
start
();
transform
.
clear
();
result_detection
=
detectQRCode
(
src
,
transform
);
total
.
stop
();
transform_time
+=
total
.
getTimeSec
();
if
(
!
result_detection
)
{
break
;
}
total
.
reset
();
}
double
fps
=
count_experiments
/
transform_time
;
if
(
!
result_detection
)
{
cout
<<
"Not find QR-code."
<<
'\n'
;
return
-
2
;
}
Mat
color_src
=
imread
(
in
);
getMatWithQRCodeContour
(
color_src
,
transform
);
getMatWithFPS
(
color_src
,
fps
);
for
(;;)
{
imshow
(
"Detect QR code on image"
,
color_src
);
if
(
waitKey
(
30
)
>
0
)
{
break
;
}
}
if
(
!
out
.
empty
())
{
getMatWithQRCodeContour
(
color_src
,
transform
);
getMatWithFPS
(
color_src
,
fps
);
cout
<<
"Input image file path: "
<<
in
<<
'\n'
;
cout
<<
"Output image file path: "
<<
out
<<
'\n'
;
cout
<<
"Size: "
<<
color_src
.
size
()
<<
'\n'
;
cout
<<
"FPS: "
<<
fps
<<
'\n'
;
vector
<
int
>
compression_params
;
compression_params
.
push_back
(
IMWRITE_PNG_COMPRESSION
);
compression_params
.
push_back
(
9
);
try
{
imwrite
(
out
,
color_src
,
compression_params
);
}
catch
(
cv
::
Exception
&
ex
)
{
cout
<<
"Exception converting image to PNG format: "
;
cout
<<
ex
.
what
()
<<
'\n'
;
return
-
3
;
}
}
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment