本記事でできること
想定シーン
ロボットをビジュアルフィードバック制御する
カメラを使ったロボットアームの制御方法を、ビジュアルフィードバック制御といいます。ここでは、ビジュアルフィードバック制御を使った自動化システムを開発する際に必要となる画像認識プログラムをまとめています。
画像にマスクをかける
カメラで撮影した画像には、対象物体の背景や、関係のない物体など、実際の画像認識には不要な部分が写り込んでいる場合があります。こうした不要な箇所を含めて画像処理フィルターをかけてしまうと想定したものと異なる結果が得られてしまい、ロボットのビジュアルフィードバック制御がうまくいかなくなる場合があります。そこで、カメラ画像に対して、見るべきもの以外を黒塗りしてしまう処理をマスク処理といいます。マスク処理では、見るべき箇所(=ROI:Region of Interest)を定義して、それ以外を塗りつぶすマスク画像を作成して、元画像に対してマスク画像を重ねがけることで実装します。本記事では、マスク処理をするためのプログラムを掲載します。
実行環境
- OS:Ubuntu 22.04 LTS
- 言語:C++
- クルーボ:v5.1.0
クルーボについて
ロボットアプリケーション開発には、株式会社チトセロボティクスのロボット制御ソフトウェア「クルーボ」を使用します。本記事のプログラムは、クルーボがインストールされた制御コンピュータ上で動作します。
- クルーボの製品サイト:https://chitose-robotics.com/
プログラム抜粋
cv::Mat set_mask_on_image(const cv::Mat& target_image, const cv::Mat& mask_image) {
cv::Mat masked_image;
if (target_image.channels() == 1) {
cv::Mat mask_image_gray = convert_grayscale(mask_image);
target_image.copyTo(masked_image, mask_image_gray);
} else {
target_image.copyTo(masked_image, mask_image);
}
return masked_image;
}
全体プログラム
#include <iostream>
#include <opencv2/opencv.hpp>
cv::Mat load_image(const std::string file_path) {
cv::Mat loaded_image = cv::imread(file_path, 1);
if (loaded_image.empty()) {
throw std::runtime_error("画像を正常に読み込めませんでした。");
}
return loaded_image;
}
cv::Mat convert_grayscale(const cv::Mat& image) {
const int grayscale_channel_num = 1;
if (image.channels() == grayscale_channel_num) {
return image.clone();
}
cv::Mat gray_image;
cvtColor(image, gray_image, cv::COLOR_BGR2GRAY);
return gray_image;
}
cv::Mat set_mask_on_image(const cv::Mat& target_image, const cv::Mat& mask_image) {
cv::Mat masked_image;
if (target_image.channels() == 1) {
cv::Mat mask_image_gray = convert_grayscale(mask_image);
target_image.copyTo(masked_image, mask_image_gray);
} else {
target_image.copyTo(masked_image, mask_image);
}
return masked_image;
}
int main(void) {
std::string file_path = "../data/fuji.jpg";
const cv::Mat loaded_image = load_image(file_path);
std::string file_path_mask = "../data/mask.jpg";
const cv::Mat mask_image = load_image(file_path_mask);
const cv::Mat masked_image = set_mask_on_image(loaded_image, mask_image);
cv::imshow("masked_image", masked_image);
cv::waitKey(0);
}
おわりに
人手作業をロボットアームで自動化するために、カメラを使ったロボット制御=ビジュアルフィードバック制御が大切です。
ロボット制御用の画像認識でも中身のひとつひとつはシンプルなので、要素に分解して解説していきたいと思います。