広告

UE5.2でOpencvを使ってQRコードの読み込み(その1)

ZxingをつかってQRコード読み込みがうまくいかなかったので代替案を探しているとどうやらUE5ではOpencvが使えるらしいので、OpenCVを使ってQRコードの読み込みを使ってみる。

UE5.2でOpenCVを有効にする

例のごとく新規プロジェクトから作っていきます。
OpenCVでのQRコード読み込みはC++で書くのでc++プロジェクトでプロジェクトを作成します。

プロジェクトが起動したら(起動しない場合はVisualStduioでF5を押して起動させてください)、
編集→プラグインから「OpenCV」で検索します。


この「OpenCV」を有効にします。
(OpenCV Lens Distortionはカメラのキャリブレーションなどに使用するもののようです。詳細は分からないので各自で調べてください)

QRコード読み込みクラスの作成

再起動をしたら、画像からQRコードの読み取りができるクラスを作成します。
今回はどこからでも呼べるようにライブラリとして作成してみます。
「ツール」→「新規c++クラス」から「BluePrint Function Library」を選んでc++クラスを作成します。
(今回はOpenCVLibraryと名前を付けました)

C++クラスを追加したらプロジェクトを終了します。
「プロジェクト名」.Build.cs(今回はOpenCvQRCode.Build.cs)のModuleに「”OpenCV”, “OpenCVHelper”」を追加します

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });

↑これを ↓こう

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore","OpenCV", "OpenCVHelper" });

追加したc++クラスのヘッダーに関数を追加します。

public:
	UFUNCTION(BlueprintCallable)
	static FString ReadQRCode(const FString Path);

cppに本体を作成します。
まずはopenCV系のヘッダーをインクルードしますが、
「”PreOpenCVHeaders.h“」と「”PostOpenCVHeaders.h“」の間にインクルードしないとエラーが出るので注意してください。
でインクルードしようとするとエラー表示されると思いますが気にせずに記載してください。
エラーが出る場合はProjectの「Generate Visual Studio・・・」を実行してください。
(ビルドではエラーが出ないはず・・・)

#include "PreOpenCVHeaders.h"

#include <opencv2/core/mat.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/barcode.hpp>

#include "PostOpenCVHeaders.h"

ついでにファイルチェックも行うので「include <filesystem>」も追加します。

#include <filesystem>

本体です。
Pathをcharのポインタに変換して、カラーの画像指定で読み込みます。
(おそらくグレースケールの画像を読むとまずい気がしますがいったんこのままで・・・)
で読み込んだものをデコードさせているだけの簡単なものです。

/*
*	QRコードの読み込み
*	@param Path QRコード画像のパス
*	@return QRコードの文字列
*/
FString UOpenCVLibrary::ReadQRCode(const FString Path)
{
	// ファイルチェック
	if (std::filesystem::is_regular_file(TCHAR_TO_UTF8(*Path))) {

		// パスから読み込み
		const cv::Mat input_Image = cv::imread(TCHAR_TO_UTF8(*Path), cv::IMREAD_ANYCOLOR);
		// デーコーダー
		cv::QRCodeDetector detecter;
		//
		FString data = detecter.detectAndDecode(input_Image).c_str();

		return data;
	}
	
	return FString();
}

ヘッダー全体

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "OpenCVLibrary.generated.h"

/**
 * 
 */
UCLASS()
class OPENCVQRCODE_API UOpenCVLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
	
public:
	UFUNCTION(BlueprintCallable)
	static FString ReadQRCode(const FString Path);
};

cpp全体

// Fill out your copyright notice in the Description page of Project Settings.

#include "OpenCVLibrary.h"

#include <filesystem>

#include "PreOpenCVHeaders.h"

#include <opencv2/core/mat.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/barcode.hpp>

#include "PostOpenCVHeaders.h"

/*
*	QRコードの読み込み
*	@param Path QRコード画像のパス
*	@return QRコードの文字列
*/
FString UOpenCVLibrary::ReadQRCode(const FString Path)
{
	// ファイルチェック
	if (std::filesystem::is_regular_file(TCHAR_TO_UTF8(*Path))) {
		// パスから読み込み
		const cv::Mat input_Image = cv::imread(TCHAR_TO_UTF8(*Path), cv::IMREAD_ANYCOLOR);
		// デーコーダー
		cv::QRCodeDetector detecter;
		//
		FString data = detecter.detectAndDecode(input_Image).c_str();

		return data;
	}
	
	return FString();
}

BPを使って実際に読み込めるか確認

ここまで記載出来たらF5でプロジェクトを起動します。
「ReadQRCode_BP」など適当な名前をつけたBPを作成します。
(確認用であれば、レベルブループリントに直接記載してもいいかもしれません)

BPの適当なタイミングで先ほど作った「ReadQRCode」を呼び出します。

QR画像は適当なものを使います。
今回はこちら.

これを「コンテンツ」フォルダの適当なフォルダ直下に保存します。
今回は「Resource」フォルダを作成してその直下に保存します。

保存するとプロジェクト側で「インポートしますか?」と聞いてくるので「インポートしない」とします。
BP側でパスの指定をします。
「Project Content」で検索して「Get Project Content Directory」を取得します。

パスを作成してしたいので「Combine」を使用して、パスを生成します.

In Pathsから左クリックを押しながらドラッグして「配列を作成」を置きます。

配列を作成の0に先ほどの「Get Project Content Directory」を接続
「ピンを追加」を押してして、1に「Resource」を記載
「ピンを追加」を押してして、2にQRコードの画像名を設定します。(拡張子まで入れてください)

これでパスが作成できたので、ReadQRCoreにつなげます。

あとは確認用にPrintStringにつなげれば完成です。

あとはBPを配置して実行すると・・・・

こんな感じで表示されるはずです。
あとは実行ファイルで確認したい場合は、先ほどの作ったリソースファイルを実行ファイルでもコピーするようにしないといけないので、プロジェクト設定から、コピーする設定にします。
「編集」→「プロジェクト設定」から
「パッケージ化」→「このプロジェクトの追加ビルド」の「詳細設定」から
「コピーする追加の非アセットディレクトリ」から先ほどの「Resource」フォルダを設定します。

これでビルド時に「Resource」フォルダも実行ファイル内にコピーされるので動くようになるはずです。

これで画像ファイルでのQRコード読み込みができるようになったはずです。
次はカメラ起動できるかやってみます。

コメント

タイトルとURLをコピーしました