概要
M5UnitV2はディスプレイを搭載していないため、OpenCVのcv::imshow()関数などでの確認ができません。画像処理の結果を確認するために、画像をブラウザで配信して確認できるようにします。
環境構築
構築手順に入る前に、まずPCに以下のバージョンのUbuntuをインストールした環境で、構築しました。
Ubuntu 22.04.3 LTS(x64)
OpenCV ver 0.4.4
ncnn ver 231027
Cpp MJPEG Streamerのダウンロード
GitHubからnadjieb氏のcpp-mjpeg-streamerのコードをダウンロードします。
Cpp MJPEG Streamerは、OpenCVの Video画像をJPEGに変換して、HTTP Streamingで配信するためのプログラムです。Cpp MJPEG StreamerはC++のプログラムをヘッダファイルのみでコンパイルして、HTTP Streamingサーバを動かすことができます。
% mkdir example
% cd example
% curl -LO https://raw.githubusercontent.com/nadjieb/cpp-mjpeg-streamer/master/single_include/nadjieb/mjpeg_streamer.hpp
CMakeLists.txt ファイルの作成
cmakeでコンパイルするために、CMakeLists.txtを作成します。
gedit CMakeLists.txt
SET(CMAKE_BUILD_TYPE "Release")
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
# Ubuntuでデバックするためにx64を選択、UnitV2ではarmを指定
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()
PROJECT(mpegstream)
cmake_minimum_required(VERSION 3.8)
set(CMAKE_CXX_STANDARD 17)
if(OpenCV_FOUND)
message(OPENCV_VERSION)
endif(OpenCV_FOUND)
find_package(OpenCV REQUIRED)
link_directories(${OpenCV_LIBRARY_DIRS})
include_directories(${OpenCV_INCLUDE_DIRS} )
include_directories(${PROJECT_SOURCE_DIR})
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${NCNN_INSTALL_DIR}/include/ncnn)
add_executable(mpegstreamer main.cpp)
target_link_libraries(mpegstreamer ${OpenCV_LIBRARIES})
target_link_libraries(mpegstreamer ${NCNN_INSTALL_DIR}/lib/libncnn.a -fopenmp)
サンプルプログラム
MJPEG Streamerでサーバを建てるサンプルプログラムです。
% gedit main.cpp
#include <opencv2/opencv.hpp>
#include <mjpeg_streamer.hpp>
#include <net.h>
#include <pthread.h>
using namespace std;
using namespace cv;
using MJPEGStreamer = nadjieb::MJPEGStreamer;
int main(int argc, char **argv) {
int VideoPort = 0;
bool low_quality_mode = true;
if(argc >= 2) {
VideoPort = atoi(argv[1]);
}
VideoCapture cap(VideoPort);
if(!cap.isOpened()) {
std::cout << "Cannot open cam" << std::endl;
return -1;
}
cap.set(cv::CAP_PROP_FOURCC, cv::CAP_OPENCV_MJPEG);
if(!cap.set(cv::CAP_PROP_FRAME_WIDTH, 640))
std::cout << "camera set width error" << std::endl;
if(!cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480))
std::cout << "camera set height error" << std::endl;
MJPEGStreamer streamer;
std::vector<int> params = {cv::IMWRITE_JPEG_QUALITY, 90};
streamer.start(7778);
std::chrono::steady_clock::time_point Tbegin, Tend;
while(cap.isOpened()) {
Mat frame;
Tbegin = std::chrono::steady_clock::now();
cap >> frame;
if(low_quality_mode == true)
resize(frame, frame, Size(), 1.0f / 2.0f, 1.0f / 2.0f, INTER_AREA);
Tend = std::chrono::steady_clock::now();
float fps = std::chrono::duration_cast<std::chrono::milliseconds>(Tend - Tbegin).count();
putText(frame, cv::format("FPS %0.2f", 1000.0/fps), cv::Point(10, 20), cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(0, 0, 255));
#ifdef __x86_64__
imshow("frame", frame);
const int key = cv::waitKey(1);
#endif
std::vector<uchar> buff_bgr;
cv::imencode(".jpg", frame, buff_bgr, params);
streamer.publish("/frame", std::string(buff_bgr.begin(), buff_bgr.end()));
}
streamer.stop();
return 0;
}
ビルド
Ubuntu用のバイナリをcmakeでコンパイルして、生成されたバイナリを実行します。
% cmake -B build/x64 -DTARGET_COMPILE=x64 .
% cmake --build build/x64
% ./bin/x64/mpegstreamer
UnitV2(arm環境)で動くバイナリをビルドする場合は、Ubuntu用のバイナリで作成されたキャッシュを削除した上で、以下のコマンドでビルドします。
% cmake -B build/arm -DTARGET_COMPILE=arm .
% cmake --build build/arm
% ./bin/x64/mpegstreamer
For M5UnitV2(ARM)
プログラムを動かし、"http://127.0.0.1:7778/frame"へアクセスすると、カメラからのキャプチャ画像をブラウザへ配信して確認することができます。
プログラムの格納先
このプログラムは以下に格納しています。
https://github.com/nnn112358/MJPEGStreamer
参考資料
この記事を作成するにあたり、以下のウェブサイトを参考にしました。