-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathauthorCapture.cpp
175 lines (139 loc) · 5.88 KB
/
authorCapture.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
//
// authorCapture.cpp
// QRCode-cpp
//
// Created by wangzeyu on 10/24/17.
// Copyright © 2017 wangzeyu. All rights reserved.
//
#include <string>
#include <exception>
#include <stdlib.h>
#include <fstream>
#include <zxing/common/Counted.h>
#include <zxing/Binarizer.h>
#include <zxing/MultiFormatReader.h>
#include <zxing/Result.h>
#include <zxing/ReaderException.h>
#include <zxing/common/GlobalHistogramBinarizer.h>
#include <zxing/Exception.h>
#include <zxing/common/IllegalArgumentException.h>
#include <zxing/BinaryBitmap.h>
#include <zxing/DecodeHints.h>
#include <zxing/qrcode/QRCodeReader.h>
#include <zxing/MultiFormatReader.h>
#include <zxing/MatSource.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "authorCapture.hpp"
#include "utils.hpp"
using namespace zxing;
using namespace zxing::qrcode;
using namespace cv;
bool authorCapture(string write_img_file, string write_qrpos_file) {
int deviceId = 0;
int captureWidth = 640;
int captureHeight = 480;
bool multi = false;
bool isDetected = false;
Point2f landmarks[4];
// Log
cout << "Capturing from device " << deviceId << "..." << endl;
// Open video captire
VideoCapture videoCapture(deviceId);
if (!videoCapture.isOpened()) {
// Log
cerr << "Open video capture failed on device id: " << deviceId << endl;
return false;
}
if (!videoCapture.set(CAP_PROP_FRAME_WIDTH, captureWidth)) {
// Log
cerr << "Failed to set frame width: " << captureWidth << " (ignoring)" << endl;
}
if (!videoCapture.set(CAP_PROP_FRAME_HEIGHT, captureHeight)) {
// Log
cerr << "Failed to set frame height: " << captureHeight << " (ignoring)" << endl;
}
// The captured image and its grey conversion
Mat image, grey, frame;
// Open output window
namedWindow("Author Capturing (Press c)", cv::WINDOW_AUTOSIZE);
// Stopped flag will be set to -1 from subsequent wayKey() if no key was pressed
int stopped = -1;
while (stopped != 'c') {
// Capture image
bool result = videoCapture.read(image);
isDetected = false;
if (result) {
// Convert to grayscale
cvtColor(image, grey, COLOR_BGR2GRAY);
frame = image.clone();
try {
// Create luminance source
Ref<LuminanceSource> source = MatSource::create(grey);
// Search for QR code
Ref<Reader> reader;
if (multi) {
reader.reset(new MultiFormatReader);
} else {
reader.reset(new QRCodeReader);
}
Ref<Binarizer> binarizer(new GlobalHistogramBinarizer(source));
Ref<BinaryBitmap> bitmap(new BinaryBitmap(binarizer));
Ref<Result> result(reader->decode(bitmap, DecodeHints(DecodeHints::TRYHARDER_HINT)));
// Get result point count
int resultPointCount = result->getResultPoints()->size();
// QR code detected
if (resultPointCount == 4) {
isDetected = true;
for (int j = 0; j < resultPointCount; j++) {
// Save points to landmarks
landmarks[j] = toCvPoint(result->getResultPoints()[j]);
// Draw circles around landmarks
circle(frame, landmarks[j], 10, Scalar(110, 220, 0), 2);
// Get start result point
Ref<ResultPoint> previousResultPoint = (j > 0) ? result->getResultPoints()[j - 1] : result->getResultPoints()[resultPointCount - 1];
// Draw line
line(frame, toCvPoint(previousResultPoint), toCvPoint(result->getResultPoints()[j]), Scalar(110, 220, 0), 2, 8 );
// Update previous point
previousResultPoint = result->getResultPoints()[j];
}
} else {
// Keep capturing if QR code is not detectable
isDetected = false;
}
} catch (const ReaderException& e) {
// cerr << e.what() << " (ignoring)" << endl;
} catch (const zxing::IllegalArgumentException& e) {
// cerr << e.what() << " (ignoring)" << endl;
} catch (const zxing::Exception& e) {
// cerr << e.what() << " (ignoring)" << endl;
} catch (const std::exception& e) {
// cerr << e.what() << " (ignoring)" << endl;
}
// Show captured image
imshow("Author Capturing (Press c)", frame);
// Wait a key for 1 millis
stopped = waitKey(1);
if (!isDetected) {
stopped = -1;
cout << "Keep capturing if QR code is not detectable\n";
continue;
} else if (stopped == 'c' && isDetected) {
imwrite(write_img_file, image);
ofstream fout(write_qrpos_file);
for (int j = 0; j < 4; j++) {
fout << landmarks[j].x << ' ' << landmarks[j].y << endl;
}
fout.close();
imwrite("qr_" + write_img_file, frame);
}
} else {
// Log
cerr << "video capture failed" << endl;
}
}
// Release video capture
videoCapture.release();
return true;
}