日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于OpenCV实现二维码发现与定位

發布時間:2024/3/13 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于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实现二维码发现与定位的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。