├── Bullseye_32
├── CMakeLists.txt
├── QR.cbp
└── main.cpp
├── Bullseye_64
├── CMakeLists.txt
├── QR.cbp
└── main.cpp
├── Bullseye_64_LCCV
├── CMakeLists.txt
├── QR.cbp
├── QR.layout
├── include
│ ├── lccv.hpp
│ ├── libcamera_app.hpp
│ └── libcamera_app_options.hpp
└── src
│ ├── lccv.cpp
│ ├── libcamera_app.cpp
│ ├── libcamera_app_options.cpp
│ └── main.cpp
├── Buster_32
├── CMakeLists.txt
├── QRpi.cbp
└── main.cpp
├── Buster_64
├── CMakeLists.txt
├── QRpi.cbp
└── main.cpp
├── LICENSE
└── README.md
/Bullseye_32/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
2 |
3 | project(QRpi)
4 |
5 | macro(use_cxx11)
6 | if (CMAKE_VERSION VERSION_LESS "3.1")
7 | if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
8 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
9 | endif ()
10 | else ()
11 | set (CMAKE_CXX_STANDARD 17)
12 | endif ()
13 | endmacro(use_cxx11)
14 |
15 | find_package(OpenCV REQUIRED)
16 |
17 | set(SOURCES ./main.cpp)
18 |
19 | set(EXTRA_LIBS ${OpenCV_LIBS} libgobject-2.0.so libgstreamer-1.0.so libgstapp-1.0.so /usr/local/lib/libzbar.so)
20 |
21 | set(EXECUTABLE_OUTPUT_PATH "./")
22 |
23 | link_directories(/usr/lib/arm-linux-gnueabihf/ /usr/local/lib/)
24 |
25 | include_directories(${OpenCV_INCLUDE_DIRS})
26 |
27 | add_link_options(-fopenmp -s -ldl -lpthread)
28 |
29 | add_executable(QRpi ${SOURCES})
30 |
31 | target_link_libraries(QRpi ${EXTRA_LIBS})
--------------------------------------------------------------------------------
/Bullseye_32/QR.cbp:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/Bullseye_32/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | using namespace std;
9 |
10 | // Create zbar scanner
11 | zbar::ImageScanner scanner;
12 |
13 | struct decodedObject
14 | {
15 | string type;
16 | string data;
17 | vector location;
18 | };
19 |
20 | // Display barcode and QR code location
21 | void display(cv::Mat &im, vector&decodedObjects)
22 | {
23 | // Loop over all decoded objects
24 | for(size_t i = 0; i points = decodedObjects[i].location;
26 | vector hull;
27 |
28 | // If the points do not form a quad, find convex hull
29 | if(points.size() > 4) cv::convexHull(points, hull);
30 | else hull = points;
31 |
32 | // Number of points in the convex hull
33 | size_t n = hull.size();
34 |
35 | for(size_t j=0; j&decodedObjects, int nb_frames)
42 | {
43 | // Convert image to grayscale
44 | cv::Mat imGray;
45 |
46 | cv::cvtColor(im, imGray, cv::COLOR_BGR2GRAY);
47 |
48 | // Wrap image data in a zbar image
49 | zbar::Image image(im.cols, im.rows, "Y800", (uchar*)imGray.data, im.cols*im.rows);
50 |
51 | // Scan the image for barcodes and QRCodes
52 | int res = scanner.scan(image);
53 |
54 | if (res > 0) {
55 | // Print results
56 | for(zbar::Image::SymbolIterator symbol = image.symbol_begin(); symbol != image.symbol_end(); ++symbol){
57 | decodedObject obj;
58 |
59 | obj.type = symbol->get_type_name();
60 | obj.data = symbol->get_data();
61 | // Obtain location
62 |
63 | for(int i = 0; i< symbol->get_location_size(); i++){
64 | obj.location.push_back(cv::Point(symbol->get_location_x(i),symbol->get_location_y(i)));
65 | }
66 | decodedObjects.push_back(obj);
67 |
68 | // debug - print type and data
69 | cout << nb_frames << endl;
70 | cout << "Type : " << obj.type << endl;
71 | cout << "Data : " << obj.data << endl << endl;
72 |
73 | }
74 | display(im, decodedObjects);
75 | }
76 | }
77 | /// For the Raspberry Pi 64-bit Bullseye OS
78 |
79 | std::string gstreamer_pipeline(int capture_width, int capture_height, int framerate, int display_width, int display_height) {
80 | return
81 | " libcamerasrc ! video/x-raw, "
82 | " width=(int)" + std::to_string(capture_width) + ","
83 | " height=(int)" + std::to_string(capture_height) + ","
84 | " framerate=(fraction)" + std::to_string(framerate) +"/1 !"
85 | " videoconvert ! videoscale !"
86 | " video/x-raw,"
87 | " width=(int)" + std::to_string(display_width) + ","
88 | " height=(int)" + std::to_string(display_height) + " ! appsink";
89 | }
90 |
91 | int main()
92 | {
93 | int ch=0;
94 | int nb_frames=0;
95 | cv::Mat image;
96 | float f;
97 | float FPS[16];
98 | int i, Fcnt=0;
99 | chrono::steady_clock::time_point Tbegin, Tend;
100 |
101 | for(i=0;i<16;i++) FPS[i]=0.0;
102 |
103 | //pipeline parameters
104 | //keep this resolution!!!
105 | //it will be cropped to 720x720
106 | int capture_width = 1024;
107 | int capture_height = 768;
108 | int framerate = 15 ;
109 | int display_width = 1024;
110 | int display_height = 768;
111 |
112 | //reset frame average
113 | std::string pipeline = gstreamer_pipeline(capture_width, capture_height, framerate,
114 | display_width, display_height);
115 | std::cout << "Using pipeline: \n\t" << pipeline << "\n\n\n";
116 |
117 | cv::VideoCapture cap(pipeline, cv::CAP_GSTREAMER);
118 | if(!cap.isOpened()) {
119 | std::cout<<"Failed to open camera."< decodedObjects;
141 | decode(image, decodedObjects, nb_frames++);
142 |
143 | //calculate frame rate (just for your convenience)
144 | Tend = chrono::steady_clock::now();
145 | f = chrono::duration_cast (Tend - Tbegin).count();
146 | Tbegin = Tend;
147 | if(f>0.0) FPS[((Fcnt++)&0x0F)]=1000.0/f;
148 | for(f=0.0, i=0;i<16;i++){ f+=FPS[i]; }
149 | putText(image, cv::format("FPS %0.2f", f/16),cv::Point(10,20),cv::FONT_HERSHEY_SIMPLEX,0.6, cv::Scalar(0, 0, 255));
150 |
151 | //show result
152 | cv::imshow("Video",image);
153 | ch=cv::waitKey(10);
154 | }
155 | cap.release();
156 | cv::destroyWindow("Video");
157 | return 0;
158 | }
159 |
--------------------------------------------------------------------------------
/Bullseye_64/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
2 |
3 | project(QRpi)
4 |
5 | macro(use_cxx11)
6 | if (CMAKE_VERSION VERSION_LESS "3.1")
7 | if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
8 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
9 | endif ()
10 | else ()
11 | set (CMAKE_CXX_STANDARD 17)
12 | endif ()
13 | endmacro(use_cxx11)
14 |
15 | find_package(OpenCV REQUIRED)
16 |
17 | set(SOURCES ./main.cpp)
18 |
19 | set(EXTRA_LIBS ${OpenCV_LIBS} libgobject-2.0.so libgstreamer-1.0.so libgstapp-1.0.so /usr/local/lib/libzbar.so)
20 |
21 | set(EXECUTABLE_OUTPUT_PATH "./")
22 |
23 | link_directories(/usr/lib/aarch64-linux-gnu/ /usr/local/lib/)
24 |
25 | include_directories(${OpenCV_INCLUDE_DIRS})
26 |
27 | add_link_options(-fopenmp -s -ldl -lpthread)
28 |
29 | add_executable(QRpi ${SOURCES})
30 |
31 | target_link_libraries(QRpi ${EXTRA_LIBS})
--------------------------------------------------------------------------------
/Bullseye_64/QR.cbp:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/Bullseye_64/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | using namespace std;
9 |
10 | // Create zbar scanner
11 | zbar::ImageScanner scanner;
12 |
13 | struct decodedObject
14 | {
15 | string type;
16 | string data;
17 | vector location;
18 | };
19 |
20 | // Display barcode and QR code location
21 | void display(cv::Mat &im, vector&decodedObjects)
22 | {
23 | // Loop over all decoded objects
24 | for(size_t i = 0; i points = decodedObjects[i].location;
26 | vector hull;
27 |
28 | // If the points do not form a quad, find convex hull
29 | if(points.size() > 4) cv::convexHull(points, hull);
30 | else hull = points;
31 |
32 | // Number of points in the convex hull
33 | size_t n = hull.size();
34 |
35 | for(size_t j=0; j&decodedObjects, int nb_frames)
42 | {
43 | // Convert image to grayscale
44 | cv::Mat imGray;
45 |
46 | cv::cvtColor(im, imGray, cv::COLOR_BGR2GRAY);
47 |
48 | // Wrap image data in a zbar image
49 | zbar::Image image(im.cols, im.rows, "Y800", (uchar*)imGray.data, im.cols*im.rows);
50 |
51 | // Scan the image for barcodes and QRCodes
52 | int res = scanner.scan(image);
53 |
54 | if (res > 0) {
55 | // Print results
56 | for(zbar::Image::SymbolIterator symbol = image.symbol_begin(); symbol != image.symbol_end(); ++symbol){
57 | decodedObject obj;
58 |
59 | obj.type = symbol->get_type_name();
60 | obj.data = symbol->get_data();
61 | // Obtain location
62 |
63 | for(int i = 0; i< symbol->get_location_size(); i++){
64 | obj.location.push_back(cv::Point(symbol->get_location_x(i),symbol->get_location_y(i)));
65 | }
66 | decodedObjects.push_back(obj);
67 |
68 | // debug - print type and data
69 | cout << nb_frames << endl;
70 | cout << "Type : " << obj.type << endl;
71 | cout << "Data : " << obj.data << endl << endl;
72 |
73 | }
74 | display(im, decodedObjects);
75 | }
76 | }
77 | /// For the Raspberry Pi 64-bit Bullseye OS
78 |
79 | std::string gstreamer_pipeline(int capture_width, int capture_height, int framerate, int display_width, int display_height) {
80 | return
81 | " libcamerasrc ! video/x-raw, "
82 | " width=(int)" + std::to_string(capture_width) + ","
83 | " height=(int)" + std::to_string(capture_height) + ","
84 | " framerate=(fraction)" + std::to_string(framerate) +"/1 !"
85 | " videoconvert ! videoscale !"
86 | " video/x-raw,"
87 | " width=(int)" + std::to_string(display_width) + ","
88 | " height=(int)" + std::to_string(display_height) + " ! appsink";
89 | }
90 |
91 | int main()
92 | {
93 | int ch=0;
94 | int nb_frames=0;
95 | cv::Mat image;
96 | float f;
97 | float FPS[16];
98 | int i, Fcnt=0;
99 | chrono::steady_clock::time_point Tbegin, Tend;
100 |
101 | for(i=0;i<16;i++) FPS[i]=0.0;
102 |
103 | //pipeline parameters
104 | //keep this resolution!!!
105 | //it will be cropped to 720x720
106 | int capture_width = 1024;
107 | int capture_height = 768;
108 | int framerate = 15 ;
109 | int display_width = 1024;
110 | int display_height = 768;
111 |
112 | //reset frame average
113 | std::string pipeline = gstreamer_pipeline(capture_width, capture_height, framerate,
114 | display_width, display_height);
115 | std::cout << "Using pipeline: \n\t" << pipeline << "\n\n\n";
116 |
117 | cv::VideoCapture cap(pipeline, cv::CAP_GSTREAMER);
118 | if(!cap.isOpened()) {
119 | std::cout<<"Failed to open camera."< decodedObjects;
141 | decode(image, decodedObjects, nb_frames++);
142 |
143 | //calculate frame rate (just for your convenience)
144 | Tend = chrono::steady_clock::now();
145 | f = chrono::duration_cast (Tend - Tbegin).count();
146 | Tbegin = Tend;
147 | if(f>0.0) FPS[((Fcnt++)&0x0F)]=1000.0/f;
148 | for(f=0.0, i=0;i<16;i++){ f+=FPS[i]; }
149 | putText(image, cv::format("FPS %0.2f", f/16),cv::Point(10,20),cv::FONT_HERSHEY_SIMPLEX,0.6, cv::Scalar(0, 0, 255));
150 |
151 | //show result
152 | cv::imshow("Video",image);
153 | ch=cv::waitKey(10);
154 | }
155 | cap.release();
156 | cv::destroyWindow("Video");
157 | return 0;
158 | }
159 |
--------------------------------------------------------------------------------
/Bullseye_64_LCCV/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
2 |
3 | project(QRpi)
4 |
5 | macro(use_cxx11)
6 | if (CMAKE_VERSION VERSION_LESS "3.1")
7 | if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
8 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
9 | endif ()
10 | else ()
11 | set (CMAKE_CXX_STANDARD 17)
12 | endif ()
13 | endmacro(use_cxx11)
14 |
15 | find_package(OpenCV REQUIRED)
16 |
17 | set(SOURCES src/main.cpp src/lccv.cpp src/libcamera_app.cpp src/libcamera_app_options.cpp)
18 |
19 | set(EXTRA_LIBS ${OpenCV_LIBS} libcamera-base.so libcamera.so /usr/local/lib/libzbar.so)
20 |
21 | set(EXECUTABLE_OUTPUT_PATH "./")
22 |
23 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wfatal-errors -Wextra -Wall -std=gnu++17 -fexceptions -ftree-vectorize -Wno-unused-parameter")
24 |
25 | link_directories(/usr/lib/aarch64-linux-gnu/ /usr/local/lib/)
26 |
27 | include_directories(include ${OpenCV_INCLUDE_DIRS} /usr/include/libcamera)
28 |
29 | add_link_options(-fopenmp -s -ldl -lpthread)
30 |
31 | add_executable(QRpi ${SOURCES})
32 |
33 | target_link_libraries(QRpi ${EXTRA_LIBS})
--------------------------------------------------------------------------------
/Bullseye_64_LCCV/QR.cbp:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/Bullseye_64_LCCV/QR.layout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Bullseye_64_LCCV/include/lccv.hpp:
--------------------------------------------------------------------------------
1 | #ifndef LCCV_HPP
2 | #define LCCV_HPP
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include "libcamera_app.hpp"
10 | #include "libcamera_app_options.hpp"
11 |
12 | namespace lccv {
13 |
14 | class PiCamera {
15 | public:
16 | PiCamera();
17 | ~PiCamera();
18 |
19 | Options *options;
20 |
21 | //Photo mode
22 | bool startPhoto();
23 | bool capturePhoto(cv::Mat &frame);
24 | bool stopPhoto();
25 |
26 | //Video mode
27 | bool startVideo();
28 | bool getVideoFrame(cv::Mat &frame, unsigned int timeout);
29 | void stopVideo();
30 |
31 | protected:
32 | void run();
33 | protected:
34 | LibcameraApp *app;
35 | void getImage(cv::Mat &frame, CompletedRequestPtr &payload);
36 | static void *videoThreadFunc(void *p);
37 | pthread_t videothread;
38 | unsigned int still_flags;
39 | unsigned int vw,vh,vstr;
40 | std::atomic running,frameready;
41 | uint8_t *framebuffer;
42 | std::mutex mtx;
43 | bool camerastarted;
44 | };
45 |
46 | }
47 | #endif
48 |
--------------------------------------------------------------------------------
/Bullseye_64_LCCV/include/libcamera_app.hpp:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: BSD-2-Clause */
2 | /*
3 | * Copyright (C) 2020-2021, Raspberry Pi (Trading) Ltd.
4 | *
5 | * libcamera_app.hpp - base class for libcamera apps.
6 | */
7 |
8 | #pragma once
9 |
10 | #include
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include