AWS Lambda をローカルでVisual Studio Codeを使ってデバックしてみる。

前回でAWS Lambda をローカルで使用できるようになったので、さらに開発効率を上げるためVisual Studio Codeを使ってデバックしてみる。
具体的には実行コードにブレイクポイントを設定、実際に処理を止めて使われている変数などをチェックする。
もちろんステップ実行などもできる。

手順としては

上記でブレークポイントで止まるのでデバッグしやすい。

ではまず。

Visual Studio Code にlanch.jsonを追加。
Visual Studio Codeのルートは自動作成されたsam-appフォルダに設定、以下のようになっているはず。

f:id:treehitsuji:20190307142003p:plain

Visual Studio Codeの左の虫アイコンをクリックして上の緑の△ボタンの選択をAdd Configurationを選ぶ。Select EnvironmnetNode.js を選択すると、自動的にlanch.jsonのひな型が作成される。

f:id:treehitsuji:20190307142411p:plain

このlanch.jsonを以下のコードに書き換える

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Attach to SAM CLI",
            "type": "node",
            "request": "attach",
            "address": "localhost",
            "port": 5858,
            // From the sam init example, it would be "${workspaceRoot}/hello_world"
            "localRoot": "${workspaceRoot}/hello-world",
            "remoteRoot": "/var/task",
            "protocol": "inspector",
            "stopOnEntry": false
        }
    ]
}

f:id:treehitsuji:20190307142524p:plain

Visual Studio Codeのメニューから Terminalを呼び出し、ターミナルを表示する。(通常のターミナルでもOK)

f:id:treehitsuji:20190307142937p:plain

ターミナルウインドウで sam を デバッグモードで起動する。

sam local start-api --debug-port 5858

Running on http://127.0.0.1:3000/ (Press CTRL+C to quit) と表示され待機状態へ

f:id:treehitsuji:20190307143435p:plain

ブレークポイントで止めたいソースコードにブレイクポイントを設定

f:id:treehitsuji:20190307143612p:plain

ブラウザからURLをたたく f:id:treehitsuji:20190307143732p:plain

処理が待機状態になったので、Visual Studio Codeデバッグを開始する。(F5キーを押すか、Debug > Start Debugging)
すると、設定したデバッグポイントで停止するので、変数など確認できる。ステップ実行も可能。

f:id:treehitsuji:20190307144053p:plain

やったね、デバッグやりやすい!!

AWS Lambda をローカルで使用できるようにしてみる。

最近流行り?のサーバーレスアーキテクチャーを試してみたいのでいろいろ検討してみると今のところAWS Lambdaが標準っぽい。
しかしそのためだけにAWSにアカウント作ってもな~と考えていた。 よくよく調べてみるとAWS Lambdaで開発するにはいちいちAWSのコンソールからコードを作成したり、ローカルで作成したコードをZIPにしてアップロードするなどしなければならない。 どう考えても開発効率悪いとおもったので、いっそローカルで開発できればもっといいのにな~っと。

ありました!!
Installing the AWS SAM CLI on Linux - AWS Serverless Application Model

実際にローカルで動かすまでやってみました。

必要であったのは以下

  • Linuxbrew
  • Docker
  • awscli
  • aws-sam-cli

Linuxbrewをインストール

apt update
apt upgrade
sudo apt install linuxbrew-wrapper

次に以下を参考に
Installing the AWS SAM CLI on Linux - AWS Serverless Application Model
AWS SAM CLIをインストール

brew upgrade
brew update
brew tap aws/tap
brew install aws-sam-cli

/home/linuxbrew/binを パスに追加 ~/.bashrc の最後の行に以下を追加

export PATH='/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin':"$PATH"

いったんターミナルを閉じて、新しいターミナルを起動

sam --version

SAM CLI, version 0.12.0

上記のように表示されればOK

次にDockerをいれる。 以下を参照

Get Docker CE for Ubuntu | Docker Documentation

sudo apt-get remove docker docker-engine docker.io containerd runc

