質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Q&A

1回答

670閲覧

Raspberry Piのカメラを使って赤色を抽出して、赤色の対象物までの距離を測りたい

tada20

総合スコア4

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

0グッド

0クリップ

投稿2020/01/08 04:59

Raspberry Piのカメラを使って赤色を抽出して、赤色の対象物までの距離を測りたい

Raspberry Piのカメラで赤色を抽出し、赤色の対象物までの距離を計測するシステムを作っています。
HSVをしきい値とした機能を実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

distance:inf mm OpenCV Error: Assertion failed (dims <= 2 && step[0] > 0) in locateROI, file /build/opencv-L65chJ/opencv-3.2.0+dfsg/modules/core/src/matrix.cpp, line 949 terminate called after throwing an instance of 'cv::Exception' what(): /build/opencv-L65chJ/opencv-3.2.0+dfsg/modules/core/src/matrix.cpp:949: error: (-215) dims <= 2 && step[0] > 0 in function locateROI 中止

該当のソースコード

C++

1#include <opencv2/core/core.hpp> 2#include <opencv2/opencv.hpp> 3#include <opencv2/imgproc/imgproc.hpp> 4#include <opencv2/highgui/highgui.hpp> 5#include <stdio.h> 6#include <wiringPi.h> 7#include <wiringPiI2C.h> 8#include <sys/time.h> 9#include <unistd.h> 10#include <iostream> 11#include <vector> 12#include <cmath> 13#include <limits> 14#include "image_processing.h" 15 16using namespace cv; 17using namespace std; 18void switch_cam(int); 19 20#define XSIZE 320 21#define YSIZE 240 22 23const unsigned short width = 320; 24const unsigned short height = 240; 25 26int main() 27{ 28 Mat Leftimage(XSIZE,YSIZE,CV_8UC3); 29 Mat Rightimage(XSIZE,YSIZE, CV_8UC3); 30 Mat frame1; 31 Mat frame2; 32 33 wiringPiSetup(); 34 pinMode(7, OUTPUT); 35 pinMode(0, OUTPUT); 36 pinMode(1, OUTPUT); 37 digitalWrite(1, 1); 38 digitalWrite(0, 1); 39 pinMode(3, OUTPUT); 40 digitalWrite(3, 1); 41 pinMode(4, OUTPUT); 42 digitalWrite(4, 1); 43 pinMode(13, OUTPUT); 44 digitalWrite(13, 1); 45 pinMode(6, OUTPUT); 46 digitalWrite(6, 1); 47 48 VideoCapture cap(0); 49 if(!cap.isOpened()){ 50 return -1; 51 } 52 53 namedWindow("Left", 1); 54 namedWindow("Right", 1); 55 56 int camera = 1; 57 int flg = 0; 58 while(1){ 59 60 double left_center_x, right_center_x; 61 62 Mat LeftCam, RightCam; 63 cap.set(CV_CAP_PROP_FRAME_WIDTH, XSIZE); 64 cap.set(CV_CAP_PROP_FRAME_HEIGHT, YSIZE); 65 switch_cam(camera); 66 67 if(camera == 0){ 68 cap >> LeftCam; 69 //imshow("Left", LeftCam); 70 frame1 = LeftCam.clone(); 71 } 72 73 if(camera == 1){ 74 cap >> RightCam; 75 //imshow("Right", RightCam); 76 frame2 = RightCam.clone(); 77 } 78 79 if(camera==2){ 80 81 Mat gray_left; 82 Mat bin_left; 83 cvtColor(Leftimage, gray_left, CV_RGB2GRAY); 84 threshold(gray_left, bin_left, 0, 255, THRESH_BINARY|THRESH_OTSU); 85 86 Mat gray_right; 87 Mat bin_right; 88 cvtColor(Rightimage, gray_right, CV_RGB2GRAY); 89 threshold(gray_right, bin_right, 0, 255, THRESH_BINARY|THRESH_OTSU); 90 91 hsv_threshold threshold0 = {120, 180, 80, 50}; 92 93 Mat binary1, binary2; 94 Mat hsv_gray1, hsv_gray2; 95 Mat gray1, gray2; 96 97 hsv_gray1 = extract_color(frame1, threshold0); 98 hsv_gray2 = extract_color(frame2, threshold0); 99 threshold(hsv_gray1, binary1, 128, 255, THRESH_BINARY); 100 threshold(hsv_gray2, binary2, 128, 255, THRESH_BINARY); 101 cvtColor(binary1, gray1, CV_GRAY2BGR); 102 cvtColor(binary2, gray2, CV_GRAY2BGR); 103 104 int xmax1=0, xmin1=319, ymin1=279, ymax1=0; 105 for(int y = 0; y < binary1.rows; y++){ 106 for(int x = 0; x < binary1.cols; x++){ 107 if(gray1.at <Vec3b>(y, x)[0] > 0){ 108 xmax1 = x > xmax1 ? x : xmax1; 109 xmin1 = x < xmin1 ? x : xmin1; 110 ymax1 = y > ymax1 ? y : ymax1; 111 ymin1 = y < ymin1 ? y : ymin1; 112 } 113 } 114 } 115 116 int xmax2=0, xmin2=319, ymin2=279, ymax2=0; 117 for(int y = 0; y < binary2.rows; y++){ 118 for(int x = 0; x < binary2.cols; x++){ 119 if(gray2.at <Vec3b>(y, x)[0] > 0){ 120 xmax2 = x > xmax2 ? x : xmax2; 121 xmin2 = x < xmin2 ? x : xmin2; 122 ymax2 = y > ymax2 ? y : ymax2; 123 ymin2 = y < ymin2 ? y : ymin2; 124 } 125 } 126 } 127 128 double d1=0.0; 129 int xl1, yl1; 130 xl1 = xmax1 - xmin1; 131 yl1 = ymax1 - ymin1; 132 d1 = sqrt(xl1 * xl1 + yl1 * yl1); 133 134 double radius1=d1/2.0; 135 136 double center_x1=(double)(xmax1-xmin1)/2.0+xmin1; 137 double center_y1=(double)(ymax1-ymin1)/2.0+ymin1; 138 right_center_x = center_x1; 139 140 double d2=0.0; 141 int xl2, yl2; 142 xl2 = xmax2 - xmin2; 143 yl2 = ymax2 - ymin2; 144 d2 = sqrt(xl2 * xl2 + yl2 * yl2); 145 146 double radius2=d2/2.0; 147 148 double center_x2=(double)(xmax2-xmin2)/2.0+xmin2; 149 double center_y2=(double)(ymax2-ymin2)/2.0+ymin2; 150 left_center_x = center_x2; 151 152 circle(binary1, Point((int)center_x1, (int)center_y1), (int)radius1, Scalar(200,0,200), 1, CV_AA); 153 circle(binary2, Point((int)center_x2, (int)center_y2), (int)radius2, Scalar(200,0,200), 1, CV_AA); 154 155 std::cout << "right_center_x: " << center_x1 << " right_center_y: " << center_y1 << std::endl; 156 std::cout << "right_center_x: " << center_x2 << " right_center_y: " << center_y2 << std::endl; 157 158 imshow("gray_left", binary1); 159 imshow("gray_right", binary2); 160 while(waitKey(0)!=27); 161 } 162 163 double distance = 9000.0/(left_center_x-right_center_x); 164 if(distance<0) distance -= distance*2; 165 cout << "distance:" << distance << " mm" <<endl; 166 167 //cout << "camera:" << camera << endl; 168 camera++; 169 camera = camera % 3; 170 flg++; 171 //if(flg > 20 ) flg = 20; 172ls 173 //waitKey(10); 174 if(waitKey(1) == 27) break; 175 } 176 return 0; 177} 178 179void switch_cam(int cam) 180{ 181 if(cam == 0){ 182 system("i2cset -y 1 0x70 0x00 0x04"); 183 digitalWrite(7, 0); 184 digitalWrite(0, 0); 185 digitalWrite(1, 1); 186 } 187 else if( cam == 1){ 188 system("i2cset -y 1 0x70 0x00 0x06"); 189 digitalWrite(7, 0); 190 digitalWrite(0, 1); 191 digitalWrite(1, 0); 192 } 193} 194

