基于OpenCV实现二维码发现与定位
生活随笔
收集整理的這篇文章主要介紹了
基于OpenCV实现二维码发现与定位
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
基于OpenCV實現二維碼發現與定位
在如今流行掃描的年代,應用程序實現二維碼掃描檢測與識別已經是應用程序的標配、特別是在移動端、如果你的應用程序不能自動發現檢測二維碼,自動定位二維碼你都不好意思跟別人打招呼,二維碼識別與解析基于ZXing包即可。難點就在于如何從畫面中快速而準確的找到二維碼區域,尋找到二維碼三個匹配模式點。
一:二維碼的結構與基本原理
標準的二維碼結構如下:
特別要關注的是圖中三個黑色正方形區域,它們就是用來定位一個二維碼的最重要的三個區域,我們二維碼掃描與檢測首先要做的就是要發現這三個區域,如果找到這個三個區域,我們就成功的發現一個二維碼了,就可以對它定位與識別了。二維碼其它各個部分的說明如下:
三個角上的正方形區域從左到右,從上到下黑白比例為1:1:3:1:1。
不管角度如何變化,這個是最顯著的特征,通過這個特征我們就可以實現二維碼掃描檢測與定位。
二:算法各部與輸出
1. 首先把輸入圖像轉換為灰度圖像
2. 通過OTSU轉換為二值圖像
3. 對二值圖像使用輪廓發現得到輪廓
4. 根據二維碼三個區域的特征,對輪廓進行面積與比例過濾得到最終結果顯示如下:
三:程序運行演示與代碼實現
下面的圖片左側為原圖、右側為二維碼定位結果
程序各個步驟完整源代碼如下
#include <opencv2/opencv.hpp> #include <math.h> #include <iostream>using namespace cv; using namespace std;void scanAndDetectQRCode(Mat & image, int index); bool isXCorner(Mat &image); bool isYCorner(Mat &image); Mat transformCorner(Mat &image, RotatedRect &rect); int main(int argc, char** argv) {/*for (int i = 1; i < 25; i++) {Mat qrcode_image = imread(format("D:/gloomyfish/qrcode/%d.jpg", i));scanAndDetectQRCode(qrcode_image, i);}return 0;*/Mat src = imread("D:/gloomyfish/qrcode_99.jpg");if (src.empty()) {printf("could not load image...\n");return -1;}namedWindow("input image", CV_WINDOW_AUTOSIZE);imshow("input image", src);Mat gray, binary;cvtColor(src, gray, COLOR_BGR2GRAY);imwrite("D:/gloomyfish/outimage/qrcode_gray.jpg", gray);threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);imwrite("D:/gloomyfish/outimage/qrcode_binary.jpg", binary);// detect rectangle nowvector<vector<Point>> contours;vector<Vec4i> hireachy;Moments monents;findContours(binary.clone(), contours, hireachy, RETR_LIST, CHAIN_APPROX_SIMPLE, Point());Mat result = Mat::zeros(src.size(), CV_8UC3);for (size_t t = 0; t < contours.size(); t++) {double area = contourArea(contours[t]);if (area < 100) continue;RotatedRect rect = minAreaRect(contours[t]);// 根據矩形特征進行幾何分析float w = rect.size.width;float h = rect.size.height;float rate = min(w, h) / max(w, h);if (rate > 0.85 && w < src.cols/4 && h<src.rows/4) {printf("angle : %.2f\n", rect.angle);Mat qr_roi = transformCorner(src, rect);if (isXCorner(qr_roi) && isYCorner(qr_roi)) {drawContours(src, contours, static_cast<int>(t), Scalar(0, 0, 255), 2, 8);imwrite(format("D:/gloomyfish/outimage/contour_%d.jpg", static_cast<int>(t)), qr_roi);drawContours(result, contours, static_cast<int>(t), Scalar(255, 0, 0), 2, 8);}}}imshow("result", src);imwrite("D:/gloomyfish/outimage/qrcode_patters.jpg", src);waitKey(0);return 0; }歡迎繼續關注本博客,加入OpenCV學習群
總結
以上是生活随笔為你收集整理的基于OpenCV实现二维码发现与定位的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 跨文化沟通初探
- 下一篇: c语言规定对程序中所用的变量必须,【判断