sudo apt-get update

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io

上記でインストール

sudo docker ps

上記のコマンド入力でエラーが出てなければOK
以下の表示が出てくればOK
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

次に、AWSのリージョンを設定する。この作業をしないとこの後で、リージョン設定されていないです!!と、いうこと聞かないので、ここで設定しておく

brew install awscli
aws configure

以下のように設定
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: ap-northeast-1
Default output format [None]: json

リージョンセットOK!!

次に、以下を参照にQuick Startを試してみる。
Quick Start - AWS Serverless Application Model

cd ~
mkdir work
cd work
sam init --runtime nodejs

上記で work フォルダーの中に sam-appフォルダが作成される
nodeで実行できるようにする。

cd ~/work/sam-app/hello-world
npm install
cd ..
sam local start-api

ここで ターミナルに
Running on http://127.0.0.1:3000/ (Press CTRL+C to quit) と表示されればOK

Error: Running AWS SAM projects locally requires Docker. Have you got it installed? と表示された場合は

dockerがログインしたユーザで操作できない状態なので以下で確認

docker ps

Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.39/containers/json: dial unix /var/run/docker.sock: connect: permission denied

上記のエラーが表示されている場合は現在のログインユーザをdockerグループへ入れてあげる。

gpasswd -a <USER> docker

いったんログアウト&ログインして再度コマンドで確認

docker ps

sudo なしの上記のコマンド入力でエラーが出てなければOK
以下の表示が出てくればOK
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

cd ~/work/sam-app/
sam local start-api

Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
上記を確認!!

あとは以下をブラウザから呼び出して http://127.0.0.1:3000/hello

{"message":"hello world"}

表示されればOK

f:id:treehitsuji:20190305135826p:plain

OpenCVを使って画像を縮小、拡大してみる。

画像を小さくしたり、大きくしたりしたいけど、正方形なら cv::resize を
使えばいいのだけど 長方形の画像などでは縦横比を維持したまま縮小、拡大したい。

//画面をだすよ
void display(cv::Mat image) {
    //名前をつける
    std::string windowName = "windowName";
    cv::namedWindow(windowName);
    //画面出た!!
    cv::imshow(windowName, image);
    //なにかキーをおして~
    cv::waitKey(1000 * 10);
    //整理整頓
    cv::destroyWindow(windowName);
}

//
// ここから
//
int main(int argc, char** argv) {

    //500x500の画像に変換
    int width = 500;

    cv::Mat convert_mat, work_mat;
    //前処理 余った余白は黒で埋める
    work_mat = cv::Mat::zeros(cv::Size(width, width), CV_8UC3);
    //画面読み込み
    cv::Mat target_mat= cv::imread("starry_night.jpg");

    //縦横どっちか長い方は?
    int big_width = target_mat.cols > target_mat.rows ? target_mat.cols : target_mat.rows;
    //割合
    double ratio = ((double)width / (double)big_width);

    //リサイズ
    cv::resize(target_mat, convert_mat, cv::Size(), ratio, ratio, cv::INTER_NEAREST);

    //中心をアンカーにして配置
    cv::Mat Roi1(work_mat, cv::Rect((width - convert_mat.cols) / 2, (width - convert_mat.rows) / 2, 
    convert_mat.cols, convert_mat.rows));
    convert_mat.copyTo(Roi1);

    target_mat = work_mat.clone();

    //画面へ
    display(target_mat);
    return 0;
}

変換前画像 (752x600) f:id:treehitsuji:20190220114225p:plain

変換後画像 (500x500) f:id:treehitsuji:20190220114236p:plain

VisualStudioCodeでOpenCVを使ったC++プログラムをブレークポイントで停止させてデバッグできるようにしてみる②

f:id:treehitsuji:20190215155327p:plain

CMakeLists.txtを以下に変更

