概要
ZBarは、さまざまなプラットフォームでバーコードを読み取るためのオープンソースのライブラリです。UnitV2のサンプルのcode_detectorでZ-Barライブラリが使われています。
ZBarでQRコード読み取りを行ってみましょう。
環境構築
構築手順に入る前に、まずPCに以下のバージョンのUbuntuをインストールした環境で、構築しました。
Ubuntu 22.04.3 LTS(x64)
OpenCV ver 0.4.4
ncnn ver 23102
zbar ver 0.10
作業フォルダの作成
作業フォルダを作成します。
% mkdir z_bar_opencv
% cd z_bar_opencv
プログラムの作成
ZBarとOpenCVでQRコードを読み取るプログラムを作成します。
% gedit main.cpp
main.cpp
#include <iomanip>
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <zbar.h>
using namespace std;
using namespace cv;
using namespace zbar;
int main(int argc, char **argv) {
int cam_idx = 0;
if(argc == 2) {
cam_idx = atoi(argv[1]);
}
VideoCapture cap(cam_idx);
if(!cap.isOpened()) {
cerr << "Could not open camera." << endl;
exit(EXIT_FAILURE);
}
if(!cap.set(cv::CAP_PROP_FRAME_WIDTH, 640))
cout << "camera set width error" << endl;
if(!cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480))
cout << "camera set height error" << endl;
// zbar scannerを生成
ImageScanner scanner;
// zbarのconfig設定
scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
while(cap.isOpened()) {
// 撮像してグレースケール変換
cv::Mat frame, frame_gray;
cap >> frame;
cvtColor(frame, frame_gray, cv::COLOR_BGR2GRAY);
// 画像をcv:matからImageクラスへ変換
Image image(frame_gray.cols, frame_gray.rows, "Y800", (uchar *)(frame_gray.data), frame_gray.cols * frame_gray.rows);
// 画像をzbarへ入力
scanner.scan(image);
int counter = 0;
for(Image::SymbolIterator symbol = image.symbol_begin(); symbol != image.symbol_end(); ++symbol) {
// 読み取り結果をコンソールに表示
cout << counter << " decoded " << symbol->get_type_name() << " symbol \"" << symbol->get_data() << '"' << endl;
cout << "Location: (" << symbol->get_location_x(0) << "," << symbol->get_location_y(0) << ")" << endl;
cout << "Size: " << symbol->get_location_size() << endl;
// QRコードの位置を描画する
if(symbol->get_location_size() == 4) {
// rectangle(frame, Rect(symbol->get_location_x(i), symbol->get_location_y(i), 10, 10), Scalar(255, 128, 0));
line(frame, Point(symbol->get_location_x(0), symbol->get_location_y(0)), Point(symbol->get_location_x(1), symbol->get_location_y(1)), Scalar(255, 128, 0), 2, 8, 0);
line(frame, Point(symbol->get_location_x(1), symbol->get_location_y(1)), Point(symbol->get_location_x(2), symbol->get_location_y(2)), Scalar(255, 128, 0), 2, 8, 0);
line(frame, Point(symbol->get_location_x(2), symbol->get_location_y(2)), Point(symbol->get_location_x(3), symbol->get_location_y(3)), Scalar(255, 128, 0), 2, 8, 0);
line(frame, Point(symbol->get_location_x(3), symbol->get_location_y(3)), Point(symbol->get_location_x(0), symbol->get_location_y(0)), Scalar(255, 128, 0), 2, 8, 0);
}
counter++;
}
image.set_data(NULL, 0);
#ifdef __x86_64__
imshow("Results", frame);
waitKey(30);
#endif
}
return 0;
}
CMakeLists.txt ファイルの作成
cmakeでコンパイルするために、CMakeLists.txtを編集します。
gedit CMakeLists.txt
CMakeLists.txt
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
PROJECT(example)
cmake_minimum_required(VERSION 3.5)
if(TARGET_COMPILER STREQUAL "arm")
message(STATUS "TARGET_COMPILE STREQUAL arm")
SET(CMAKE_CXX_COMPILER arm-none-linux-gnueabihf-g++)
SET(CMAKE_C_COMPILER arm-none-linux-gnueabihf-gcc)
SET(NCNN_INSTALL_DIR /opt/external/ncnn/install/arm/)
SET(ZBAR_INSTALL_DIR /opt/external/zbar-0.10/build/arm)
SET(OpenCV_DIR /opt/external/opencv/build/arm)
else()
message(STATUS "TARGET_COMPILE STREQUAL X64")
SET(NCNN_INSTALL_DIR /opt/external/ncnn/install/x64/)
SET(ZBAR_INSTALL_DIR /opt/external/zbar-0.10/build/x64/)
SET(OpenCV_DIR /opt/external/opencv/build/x64)
endif()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
set(Target z_bar_opencv)
find_package(OpenCV REQUIRED)
add_executable(${Target} main.cpp)
link_directories(${OpenCV_LIBRARY_DIRS})
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${OpenCV_INCLUDE_DIRS} )
include_directories(${NCNN_INSTALL_DIR}/include/ncnn)
include_directories(${ZBAR_INSTALL_DIR}/include/)
target_link_libraries(${Target} ${OpenCV_LIBRARIES})
target_link_libraries (${Target} ${NCNN_INSTALL_DIR}/lib/libncnn.a -fopenmp)
target_link_libraries (${Target} ${ZBAR_INSTALL_DIR}/lib/libzbar.so)
ビルド
Ubuntu用のバイナリをcmakeでコンパイルして、生成されたバイナリを実行します。
% cmake .
% make
% ./bin/z_bar_opencv
UnitV2(arm環境)で動くバイナリをビルドする場合は、Ubuntu用のバイナリで作成されたキャッシュを削除した上で、以下のコマンドでビルドします。
% rm CMakeCache.txt
% cmake -B build/arm -DTARGET_COMPILE=arm .
% cmake --build build/arm
作成したプログラム
作成したプログラムは以下のGitHubへ格納しています。
参考資料
この記事を作成するにあたり、以下のウェブサイトを参考にしました。