I have written an OpenCV QR code recognition program that can scan 2 QR codes but I keep getting an “Out of range vector error”. I have already tried several things to fix the error, but nothing has helped. Here is my code:
#include <iostream>
#include <fstream>
#include <opencv2/objdetect.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/opencv.hpp>
#include "opencv2/videoio.hpp"
#include <opencv2/video.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
// Funktion zum Anzeigen der erkannten QR-Code-Rahmenbox
void display(Mat& im, Mat& bbox)
{
if (bbox.empty())
{
cout << "Error: bbox vector is empty" << endl;
return;
}
if (bbox.rows < 4)
{
cout << "Error: bbox vector does not contain enough points" << endl;
return;
}
for (int i = 0; i < bbox.rows - 1; i++)
{
line(im, Point2i(bbox.at<float>(i, 0), bbox.at<float>(i, 1)), Point2i(bbox.at<float>(i + 1, 0), bbox.at<float>(i + 1, 1)), Scalar(255, 0, 0), 3);
}
line(im, Point2i(bbox.at<float>(bbox.rows - 1, 0), bbox.at<float>(bbox.rows - 1, 1)), Point2i(bbox.at<float>(0, 0), bbox.at<float>(0, 1)), Scalar(255, 0, 0), 3);
imshow("Ergebnis", im);
}
/*
void display(Mat& im, Mat& bbox) {
int n = bbox.rows;
for (int i = 0; i < n - 1; i++) {
line(im, Point2i(bbox.at<float>(i, 0), bbox.at<float>(i, 1)), Point2i(bbox.at<float>(i + 1, 0), bbox.at<float>(i + 1, 1)), Scalar(255, 0, 0), 3);
}
line(im, Point2i(bbox.at<float>(n - 1, 0), bbox.at<float>(n - 1, 1)), Point2i(bbox.at<float>(0, 0), bbox.at<float>(0, 1)), Scalar(255, 0, 0), 3);
imshow("Ergebnis", im);
}
void display(Mat& im, Mat& bbox)
{
int n = bbox.rows;
for (int i = 0; i < n; i++)
{
line(im, Point2i(bbox.at<float>(i, 0), bbox.at<float>(i, 1)), Point2i(bbox.at<float>((i + 1) % n, 0), bbox.at<float>((i + 1) % n, 1)), Scalar(255, 0, 0), 3);
}
imshow("Ergebnis", im);
}*/
int main(int argc, char** argv)
{
Mat inputImage;
VideoCapture cap;
cap.set(CAP_PROP_FRAME_WIDTH, 720);
cap.set(CAP_PROP_FRAME_HEIGHT, 480);
cap.set(CAP_PROP_FPS, 30);
// Öffne eine Datei, um die erkannten QR-Codes zu speichern
ofstream MyFile("QR_data.txt");
MyFile << "Erkannte QR-Code-Daten\n";
MyFile << "===============\n";
int count = 0;
int imageNo = 0;
// Wenn das Videocapture nicht geöffnet wurde, lies von einer Datei
if (!cap.open(0))
inputImage = imread("qr.png");
while (true)
{
Mat frame;
cap >> frame;
// Wenn der Frame leer ist, beende die Schleife
if (frame.empty()) break;
// Konvertiere den Frame zu Graustufen
Mat gray;
cvtColor(frame, gray, COLOR_YUV2BGR);
cvtColor(frame, gray, COLOR_BGR2GRAY);
// Zeige das Live-Video an
imshow("Live", gray);
inputImage = gray;
// Wenn der Benutzer 'ESC' drückt, beende die Schleife
if (waitKey(10) == 27) break;
// Erstelle ein QRCodeDetector-Objekt
QRCodeDetector qrDecoder = QRCodeDetector::QRCodeDetector();
Mat bbox, rectifiedImage;
// Wenn das Eingabebild leer ist, gehe zur nächsten Iteration
if (inputImage.empty()) continue;
// Versuche, den QR-Code zu erkennen und zu decodieren
std::string data = qrDecoder.detectAndDecodeCurved(inputImage, bbox, rectifiedImage);
// Ausgabe der Größe von "bbox" vor dem Aufruf der Funktion
cout << "bbox rows before detectAndDecodeCurved: " << bbox.rows << endl;
// Wenn der QR-Code erfolgreich erkannt und decodiert wurde, gebe die Daten aus
if (data.length() > 0)
{
// Ausgabe der Größe von "bbox" nach dem Aufruf der Funktion
cout << "bbox rows after detectAndDecodeCurved: " << bbox.rows << endl;
count++;
imageNo++;
cout << "\n Erkannte Daten 1: " << data << endl;
cout << bbox << "\n";
display(inputImage, bbox);
rectifiedImage.convertTo(rectifiedImage, CV_8UC3);
imshow("Rectified QRCode 1 : ", rectifiedImage);
// Wenn die QR-Code-Rahmenbox vorhanden ist, fülle sie
if (bbox.cols > 0)
{
// Erstelle einen Vektor von Punkten
vector<cv::Point> point;
point.push_back(Point((unsigned)bbox.at<float>(0, 0), (unsigned)bbox.at<float>(0, 1)));
point.push_back(Point((unsigned)bbox.at<float>(0, 2), (unsigned)bbox.at<float>(0, 3)));
point.push_back(Point((unsigned)bbox.at<float>(0, 4), (unsigned)bbox.at<float>(0, 5)));
point.push_back(Point((unsigned)bbox.at<float>(0, 6), (unsigned)bbox.at<float>(0, 7)));
// Fülle die QR-Code-Rahmenbox
cv::fillConvexPoly(inputImage,
point,
Scalar(255, 0, 0),
0);
}
// Erstelle ein weiteres QRCodeDetector-Objekt
QRCodeDetector qrDecoder2 = QRCodeDetector::QRCodeDetector();
Mat bbox2, rectifiedImage2;
// Versuche, den QR-Code zu erkennen und zu decodieren
std::string data2 = qrDecoder2.detectAndDecodeCurved(inputImage, bbox2, rectifiedImage2);
// Wenn der QR-Code erfolgreich erkannt und decodiert wurde, gebe die Daten aus
if (data2.length() > 0)
{
count++;
cout << "\n Erkannte Daten 2: " << data2 << endl;
cout << bbox2; "\n";
display(inputImage, bbox2);
rectifiedImage2.convertTo(rectifiedImage2, CV_8UC3);
imshow("Rectified QRCode 2: ", rectifiedImage2);
}
// Schreibe die erkannten Daten in die Datei
MyFile << "Bild Nummer :" << imageNo << "\n";
MyFile << "-------------" << "\n";
MyFile << "QR code 1; \n";
MyFile << " Daten : " << data << "\n\n";
MyFile << " Position : [ ";
for (int i = 0; i < bbox.cols; i++) {
MyFile << "(" << bbox.at<float>(0, i * 2) << " , " << bbox.at<float>(0, i * 2 + 1) << ")";
if (i < bbox.cols - 1)
MyFile << " , ";
}
MyFile << " ] \n\n";
// Schreibe die erkannten Daten in die Datei
if (count > 1) {
MyFile << "QR code 2; \n";
MyFile << " Daten : " << data2 << "\n";
MyFile << " Position : [ ";
for (int i = 0; i < bbox2.cols; i++) {
MyFile << "(" << bbox2.at<float>(0, i * 2) << " , " << bbox2.at<float>(0, i * 2 + 1) << ")";
if (i < bbox2.cols - 1)
MyFile << " , ";
}
MyFile << " ] \n\n";
}
MyFile << "\n";
}
else
cout << "QR-Code nicht erkannt" << endl;
Mat empty = inputImage;
}
count = 0;
// Warte 10 Millisekunden, bevor die nächste Iteration fortgesetzt wird
waitKey(10);
// Schließe die Datei, in der die erkannten QR-Codes gespeichert sind
MyFile.close();
return 0;
}