cmake_minimum_required(VERSION 3.5.1)                                                              
project(main)                                                                                      
set(CMAKE_CXX_STANDARD 11)                                                                         
set(CMAKE_CXX_FLAGS "-Wall -g")                                                                    
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(main main.cpp)
target_link_libraries(main ${OpenCV_LIBRARIES})

main.cppを以下に変更

#include <opencv2/core/core.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
    std::cout << cv::getBuildInformation() << std::endl;
    return 0;
}

7行目にブレーク―ポイントを設定 f:id:treehitsuji:20190218105307p:plain

コマンドパレットを起動して(Ctrl+Shift+p)
Cmake:Build a Target を選択する。

f:id:treehitsuji:20190218105633p:plain

ALLを選択

f:id:treehitsuji:20190218105732p:plain

OUTPUTビューにビルド成功と表示されればOK

[build] [ 50%] Building CXX object CMakeFiles/main.dir/main.cpp.o
[build] [100%] Linking CXX executable main
[build] [100%] Built target main
[build] Build finished with exit code 0

メニューより Debug->Start Debugging を選択する。またはF5キーを押す

Select Enviroment と表示されるので
C++(GDB/LLDB)を選択

f:id:treehitsuji:20190218110208p:plain

Lanch.json が自動的に作成される。
Lanch.jsonの以下の行を変更する。

"program": "enter program name, for example ${workspaceFolder}/a.out",

変更後

"program": "${workspaceFolder}/build/main",

f:id:treehitsuji:20190218110748p:plain

セーブして。再度
メニューより Debug->Start Debugging を選択する。またはF5キーを押す

ブレークポイントで止まる。

f:id:treehitsuji:20190215155327p:plain

VisualStudioCodeでOpenCVを使ったC++プログラムをブレークポイントで停止させてデバッグできるようにしてみる①

f:id:treehitsuji:20190215155327p:plain
ブレークポイントで止まっている画像
VisualStudioCodeがなんかよい感じなのでプロジェクトを作成してデバッグできるようにしてみる。
ソースコードの行にブレイクポイントを設定して変数の中身などを確認できる。
さらにステップ実行も可能。

ステップとして

  • gdbのインストール
sudo apt install gdb
cd ~
mkdir vswork

VSCODEのメニュー File > Add Folder to Workspace で 先ほど作成した ~/vsworkを選択する。 f:id:treehitsuji:20190215161036p:plain

  • CMakeのQuickStartを利用してCmakeを使用できるようにする。

    View > Command Palette (Ctrl+Shift+P) で コマンドパレットを表示
    Cmake と入力 f:id:treehitsuji:20190215161442p:plain

プルダウンから Cmake:Quick Start を選択
Select a Kit と表示されるので GCC 7.3.0 選択
f:id:treehitsuji:20190215161846p:plain

新しいプロジェクトの名前を入れるように指示されるので 適当にプロジェクト名を入れる。

f:id:treehitsuji:20190215162302p:plain

ライブラリーを作成するのか実行ファイルを作成するのか聞かれるので
Executableを選択。 f:id:treehitsuji:20190215162429p:plain

以上の手順で以下のようなファイル構成になる。

f:id:treehitsuji:20190215162616p:plain

OpenCVが4.0になっていたのでcontribも含めてコンパイルしてみる。

以下は本家のサイト opencv.org

せっかくなのでGithubからソースをクローンしてコンパイルをしてみることにした。(Linux

手順としては

  • 必要なパッケージをインストール
sudo apt update
sudo apt upgrade

sudo apt install build-essential
sudo apt install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libdc1394-22-dev
  • opencvGitHubからクローン、バージョン指定(check out)
cd ~
mkdir work
cd ~/work
git clone https://github.com/opencv/opencv.git
cd ~/work/opencv
git checkout -b 4.0.1 refs/tags/4.0.1
  • contribをGitHubからクローン、バージョン指定(check out)
cd ~/work
git clone https://github.com/opencv/opencv_contrib.git
cd ~/work/opencv_contrib
git checkout -b 4.0.1 refs/tags/4.0.1
cd ~/work/opencv
mkdir build
cd ~/work/opencv/build

cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules ..

make -j2

sudo make install
sudo ldconfig
  • インストールされているかチェック

    以下のコードをコンパイルして実行してみる。

cd ~
mkdir test
cd ~/test

cat <<EOF > testcv.cpp
#include <opencv2/core/core.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
    std::cout << cv::getBuildInformation() << std::endl;
    return 0;
}
EOF