試したこと

1つにまとめている関数(camera==2)のところを、別々の関数に分けて書いたところ、エラーは消えてプログラム自体は動いたが、右カメラだけ真っ黒になった。(これはおそらく右カメラの赤色に対するHSVのしきい値が抽出するのに適した値に設定できていないためだと思われる。)

※左カメラは映りもクリアで、赤色もすぐに抽出できたため、右カメラと左カメラは、かなりの個体差があると思われる。

補足情報(FW/ツールのバージョンなど)

Raspberry Pi 3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yuki23

2020/01/08 06:18

質問は何ですか?
tada20

2020/01/08 06:36

エラーの意味がわからないので教えていただきたいです。また、hsv_threshold threshold0 = {120, 180, 80, 50};で赤色を抽出するためのしきい値を適切な値に設定したいのですが、どうすればよいでしょうか hsv_thresholdは構造体で、第一引数から順に、Hの最小値、Hの最大値、Sの値、Vの値としています。
fana

2020/01/09 02:04

(物理的に可能なのかどうか不明ですが)カメラの個体差を疑うなら,とりあえず左右カメラを入れ替えてみたらどうなるのか?を見てみるとか.
guest

回答1

0

エラーの意味がわからないので教えていただきたいです。

私の手元には動かす環境もないし、する気もないので代わりにデバッグしてあげることはしませんが、
ご自分でGDBなどでステップ実行されてみれば、発生している箇所がわかるでしょう。
OpenCVの関数を呼んでいるところで例外が発生するはずです。
そこで渡している引数を確認してみれば、おかしな値を渡していることに気づくはずです。

ご自分で推測されているとおり、物体が抽出できなかった場合のことを全く考慮していないので、その時の値がおかしいのではないでしょうか。
たぶん、cv::circle に渡す座標なり半径なりが原因ではないかと思います(あてずっぽうです)

また、hsv_threshold threshold0 = {120, 180, 80, 50};で赤色を抽出するためのしきい値を適切な値に設定したいのですが、どうすればよいでしょうか

一般論としては、対象物の性質とカメラの特性によって変わります、としか言えません。
あなたのやりたいこととしては、同じ物体を同じ距離で撮影したとき、両方のカメラで同じ大きさで抽出されることを期待しているはずです。
ならば、そうなるように調整すればよいでしょう。

また、カメラがおかしいことがわかっているのならば、直すなり、買い換えるなり、他のものを買うなりすることも考慮してください。
他にも、照明の当て方、レンズの選び方など覚えなければいけないことは無数にあります。画像処理の開発において、プログラムだけいじっていればいいという考えは捨ててください。

投稿2020/01/08 14:02

yuki23

総合スコア1448

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問