-
Notifications
You must be signed in to change notification settings - Fork 0
#KL26-140 二次元コードの検出精度向上 #39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -8,9 +8,8 @@ | |||||
|
|
||||||
| QrCodeDetector::QrCodeDetector() | ||||||
| { | ||||||
| detector.setEpsX(0.2); // 水平方向のファインダパターン探索の許容誤差指定 | ||||||
| detector.setEpsY(0.2); // 垂直方向のファインダパターン探索の許容誤差指定 | ||||||
| options.setFormats(ZXing::BarcodeFormat::QRCode); // QRコードのみを検出 | ||||||
| options.setFormats(ZXing::BarcodeFormat::QRCode); | ||||||
| options.setTryHarder(true); | ||||||
| LOG_CREATE("QrCodeDetector"); | ||||||
| } | ||||||
|
|
||||||
|
|
@@ -28,48 +27,22 @@ QrCodeDetectionResult QrCodeDetector::detect(const cv::Mat& frame) | |||||
| return result; | ||||||
| } | ||||||
|
|
||||||
| // QRコードの各頂点の位置を検出 | ||||||
| std::vector<cv::Point2f> corners; | ||||||
| if(!detector.detect(frame, corners) || corners.size() != 4) { | ||||||
| return result; | ||||||
| } | ||||||
|
|
||||||
| // 透視変換で正面化 | ||||||
| cv::Mat rectifiedFrame = rectify(frame, corners); | ||||||
| // 入力画像からZXing用のImageViewを生成 | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| ZXing::ImageView iv(frame.data, frame.cols, frame.rows, ZXing::ImageFormat::BGR, | ||||||
| static_cast<int>(frame.step)); | ||||||
|
|
||||||
| // 正面化したフレームをデコード | ||||||
| ZXing::ImageView iv(rectifiedFrame.data, rectifiedFrame.cols, rectifiedFrame.rows, | ||||||
| ZXing::ImageFormat::BGR, static_cast<int>(rectifiedFrame.step)); | ||||||
| // 入力画像からQRコードを検出し、デコード結果を取得 | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| auto qrCode = ZXing::ReadBarcode(iv, options); | ||||||
|
|
||||||
| if(qrCode.isValid()) { | ||||||
| result.wasDetected = true; | ||||||
| result.content = qrCode.text(); | ||||||
| for(int i = 0; i < 4; ++i) { | ||||||
| result.corners[i] = corners[i]; | ||||||
| } | ||||||
| // QRコードが検出できなかった場合は終了 | ||||||
| if(!qrCode.isValid()) { | ||||||
| Logger::error("ZXing detect + decode failed"); | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| return result; | ||||||
| } | ||||||
| return result; | ||||||
| } | ||||||
| cv::Mat QrCodeDetector::rectify(const cv::Mat& frame, const std::vector<cv::Point2f>& corners) const | ||||||
| { | ||||||
| // 対辺の長さの最大値を正方形の一辺とする | ||||||
| float maxWidth = std::max(cv::norm(corners[1] - corners[0]), cv::norm(corners[2] - corners[3])); | ||||||
| float maxHeight = std::max(cv::norm(corners[3] - corners[0]), cv::norm(corners[2] - corners[1])); | ||||||
| float outputQrSize = std::max(maxWidth, maxHeight); | ||||||
|
|
||||||
| // クワイエットゾーン(余白)を追加する | ||||||
| float quietZoneSize = outputQrSize * quietZoneRatio; | ||||||
| int outputSize = static_cast<int>(outputQrSize + 2.f * quietZoneSize); | ||||||
| // 検出結果を保存 | ||||||
| result.wasDetected = true; | ||||||
| result.content = qrCode.text(); | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 検出結果(QrCodeDetectionResult)は、検出したQRコードの4頂点の座標も格納するようなデータ構造になってると思う。現状、その4頂点の座標を使うかはわからないけど、検出したQRの中央のx座標に向かってカメラ走行するみたいな動作もできるかもしれないから、検出した4頂点の座標も格納したい。 |
||||||
|
|
||||||
| // 余白分だけ内側にQRコード領域を配置 | ||||||
| std::vector<cv::Point2f> dstCorners | ||||||
| = { { quietZoneSize, quietZoneSize }, | ||||||
| { quietZoneSize + outputQrSize, quietZoneSize }, | ||||||
| { quietZoneSize + outputQrSize, quietZoneSize + outputQrSize }, | ||||||
| { quietZoneSize, quietZoneSize + outputQrSize } }; | ||||||
| cv::Mat pixelNum = cv::getPerspectiveTransform(corners, dstCorners); | ||||||
| cv::Mat rectifiedFrame; | ||||||
| cv::warpPerspective(frame, rectifiedFrame, pixelNum, cv::Size(outputSize, outputSize)); | ||||||
| return rectifiedFrame; | ||||||
| } | ||||||
| return result; | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,12 +9,11 @@ | |
|
|
||
| #include <opencv2/core.hpp> | ||
| #include <opencv2/imgproc.hpp> | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. これも透視変換系の処理が不要であれば、必要ないかな。(11行目) |
||
| #include <opencv2/objdetect.hpp> | ||
| #include <ZXing/ReadBarcode.h> | ||
| #include <ZXing/ReaderOptions.h> | ||
| #include "CodeDetector.h" | ||
| #include "QrCodeDetectionResult.h" | ||
| #include "Logger.h" | ||
| #include "QrCodeDetectionResult.h" | ||
|
|
||
| class QrCodeDetector : public CodeDetector<QrCodeDetectionResult> { | ||
| public: | ||
|
|
@@ -29,24 +28,14 @@ class QrCodeDetector : public CodeDetector<QrCodeDetectionResult> { | |
| ~QrCodeDetector(); | ||
|
|
||
| /** | ||
| * @brief フレーム内のQRコードを検出する | ||
| * @brief フレーム内のQRコードを検出・デコードする | ||
| * @param frame 処理対象のフレーム | ||
| * @return 検出結果(QrCodeDetectionResult型) | ||
| * @return 検出結果 | ||
| */ | ||
| QrCodeDetectionResult detect(const cv::Mat& frame) override; | ||
|
|
||
| private: | ||
| static constexpr float quietZoneRatio = 0.2f; // 透視変換後のクワイエットゾーン比率 | ||
| cv::QRCodeDetector detector; // OpenCVのQRコード検出器 | ||
| ZXing::ReaderOptions options; // ZXingのデコードオプション | ||
|
|
||
| /** | ||
| * @brief 検出したQRコードの各頂点の座標から透視変換でQRコード領域を正面化する | ||
| * @param frame 処理対象のフレーム | ||
| * @param corners 検出したQRコードの各頂点の座標 | ||
| * @return 正面化したQRコード領域のフレーム | ||
| */ | ||
| cv::Mat rectify(const cv::Mat& frame, const std::vector<cv::Point2f>& corners) const; | ||
| ZXing::ReaderOptions options; // ZXingのデコードオプション | ||
| }; | ||
|
|
||
| #endif // QR_CODE_DETECTOR_H | ||
| #endif // QR_CODE_DETECTOR_H | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
コメント欲しい。