RealSenseSDK2で距離マップと画像の座標を一致した状態で取得する

D415やD435でrealsenseSDK2を使い距離と画像を同時取得しようと別々に処理かけると座標と見える領域にズレが生じます。
距離情報と画像情報を使って処理させるにはこのズレを一致させないといけません。

環境

ubuntu16.04 kernel 4.4.0-130-generic
opencv3.4

画像と距離情報の取得

例えば以下のページでenableして画像と距離情報を取得しているのは、ズレが生じた状態です。
librealsense/getting_started_with_openCV.md at master · IntelRealSense/librealsense · GitHub


座標系を一致した状態で取得

サンプルにあるDNNから編集しました。

#include <librealsense2/rs.hpp>
#include "cv-helpers.hpp"
#include <opencv2/opencv.hpp>   // Include OpenCV API
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace cv;
using namespace std;
using namespace rs2;
const size_t inWidth      = 640;
const size_t inHeight     = 480;
const float WHRatio       = inWidth / (float)inHeight;

int main(int argc, char** argv) try
{

    // Start streaming from Intel RealSense Camera
    pipeline pipe;
    auto config = pipe.start();
    auto profile = config.get_stream(RS2_STREAM_COLOR)
                         .as<video_stream_profile>();
    rs2::align align_to(RS2_STREAM_COLOR);

    Size cropSize;
    if (profile.width() / (float)profile.height() > WHRatio)
    {
        cropSize = Size(static_cast<int>(profile.height() * WHRatio),
                        profile.height());
    }
    else
    {
        cropSize = Size(profile.width(),
                        static_cast<int>(profile.width() / WHRatio));
    }

    Rect crop(Point((profile.width() - cropSize.width) / 2,
                    (profile.height() - cropSize.height) / 2),
              cropSize);

    const auto window_name = "Display Image";
    namedWindow(window_name, WINDOW_AUTOSIZE);

    while (cvGetWindowHandle(window_name))
    {
        // Wait for the next set of frames
        auto data = pipe.wait_for_frames();
        // Make sure the frames are spatially aligned
        data = align_to.process(data);

        auto color_frame = data.get_color_frame();
        auto depth_frame = data.get_depth_frame();

        // If we only received new depth frame, 
        // but the color did not update, continue
        static int last_frame_number = 0;
        if (color_frame.get_frame_number() == last_frame_number) continue;
        last_frame_number = color_frame.get_frame_number();

        // Convert RealSense frame to OpenCV matrix:
        auto color_mat = frame_to_mat(color_frame);
        auto depth_mat = depth_frame_to_meters(pipe, depth_frame);
        
        imshow(window_name, color_mat);
        imshow("img", depth_mat);
        char key = waitKey( 5 );   

    }
}catch (const rs2::error & e)
{
    std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n    " << e.what() << std::endl;
    return EXIT_FAILURE;
}
catch (const std::exception& e)
{
    std::cerr << e.what() << std::endl;
    return EXIT_FAILURE;
}

python,opencvで任意の大きさの面積だけを抽出する

検索してもあんまり出てこなかったりして、右往左往してなんとか書きました。
でももっと効率の良い書き方があると思いますので知っていたら教えてください、、、

環境

ubuntu16.04
opencv3.4
python3.5

プログラム
import cv2
import numpy as np

frame = cv2.imread("img.png")
height = frame.shape[0]
width = frame.shape[1]

img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#2値化
thresh = 40
max_pixel = 255
ret, img_dst = cv2.threshold(img_gray,
                             thresh,
                             max_pixel,
                             cv2.THRESH_BINARY)
#指定領域面積のみ抽出                             
dst = np.zeros((height, width, 1), np.uint8)
connectivity = 4
min_area=100
max_area=10000
output = cv2.connectedComponentsWithStats(img_dst, connectivity, cv2.CV_32S)
for i in range(output[0]):
    if output[2][i][4] >= min_area and output[2][i][4] <= max_area:
        cv2.rectangle(dst, (output[2][i][0], output[2][i][1]), (
            output[2][i][0] + output[2][i][2], output[2][i][1] + output[2][i][3]), (255, 255, 255), -1)
