Skip to content

Commit

Permalink
Added barcodes decoding and button to save image
Browse files Browse the repository at this point in the history
  • Loading branch information
xavierdechamps committed May 10, 2020
1 parent b4a5846 commit 0b65c32
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 8 deletions.
Binary file added Images/QR_code.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed Images/panorama_stylization3.png
Binary file not shown.
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The implemented image manipulations are:
* Denoizing (Non-Local Means)
* Non-Photorealistic Rendering (Edge preserving, Detail enhancing, Pencil sketch, Stylization)
* White balancing (from module xphoto)
- Barcode and QR code decoder (through the external library [ZBar](https://github.com/ZBar/ZBar))

# Requirements
This code requires an installed version of OpenCV. The program is linked against the following libraries of OpenCV:
Expand All @@ -39,12 +40,13 @@ This code requires an installed version of OpenCV. The program is linked against
* libopencv_video
* libopencv_photo

The code may also be compiled against two optional libraries:
* libopencv_objdetect
* libopencv_stitching
* libopencv_xphoto
The code can also be compiled against four optional libraries:
* libopencv_objdetect (enables face detection)
* libopencv_stitching (enables the panorama creation)
* libopencv_xphoto (enables features from xphoto)
* libzbar (enables decryption of barcodes and QR codes)

The first one enables face detection and the second one creates a panorama from a series of picked up frames. If you don't have these libraries inside your OpenCV installation directory, just comment the top lines in the file [Video.pro](SRC/Video.pro). If you have the objdetect library, a face-detetection cascade from OpenCV is also required. In this program the face-detection cascade file is hard-coded as opencv-4.1.0/data/haarcascades/haarcascade_frontalface_default.xml in the file [mainwindow.cpp](SRC/mainwindow.cpp). This path must be adapted according to your installation.
If you don't have these libraries inside your OpenCV installation directory, just comment the top lines in the file [Video.pro](SRC/Video.pro). If you have the objdetect library, a face-detetection cascade from OpenCV is also required. In this program the face-detection cascade file is hard-coded as opencv-4.3.0/data/haarcascades/haarcascade_frontalface_default.xml in the file [mainwindow.cpp](SRC/mainwindow.cpp). This path must be adapted according to your installation. The ZBar library must also be compiled in order to be able to decode the barcodes / QR codes. For this library to function, it is not mandatory to compile ZBar with gtk, python or qt4 options enabled (only the headers and the library are required, not the executable).

Your C++ compiler must accept c++11 directives.

Expand All @@ -63,4 +65,7 @@ Not tested. Should be similar to what is done for MacOS
Not tested. No idea.

## Stitching operation done on my laptop with application of the Stylization filter from the module Photo / Non-Photorealistic Rendering
![Stitching operation done on my laptop with application of the Stylization filter from the module Photo / Non-Photorealistic Rendering](https://github.com/xavierdechamps/Live_camera_Opencv/blob/master/Images/panorama_stylization3.jpg)
![Stitching operation done on my laptop with application of the Stylization filter from the module Photo / Non-Photorealistic Rendering](https://github.com/xavierdechamps/Live_camera_Opencv/blob/master/Images/panorama_stylization3.jpg)

## Decoding of a barcode with the library ZBar
![Decoding of a barcode with the library ZBar](https://github.com/xavierdechamps/Live_camera_Opencv/blob/master/Images/QR_code.jpg)
11 changes: 10 additions & 1 deletion SRC/Video.pro
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
# Path to global OpenCV installation directory
MY_OPENCV_DIR = /Users/dechamps/Documents/Codes/Cpp/Images/Libraries/opencv-4.1.2/install
MY_OPENCV_DIR = /Users/dechamps/Documents/Codes/Cpp/Images/Libraries/opencv-4.3.0/install
# If you don't have the OpenCV stiching library, comment the following line
CONFIG += stitching
# If you don't have the OpenCV object detect library, comment the following line
CONFIG += objdetect
# If you don't have the OpenCV xphoto library, comment the following line
CONFIG += xphoto
# If you don't have the ZBar library, comment the following line
CONFIG += zbar
MY_ZBAR_DIR = /Users/dechamps/Documents/Codes/Cpp/Images/Libraries/zbar-0.10/install
#
############# DO NOT MODIFY BELOW THIS LINE #############
#
stitching: DEFINES+=withstitching
objdetect: DEFINES+=withobjdetect
xphoto: DEFINES+=withxphoto
zbar: DEFINES+=withzbar

QT = core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
Expand Down Expand Up @@ -51,9 +55,13 @@ QMAKE_CXXFLAGS += -std=c++11

# Path to OpenCV include directory
INCLUDEPATH += $${MY_OPENCV_DIR}/include/opencv4
# Include the header from ZBar
zbar: INCLUDEPATH += $${MY_ZBAR_DIR}/include

# Linker flags
QMAKE_LFLAGS += -Wl,-rpath,$${MY_OPENCV_DIR}/lib
# Include libraries from ZBar
zbar: QMAKE_LFLAGS += -Wl,-rpath,$${MY_ZBAR_DIR}/lib

# Required OpenCV libraries
LIBS = -L$${MY_OPENCV_DIR}/lib
Expand All @@ -67,3 +75,4 @@ LIBS += -lopencv_imgcodecs \
stitching: LIBS += -lopencv_stitching
objdetect: LIBS += -lopencv_objdetect
xphoto: LIBS += -lopencv_xphoto
zbar: LIBS += -L$${MY_ZBAR_DIR}/lib -lzbar
47 changes: 46 additions & 1 deletion SRC/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,18 @@ void MainWindow::createActions() {
this->actionRecord->setToolTip(tr("Record the video"));
this->actionRecord->setCheckable(true);
connect(this->actionRecord, SIGNAL(triggered(bool)), this, SLOT(treat_Button_Record(bool)));

this->actionSaveImage = new QAction(tr("&Save"), this );
this->actionSaveImage->setToolTip(tr("Save the current image"));
// this->actionSaveImage->setCheckable(true);
connect(this->actionSaveImage, SIGNAL(triggered(bool)), this, SLOT(treat_Button_Save(bool)) );

#ifdef withzbar
this->actionQRcode = new QAction(tr("&QR code"), this);
this->actionQRcode->setToolTip(tr("Detect QR codes in the video"));
this->actionQRcode->setCheckable(true);
connect(this->actionQRcode, SIGNAL(triggered(bool)) , this, SLOT(treat_Button_QRcode(bool)) );
#endif
}

void MainWindow::createToolBars() {
Expand Down Expand Up @@ -292,6 +304,11 @@ void MainWindow::createToolBars() {
this->editToolBar->addAction(this->actionPhoto);
this->editToolBar->addSeparator();
this->editToolBar->addAction(this->actionRecord);
this->editToolBar->addAction(this->actionSaveImage);
#ifdef withzbar
this->editToolBar->addAction(this->actionQRcode);
#endif

addToolBar(Qt::RightToolBarArea, this->editToolBar);
}

Expand Down Expand Up @@ -432,7 +449,7 @@ void MainWindow::treat_Button_Record(bool state) {
this->video_out_name = QfileNameLocal.toStdString();

this->video_out.open(this->video_out_name,VideoWriter::fourcc('X','V','I','D'),
10.,
4.,
cv::Size(this->capture.get(cv::CAP_PROP_FRAME_WIDTH),
this->capture.get(cv::CAP_PROP_FRAME_HEIGHT)),
true);
Expand All @@ -446,6 +463,34 @@ void MainWindow::treat_Button_Record(bool state) {
}
}

void MainWindow::treat_Button_Save(bool state) {
QString QfileNameLocal = QFileDialog::getSaveFileName(this,
tr("File name to save the image"),
QString::fromStdString(this->main_directory),
tr("Images (*.png *.jpg)") );
if (QfileNameLocal.isEmpty()) // If one clicked the cancel button, the string is empty
return;

this->file_name_save = QfileNameLocal.toStdString();

vector<int> compression_params;
compression_params.push_back(IMWRITE_JPEG_QUALITY);
compression_params.push_back(100);
compression_params.push_back(IMWRITE_PNG_COMPRESSION);
compression_params.push_back(4);

Mat imageMat = myFrame->get_image_content();
Mat imageOutput;
cvtColor(imageMat, imageOutput, COLOR_BGR2RGB);
imwrite(this->file_name_save , imageOutput , compression_params );
}

#ifdef withzbar
void MainWindow::treat_Button_QRcode(bool state) {
this->myFrame->toggleQRcode();
}
#endif

void MainWindow::treat_Slider_Blur_Range(int value) {
this->myFrame->set_size_blur(value);
}
Expand Down
8 changes: 8 additions & 0 deletions SRC/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ class MainWindow: public QMainWindow
QAction *actionMotionDetection;
QAction *actionPhoto;
QAction *actionRecord;
QAction *actionSaveImage;
#ifdef withzbar
QAction *actionQRcode;
#endif@
QToolBar *editToolBar;

bool histogram_window_opened;
Expand Down Expand Up @@ -123,6 +127,10 @@ private slots:
void treat_Button_Motion_Detection(bool);
void treat_Button_Photo(bool);
void treat_Button_Record(bool);
void treat_Button_Save(bool);
#ifdef withzbar
void treat_Button_QRcode(bool);
#endif

void treat_Slider_Blur_Range(int);
void treat_Blur_Method(int);
Expand Down
84 changes: 84 additions & 0 deletions SRC/myimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ MyImage::MyImage()
#ifdef withstitching
this->panorama_activated = false;
#endif

#ifdef withzbar
this->qrcodeactivated = false;
#endif

this->motion_detected = false;
this->motion_detection_method = 1;
Expand Down Expand Up @@ -123,6 +127,12 @@ void MyImage::togglePhoto() {
this->photoed = ! (this->photoed);
}

#ifdef withzbar
void MyImage::toggleQRcode(){
this->qrcodeactivated = ! (this->qrcodeactivated);
}
#endif

// Set of functions called by external world to set parameters for the image treatments
void MyImage::set_image_content(Mat &content) {
// Receives a new image from the outside world and applies the image treatments
Expand Down Expand Up @@ -170,6 +180,11 @@ void MyImage::set_image_content(Mat &content) {

if (this->transformed)
transformImage();

#ifdef withzbar
if (this->qrcodeactivated)
getQRcode();
#endif
}

void MyImage::set_size_blur(int value) {
Expand Down Expand Up @@ -827,3 +842,72 @@ int MyImage::panorama_get_size(){
return this->Panorama_vector.size();
}
#endif

#ifdef withzbar
void MyImage::getQRcode(){
// Create zbar scanner
zbar::ImageScanner scanner;
// Configure scanner
scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1);

// Convert image to grayscale
Mat imGray;
cv::cvtColor(this->image, imGray,cv::COLOR_BGR2GRAY);

// Wrap image data in a zbar image
zbar::Image image(this->image.cols, this->image.rows, "Y800", (uchar *)imGray.data, this->image.cols * this->image.rows);

// Scan the image for barcodes and QRCodes
int nscan = scanner.scan(image);

int current_code = 0;
for(zbar::Image::SymbolIterator symbol = image.symbol_begin(); symbol != image.symbol_end(); ++symbol) {
// Print type and data
cout << "Type : " << symbol->get_type_name() << endl;
cout << "Data : " << symbol->get_data() << endl << endl;

// Obtain location
vector <Point> location;
for(int i = 0; i< symbol->get_location_size(); i++) {
location.push_back(Point(symbol->get_location_x(i),symbol->get_location_y(i)));
}

vector<Point> hull;
// If the points do not form a quad, find convex hull
if(location.size() > 4)
cv::convexHull(location, hull);
else
hull = location;

// Plot the convex hull
int n = hull.size();
for(int j = 0; j < n; j++) {
cv::line(this->image, hull[j], hull[ (j+1) % n], Scalar(255,0,0), 3);
}

// Print the text
cv::putText(this->image, //target image
symbol->get_type_name(), //text
cv::Point(10, current_code * 50 + 40 ), //top-left position
cv::FONT_HERSHEY_DUPLEX,
1.0,
CV_RGB(118, 185, 0), //font color
2);

current_code++;
cv::putText(this->image, //target image
symbol->get_data(), //text
cv::Point(10, current_code * 50 + 40 ), //top-left position
cv::FONT_HERSHEY_DUPLEX,
1.0,
CV_RGB(118, 185, 0), //font color
2);

current_code++;

}


}

#endif
14 changes: 14 additions & 0 deletions SRC/myimage.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
#include "opencv2/video/tracking.hpp"
#include "opencv2/video.hpp"

#ifdef withzbar
#include "zbar.h"
#endif

#include <iostream>

using namespace cv;
Expand Down Expand Up @@ -99,6 +103,9 @@ class MyImage
#endif
void toggleMotionDetection();
void togglePhoto();
#ifdef withzbar
void toggleQRcode();
#endif

private:
Mat image, previmage , mask , smoothed, histogram, objects, panorama, motion, background ;
Expand Down Expand Up @@ -126,9 +133,13 @@ class MyImage
vector<Mat> Panorama_vector;
Ptr<Stitcher> Panorama_stitcher;
#endif
#ifdef withzbar
bool qrcodeactivated;
#endif

Ptr<BackgroundSubtractor> pMOG2;

// Methods
void toBlackandWhite();
void inverseImage();
void smoothImage(Mat &imag, int blur_range, int method);
Expand All @@ -140,6 +151,9 @@ class MyImage
void transformImage();
void equalizeHistogram();
void modulephoto();
#ifdef withzbar
void getQRcode();
#endif
};

#endif // MYIMAGE_H

0 comments on commit 0b65c32

Please sign in to comment.