QtでOpenCV(Labelに出力)

# はじめに
OepnCVでUSBカメラから映像を表示させます。
Qtのインストール方法は、
[こちら](https://qiita.com/tom_tom_tom/items/e16618aa5040998252a3)
を参照してください。
ラベル等の設置方法は、
[こちら](https://qiita.com/tom_tom_tom/items/5cc7b3334b9fda9c7dc7)
を参照してください。

# 用意するもの
USBカメラ(PC内蔵のカメラでも可)

# ライブラリ
## インストール
OpenCVを使用しますので、別途ライブラリのインストールが必要になります
ソースからbuildするのは面倒ですので、「apt」コマンドを使用してインストールします。
「apt」コマンドを実行する前に、updateします。
```Update.
sudo apt-get update && sudo apt-get upgrade && sudo apt-get dist-upgrade
```
```Install.
sudo apt-get install -y libopencv-dev python3-opencv
```
一応、pythonのOpenCVもインストールしています。(不要かもしれません)
最新のライブラリを使用したいのでしたら、ソースを取得してbuildする必要があります。
## インストール確認
ターミナルから下記のコマンドを実行します。
```command.
dpkg -l | grep libopencv
```
沢山の出力がありますが、OpenCVのVersionが4.5.4だとわかります。
```
ii  libopencv-calib3d-dev:amd64                4.5.4+dfsg-9ubuntu4                     amd64        development files for libopencv-calib3d4.5d
(以下省略)
```
インストールされたディレクトリは、下記になります。
後でQtをbuildするときに必要になります。
```includeファイル.
/usr/include/opencv4
```
```libファイル.
/usr/lib/x86_64-linux-gnu
```
ちなみに、RaspberryPi(Raspberrypi OS)では、
```include.
/usr/include/opencv4
```
```lib.
/usr/lib/arm-linux-gnueabihf
```
になります。

# UIの作成
Qt(Qt Creator)を起動します。
新しいプロジェクトとして、「OpenCV」とします。
ラベルを設置します。
Qtの起動方法やラベルの設置方法は、「はじめに」で記載したページを参照してください。
ラベルを設置できましたら、以下のようになるはずです。
![Screenshot from 2022-12-16 08-54-39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1473918/5789bbd3-ce74-4534-3838-d741fbc811bd.png)
このラベルの大きさでは、映像が小さいので拡大します。
画面右下にある「▶geometry」をクリックします
![Screenshot from 2022-12-16 08-58-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1473918/1bfd4a7e-c9c6-7990-b29e-a33198cac70e.png)
クリック後の画面
![Screenshot from 2022-12-16 08-58-37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1473918/e327f900-a8ec-9f0e-5b7c-73a1b5b57f75.png)
幅と高さを変更します。
```幅.
55 → 640
```
```高さ.
18 → 480
```
![Screenshot from 2022-12-16 09-02-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1473918/cd638349-5fd6-e33b-7415-cf6198ed328b.png)
入力後は、中央のラベルの大きさが変更されているのが確認できます。
![Screenshot from 2022-12-16 09-03-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1473918/7bb83e52-1298-0a49-9b96-db84454a0c66.png)
ラベルが背景色と同色なので、変更したいと思います。
右下のある「styleSheet」の...をクリックします。
![Screenshot from 2022-12-16 09-04-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1473918/d14f4640-2032-c648-e929-6348c93916c6.png)
「色を追加」をクリックします。
![Screenshot from 2022-12-16 09-06-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1473918/51adb83e-5e8e-70fb-7903-de19f3e96920.png)
「background-color」をクリックします(キャプチャできませんでした)
好きな色を選択してください。今回はとりあえず「白」を選択します。
![Screenshot from 2022-12-16 09-08-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1473918/c8bca958-a9fa-8655-f54e-8385f325af30.png)
背景色の設定ができましたので「OK」をクリックします。
![Screenshot from 2022-12-16 09-10-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1473918/80b68783-2741-99f7-59d3-77de374477f5.png)
背景色が白に変更されましたが、ラベルの「TextLabel」が邪魔です。
これを消したいと思います。
![Screenshot from 2022-12-16 09-13-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1473918/d6740403-843e-fc69-144b-2d8fb6a7ead9.png)
「text」に「TextLabel」が表示しておりますので、クリックしてBS等で削除します。
![Screenshot from 2022-12-16 09-16-46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1473918/b8f44aed-f94d-1328-8d67-b965596657ba.png)
削除すると、中央のラベルの「TextLabel」が消えているのが確認できます。
![Screenshot from 2022-12-16 09-18-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1473918/10924cd8-ccd7-ea58-de31-0d2348ca0154.png)
Ctrl+sで保存し、mainwindow.uiを閉じます。
# 実装等
## 仕様
仕様は以下とします
1.プロプラム起動時からUSBカメラを取得して、ラベルに表示します
2.起動時にUSBカメラが接続されていなければ、メッセージを表示し終了します
## 実装
下記内容を実装してください。追加した箇所はコメントで「追加」としております。
```mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>				// 追加
#include <QMessageBox>			// 追加
#include <opencv2/opencv.hpp>	// 追加
#include <opencv2/highgui.hpp>	// 追加
#include <opencv2/imgproc.hpp>	// 追加

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

private slots:					// 追加
	void updateWindow();		// 追加

private:						// 追加
	QTimer *timer;				// 追加
	cv::VideoCapture cap;		// 追加
	cv::Mat frame, dst;			// 追加
	QImage qtImage;				// 追加
};
#endif // MAINWINDOW_H
```
```mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "opencv2/opencv.hpp"			// 追加
#include "opencv2/imgproc/types_c.h"	// 追加

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

	// 追加(ここから)
	timer = new QTimer(this);

	cap.open(0);
	if(!cap.isOpened()){
		QMessageBox msgBox(this);
		msgBox.setText(tr("カメラがオープンできませんでした。"));
		msgBox.setWindowTitle(tr("エラー"));
		msgBox.setStandardButtons(QMessageBox::Yes);
		msgBox.setDefaultButton(QMessageBox::Yes);
		msgBox.setIcon(QMessageBox::Warning);
		msgBox.exec();
		exit(0);
	}

	cap.set(cv::CAP_PROP_FRAME_WIDTH, 640);
	cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480);

	connect(timer, SIGNAL(timeout()), this, SLOT(updateWindow()));

	timer->start(20);
	// 追加(ここまで)
}

MainWindow::~MainWindow()
{
    delete ui;
}


// 追加(ここから)
void MainWindow::updateWindow()
{
	cap >> frame;
	cv::cvtColor(frame, dst, cv::COLOR_BGR2RGB);

	qtImage = QImage((const unsigned char*) (dst.data), dst.cols, dst.rows, QImage::Format_RGB888);
	ui->label->setPixmap(QPixmap::fromImage(qtImage));
}
// 追加(ここまで)
```
## build
▶をクリックして実行してください。
エラーが表示されます。
![Screenshot from 2022-12-16 09-46-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1473918/6256f63c-30d4-4967-7932-4d2ab9e32596.png)
これは、includeファイルがありませんでしたの意味です。
思い出してください。ライブラリをインストールしましたよね。
OpenCVのファイルをQtで設定する必要があります。
## include/libの設定
OpenCV.proを開き、下記に追加します。追加した箇所はコメントで「追加」としております。
```OpenCV.pro
QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    mainwindow.h

FORMS += \
    mainwindow.ui

TRANSLATIONS += \
    OpenCV_ja_JP.ts
CONFIG += lrelease
CONFIG += embed_translations

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

# 追加(ここから)
INCLUDEPATH += /usr/include/opencv4
DEPENDPATH += /usr/include/opencv4

unix:!macx: LIBS += \
-lopencv_alphamat \
-lopencv_aruco \
-lopencv_bgsegm \
-lopencv_bioinspired \
-lopencv_calib3d \
-lopencv_ccalib \
-lopencv_core \
-lopencv_datasets \
-lopencv_dnn \
-lopencv_dnn_objdetect \
-lopencv_dnn_superres \
-lopencv_dpm \
-lopencv_face \
-lopencv_features2d \
-lopencv_flann \
-lopencv_freetype \
-lopencv_fuzzy \
-lopencv_hdf \
-lopencv_hfs \
-lopencv_highgui \
-lopencv_img_hash \
-lopencv_imgcodecs \
-lopencv_imgproc \
-lopencv_intensity_transform \
-lopencv_line_descriptor \
-lopencv_mcc \
-lopencv_ml \
-lopencv_objdetect \
-lopencv_optflow \
-lopencv_phase_unwrapping \
-lopencv_photo \
-lopencv_plot \
-lopencv_quality \
-lopencv_rapid \
-lopencv_reg \
-lopencv_rgbd \
-lopencv_saliency \
-lopencv_shape \
-lopencv_stereo \
-lopencv_stitching \
-lopencv_structured_light \
-lopencv_superres \
-lopencv_surface_matching \
-lopencv_text \
-lopencv_tracking \
-lopencv_video \
-lopencv_videoio \
-lopencv_videostab \
-lopencv_viz \
-lopencv_ximgproc \
-lopencv_xobjdetect \
-lopencv_xphoto
# 追加(ここまで)
```
とりあえず、すべてのOpenCVライブラリを指定しました。

## 再build
今度はエラーもなく、USBカメラの映像が表示しております。
また、仕様1.の通りに起動後すぐに映像が出力されています。
![Screenshot from 2022-12-16 10-19-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1473918/2378af3d-7584-5004-f7c9-d601024fe093.png)
(映像が暗くてすみません)

## USBカメラを外して再実行
仕様2.を確認するために、一旦終了してUSBカメラをPCから抜いて起動してみましょう。
表示しているプログラムを終了します。(右上の×をクリックします)
USBカメラをPCから抜きます。
再度実行します。
![Screenshot from 2022-12-16 10-25-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1473918/c8c6ef23-a361-5c81-006f-d89cebae402b.png)
上記が表示しましたら「Yes]をクリックしてください。
プログラムが起動せずに、終了しました。
仕様通りですね。

# まとめ
OpenCVを使用すると、簡単にカメラからの映像が取得できます。
Labelに映像を出力しました。
タイマを使用した取得にしました。

# 今後の予定
●映像をLabelではなく、GraphicsViewへ出力する
●タイマではなく、スレッドでUSBカメラを取得する
を記載したいと思います。