res = cv2.bitwise_and(dst,img_dst)


cv2.imshow("gray", img_dst)
cv2.imshow("frame", frame)
cv2.imshow("result", res)

k = cv2.waitKey(0)


cv2.destroyAllWindows()

RealSenseSDK2で任意の場所の距離を取得する

距離を自由に扱いたいので、まず任意の場所の距離を取得したいと思います。
今回は画像の真ん中の座標の距離を取得します。

#include <stdio.h>
#include <librealsense2/rs.hpp> // Include RealSense Cross Platform API
#include <opencv2/opencv.hpp>   // Include OpenCV API

int main(int argc, char * argv[]) try
{
    // Declare depth colorizer for pretty visualization of depth data
    rs2::colorizer color_map;

    // Declare RealSense pipeline, encapsulating the actual device and sensors
    rs2::pipeline pipe;
    // Start streaming with default recommended configuration
    pipe.start();

    using namespace cv;
    const auto window_name = "Display Image";
    namedWindow(window_name, WINDOW_AUTOSIZE);
    float pixel_distance_in_meters;
    while (waitKey(1) < 0 && cvGetWindowHandle(window_name))
    {
        rs2::frameset data = pipe.wait_for_frames(); // Wait for next set of frames from the camera
        rs2::frame depth = color_map(data.get_depth_frame());
        rs2::depth_frame depth_point = data.get_depth_frame();

        // Query frame size (width and height)
        const int w = depth.as<rs2::video_frame>().get_width();
        const int h = depth.as<rs2::video_frame>().get_height();

        // Create OpenCV matrix of size (w,h) from the colorized depth data
        Mat image(Size(w, h), CV_8UC3, (void*)depth.get_data(), Mat::AUTO_STEP);

        //get depth
        //画像の真ん中のxy座標の距離を取得
        pixel_distance_in_meters = depth_point.get_distance(w/2,h/2);
        std::cout << pixel_distance_in_meters  << std::endl;

        // Update the window with new data
        imshow(window_name, image);
    }

    return EXIT_SUCCESS;
}
catch (const rs2::error & e)
{
    std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n    " << e.what() << std::endl;
    return EXIT_FAILURE;
}
catch (const std::exception& e)
{
    std::cerr << e.what() << std::endl;
    return EXIT_FAILURE;
}

RealSenseSDK2のプログラムをコンパイルする

RealSenseSDK2のサンプルを引っこ抜いて自分用に改造するためにした作業です。

環境

ubuntu16.04 kernel 4.4.0-130-generic
opencv3.4
 


開発パッケージ入手とインストール

GitHub - IntelRealSense/librealsense: Intel® RealSense™ SDK
ここからダウンロードもしくはgit cloneする
次に開発パッケージの入手

sudo apt-get install librealsense2-dev
sudo apt-get install librealsense2-dbg

以下参考HPを見ていたらcmake3.8.x以上が必要とのこと。
自分の環境ではcmakeバージョンが低いので以下を参考にして上げた。
デプスカメラRealSenseD435で "紫色のイカ" や "オレンジ色の玉ねぎ" を切り取ったり "金髪の人" を追っかけて距離を測る(1) with Ubuntu16.04
ここの「RealSenseとOpenCVの連携サンプルをビルド」の項目を参照
 
次にcmakeしてインストールする

cd
cd librealsense
mkdir build
cd build
cmake  ../ -DBUILD_EXAMPLES=true  -DBUILD_CV_EXAMPLES=true
make
sudo make install

(ホームにlibrealsenseとして展開している前提のコマンド)
ビルドのオプションは以下を参考。
Build Configuration · IntelRealSense/librealsense Wiki · GitHub
本当はpythonも入れたかったけど入らなかった。。。

rs-capture