cat <<EOF > CMakeLists.txt
cmake_minimum_required(VERSION 3.5.1)                                                              
project(testcv)                                                                                      
set(CMAKE_CXX_STANDARD 11)                                                                         
set(CMAKE_CXX_FLAGS "-Wall -g")                                                                    
find_package(OpenCV REQUIRED)
include_directories(\${OpenCV_INCLUDE_DIRS})
add_executable(testcv testcv.cpp)
target_link_libraries(testcv \${OpenCV_LIBRARIES})
EOF

mkdir build
cd build
cmake ..
make

上記をコンソール上にコピー&ペースト
testcv.cpp が作成されるので

実行

./testcv

以下のような情報が出力されればOK

General configuration for OpenCV 4.0.1-openvino =====================================
Version control: 4.0.1-openvino

Extra modules:
Location (extra): /home//work/opencv_contrib/modules
Version control (extra): 4.0.1

  ・
  ・
  ・

OpenCVを使ってある色以外は白黒にしてみる。

OpenCVを使ってある色以外は白黒にしてみる。

よくある処理に、ある色のみカラーにして他の色は白黒にして
ちょっと雰囲気のある写真にしたててみる。

オレンジ色のみ残して他の色を無くす(グレースケール)にしてみた。
ある色といってもRGBの数値でオレンジと示されても人間にはわからんので
直観的ででわかりやすいHSV色空間へいったん変更する。

https://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93
OpenCVでは色相(Hue)は0 - 180の範囲なので注意!!

HSV色空間へ変換した画像の色相(Hue)0〰20くらいまでのピクセル以外の
他の色のピクセルを全て彩度(Saturation)を0にすると色が無くなるのでグレースケールになる。
HSV色空間へ変換したあとRGB色空間へ戻すのをお忘れなく!!

//画面をだすよ
void display(cv::Mat image) {
    //名前をつける
    std::string windowName = "windowName";
    cv::namedWindow(windowName);
    //画面出た!!
    cv::imshow(windowName, image);
    //なにかキーをおして~
    cv::waitKey(1000 * 10);
    //整理整頓
    cv::destroyWindow(windowName);
}

//
// ここから
//
int main(int argc, char** argv) {

    cv::Mat image_ = cv::imread("fruits.jpg");
    cv::Mat ret_mat, hsv_image, dst_img;

    //HSV色空間へ
    cv::cvtColor(image_, hsv_image, CV_BGR2HSV);
    //HSV分解
    std::vector<cv::Mat> mat_channels;
    cv::split(hsv_image, mat_channels);

    //取り出す色を決定 0 - 20 まで
    int hue_min = 0;
    int hue_max = hue_min + 20;

    int hsv_value;
    int cols = hsv_image.cols;
    int rows = hsv_image.rows;
    for (int row = 0; row < rows; row++) {
        for (int col = 0; col < cols; col++) {
            hsv_value = static_cast<int>(mat_channels[0].at<uchar>(row, col));
            //色相(Hue)
            if (!((hue_min <= hsv_value) && (hsv_value <= hue_max))) {
                //彩度(Saturation)を0に
                mat_channels[1].at<uchar>(row, col) = 0;
            }
        }
    }
    //マージ
    cv::merge(mat_channels, dst_img);
    //RGB色空間へ (BGR)
    cv::cvtColor(dst_img, ret_mat, CV_HSV2BGR);

    //画面へ
    display(ret_mat);

    return 0;
}

オリジナル画像 f:id:treehitsuji:20170202175454j:plain

オレンジだけカラー画像 f:id:treehitsuji:20170202175458j:plain