0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

M5UnitV2 & ncnnAdvent Calendar 2023

Day 7

ZBarを使ってQRコードを読み取る

Last updated at Posted at 2023-12-06

概要

ZBarは、さまざまなプラットフォームでバーコードを読み取るためのオープンソースのライブラリです。UnitV2のサンプルのcode_detectorでZ-Barライブラリが使われています。
ZBarでQRコード読み取りを行ってみましょう。

環境構築

構築手順に入る前に、まずPCに以下のバージョンのUbuntuをインストールした環境で、構築しました。

M5UnitV2のクロスコンパイル環境を構築する手順

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へ格納しています。

参考資料

この記事を作成するにあたり、以下のウェブサイトを参考にしました。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?