にて動作するか確認。

自分用に改造するためにmakeが通るか確認

サンプルに何があるかは以下を参照する
librealsense/examples at master · IntelRealSense/librealsense · GitHub
 
まず、librealsenseを解凍したフォルダのexamples/captureを自分の作業したところにコピーする
次にexamples/third-partyもcaptureと同じフォルダにコピーしてくる
コマンドで

g++ rs-capture.cpp -o rs-capture.out -std=c++14 -I/home/librealsense/include/  `pkg-config --static --libs gl` `pkg-config --static --libs glew` -lglfw -lgomp -ljpeg  -L/usr/local/lib -lrealsense2
./rs-capture

これで起動確認
 
自分はglewが無いと怒られたので以下をインストール

sudo apt-get install libglew-dev

 
次にOpencvを用いたキャプチャをコンパイルしてみる
librealsense/wrappers/opencv/imshowをコピーしてくる

g++ rs-imshow.cpp -o rs-imshow.out -std=c++14 -I/home/librealsense/include/  `pkg-config --static --libs gl` `pkg-config --static --libs glew` `pkg-config --libs --cflags opencv` -lglfw -lgomp -ljpeg  -L/usr/local/lib -lrealsense2
./rs-imshow

で起動確認
f:id:weekendproject9:20180802193546p:plain
 
次回から少しずついじっていく予定
終わり

 

realSenseの環境構築とサンプル実行

Intel® RealSense™ Depth Camera D435を買ったので動かすまでのメモ
https://click.intel.com/intelr-realsensetm-depth-camera-d435.html
f:id:weekendproject9:20180802183355p:plain

[環境]
ubuntu16.04 kernel 4.4.0-130-generic

Realsenseインストール作業

自分の環境の確認

github.com
とにかくここを見る

ubuntuの人はInstallのところのLinuxへ行く
- ubuntバージョンとカーネルの確認
 2018/08/02現在
 >> Ubuntu LTS kernels 4.4, 4.10, 4.13  <<
 となっている。
 コマンドでは uname -a で自分のバージョンを確認できる

ちなみにopencvと連携して使い人は以下の一番下を確認 
 librealsense/wrappers/opencv at master · IntelRealSense/librealsense · GitHub
 2018/08/02現在ではopencv3.4で使える模様
 (このブログの下の方に3.4インストールの手順を記述)

SDKインストール作業

librealsense/distribution_linux.md at master · IntelRealSense/librealsense · GitHub
基本的にはここを見る。
しかし最新版になったり更新されると当然コマンドが変わったりキーが変わるので注意。

sudo apt-key adv --keyserver hkp://keys.gnupg.net:80 --recv-key C8B3A55A6F3EFCDE
sudo add-apt-repository "deb http://realsense-hw-public.s3.amazonaws.com/Debian/apt-repo xenial main" -u
#サンプル入手
sudo apt-get install librealsense2-dkms
sudo apt-get install librealsense2-utils

もし昔のrealsemseのバージョンが入っている人は事前に削除しておく。
サンプルを手に入れたらD435をPCに繋いで

realsense-viewer

これで動くのを確認

Opencv3.4インストール

1.
OpenCV 3.4 - OpenCV library
The source code for all platforms can be downloaded from GitHub:のところからzip入手
Release 3.4.0 · opencv/opencv_contrib · GitHub
zip入手

2.
homeにopencvという名前のフォルダを作成してDLした2つのファイルを解凍して入れる

3.

cd
cd opencv
mkdir build
cd build

cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D OPENCV_EXTRA_MODULES_PATH=~/opencv/opencv_contrib-3.4.0/modules  -D BUILD_NEW_PYTHON_SUPPORT=ON -D PYTHON_EXECUTABLE=/usr/bin/python3.5 -D BUILD_opencv_python3=ON -D BUILD_opencv_python2=ON -D WITH_V4L=ON -D WITH_VTK=ON -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D BUILD_EXAMPLES=ON -D ENABLE_FAST_MATH=1 -D CUDA_FAST_MATH=1 -D WITH_CUBLAS=1 -D WITH_OPENGL=ON -D WITH_CUDA=ON  ..

