本記事でできること
想定シーン
ロボットをビジュアルフィードバック制御する
カメラを使ったロボットアームの制御方法を、ビジュアルフィードバック制御といいます。ここでは、ビジュアルフィードバック制御を使った自動化システムを開発する際に必要となる画像認識プログラムをまとめています。
画像を回転させる
ビジュアルフィードバック制御で使用するカメラの配置が、ロボットの向きとずれている場合があります。この状態で開発をすると、首かしげながら画像認識プログラムを制作することになり、ちょっとつらいです。本記事では、画像を回転させるプログラムを掲載します。掲載したプログラムでは、直角回転以外の場合には、画像の一部が欠けてしまうことがありますので、ご注意ください。ただ、ロボット制御の場合、カメラは90度ずつ回転させる場合が多く、中途半端な角度に回転させることはほとんどありません。
実行環境
- OS:Ubuntu 22.04 LTS
- 言語:C++
- クルーボ:v5.1.0
クルーボについて
ロボットアプリケーション開発には、株式会社チトセロボティクスのロボット制御ソフトウェア「クルーボ」を使用します。本記事のプログラムは、クルーボがインストールされた制御コンピュータ上で動作します。
- クルーボの製品サイト:https://chitose-robotics.com/product
プログラム抜粋
cv::Mat rotate_image(const cv::Mat& image, const float rotate_angle) {
cv::Mat rotated_image;
if ((int)rotate_angle == 90) {
cv::rotate(image, rotated_image, cv::ROTATE_90_CLOCKWISE);
} else if ((int)rotate_angle == 180) {
cv::rotate(image, rotated_image, cv::ROTATE_180);
} else if ((int)rotate_angle == 270) {
cv::rotate(image, rotated_image, cv::ROTATE_90_COUNTERCLOCKWISE);
} else {
cv::Point2f rotate_center_point((float)image.cols / 2.f, (float)image.rows / 2.f);
cv::Mat rotate_matrix = cv::getRotationMatrix2D(rotate_center_point, rotate_angle, 1.0);
cv::warpAffine(image, rotated_image, rotate_matrix, cv::Size(image.cols, image.rows));
}
return rotated_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 rotate_image(const cv::Mat& image, const float rotate_angle) {
cv::Mat rotated_image;
if ((int)rotate_angle == 90) {
cv::rotate(image, rotated_image, cv::ROTATE_90_CLOCKWISE);
} else if ((int)rotate_angle == 180) {
cv::rotate(image, rotated_image, cv::ROTATE_180);
} else if ((int)rotate_angle == 270) {
cv::rotate(image, rotated_image, cv::ROTATE_90_COUNTERCLOCKWISE);
} else {
cv::Point2f rotate_center_point((float)image.cols / 2.f, (float)image.rows / 2.f);
cv::Mat rotate_matrix = cv::getRotationMatrix2D(rotate_center_point, rotate_angle, 1.0);
cv::warpAffine(image, rotated_image, rotate_matrix, cv::Size(image.cols, image.rows));
}
return rotated_image;
}
int main(void) {
std::string file_path = "../data/fuji.jpg";
const cv::Mat loaded_image = load_image(file_path);
const float rotate_angle = 90.f;
const cv::Mat rotated_image = rotate_image(loaded_image, rotate_angle);
cv::imshow("loaded_image", loaded_image);
cv::imshow("rotated_image", rotated_image);
cv::waitKey(0);
}
おわりに
人手作業をロボットアームで自動化するために、カメラを使ったロボット制御=ビジュアルフィードバック制御が大切です。
ロボット制御用の画像認識でも中身のひとつひとつはシンプルなので、要素に分解して解説していきたいと思います。