自分はpythonも使うのでcmake結果に出てくるpythonの項目がきちんとなっているかを確認した。
また、pythonのバージョンが違う人はPYTHON_EXECUTABLEの項目を変える

make -j  4
sudo make install
sudo /bin/bash -c ‘echo “/usr/local/lib” > /etc/ld.so.conf.d/opencv.conf’
sudo  ldconfig

おわり

DC-DCモジュール ステップアップを試してみる(2~24V→5~28V)

USBやリポなどの1セルから任意の電圧に昇圧するDCDCを買ったので電圧を確認しました。
今回買ったのは以下の物になります。
f:id:weekendproject9:20180727215004p:plain
www.denshi-trade.co.jp

モジュールにUSBをさして電圧を確認すると4.97V付近でした。
次に半固定抵抗のボリュームを時計周りに回したのですが、全然電圧が動かなくて、あれ?と思いましたが、次第に昇圧されていきました。
感覚ですが20回程度回したあたりから変動しました。


これも同じのかな?
ja.aliexpress.com

おわり

darknetでYoLoV3マルチクラス学習

Yolov3を多クラス学習したときのメモ。
といっても、サイトに手順書いてあるし、前回のyolov2とほぼ同じ。

Darknetサイト

YOLO: Real-Time Object Detection
 

注意

2018年4月30日現在、OpenCV 3.4.1以上はmakeできない
 

まず最新のdarknetを取得

$ git clone https://github.com/pjreddie/darknet
$ cd darknet

makefileを開き、自分の環境に合わせる
例:
 GPU=1
 CUDNN=1
 OPENCV=1
 OPENMP=0
 DEBUG=0

$ make

 

学習済みモデルのダウンロード

Darknetのサイト、”Download Pretrained Convolutional Weights”の項目からhere (76 MB).をクリックして
darknet53.conv.74をダウンロードする。
 

学習の準備

前回の学習ブログと同様で学習させたいデータ(画像・ラベル)を準備する。
同じやり方で大丈夫。もうある人は画像フォルダや設定ファイルをもってくれば使えます。
しかし、“・darknetで学習“の項目から編集が必要です。
・darknet/cfgの”obj.data”は以前と同様
・cfg/yolo-obj.cfgは編集する必要あり


 1.yolov3-voc.cfgをコピーしてyolo-obj.cfgに名前を変更
 2. 3行目 batch=1 を64に変更。4行目 subdivisions=1 を8に変更
 3..cfg内の[yolo]の項目を検索して、その一つ上の[convolutional]の項目内、filtersを filters=(classes + 5)x3 に変更する(3つある)
 4.各[yolo]内のclassesを自分のクラス数に書き換え
 
[確認]
・学習データ、ラベルをdataフォルダ内のobjフォルダに格納
・data/obj.names、data/objにtrain.txt,test.txtがあるか
・ darknet53.conv.74をdarknet/に保存したか
・darknet/cfgに独自のobj.data,yolo-obj.cfgを用意したか
・darknetフォルダにbackupフォルダがあるか
 

学習開始

./darknet detector train cfg/obj.data  cfg/yolo-obj.cfg darknet53.conv.74

*学習過程で "-nan" が出てくるが学習における82,94,108のどれかで数字が出ていれば学習が進んでいる
 参考→Training IOU, Cass, OBj, etc. = nan ? · Issue #600 · AlexeyAB/darknet · GitHub 
*うまくいかない場合はyolo-obj.cfgの3行目 batch=1 を32に変更。4行目 subdivisions=1 を16に変更(メモリが足らずに落ちる場合も同様)
 それでもうまくいかない場合は、batch=1、 subdivisions=1に戻して学習の挙動を見てみる
 

参考

てかこっちの方が親切でありがたい
github.com