私は、月のクレーター検出のためのOpenCVを使ってC++プログラムを作成しています。このアプローチの私の戦略は、最初に画像をHSVに変換した後、inRange()
を使用して値の範囲内の色をキャッチして閾値を生成し、それをぼかしてHoughCircles()
を使用して円を検出します。OpenCVのinRange()を使用して範囲内の色を検出する
私が完全に理解していないことの1つは、inRange()
に色の周りの低いしきい値と高いしきい値を指定すると、何も返されないということです。ちょうど黒いイメージ。これは、低しきい値をScalar(0,0,0)
に設定した場合にのみ機能しますが、これはやや不正確と思われます。私はこれについて理解していない何かがありますか?私のテストイメージは以下の通りです。
これは私がこのイメージをテストするために使用されるコードである:ここでは
#include <cstdio>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/features2d/features2d.hpp"
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
// using namespace cv;
printf("%s\n", argv[1]);
Mat src=imread(argv[1]);
if (!src.data) {
std::cout << "ERROR:\topening image" <<std::endl;
return -1;
}
// converts the image to hsv so that circle detection is more accurate
Mat hsv_image;
cvtColor(src, hsv_image, COLOR_BGR2HSV);
// high contrast black and white
Mat imgThreshold;
inRange(hsv_image,
Scalar(0, 0, 0),
Scalar(48, 207, 74),
imgThreshold);
// Applies a gaussian blur to the image
GaussianBlur(imgThreshold, imgThreshold, Size(9, 9), 2, 2);
// fastNlMeansDenoisingColored(imgThreshold, imgThreshold, 10, 10, 7, 21);
vector<Vec3f> circles;
// applies a hough transform to the image
HoughCircles(imgThreshold, circles, CV_HOUGH_GRADIENT,
2, // accumulator resolution (size of image/2)
100, //minimum dist between two circles
400, // Canny high threshold
10, // minimum number of votes
10, 65); // min and max radius
cout << circles.size() << endl;
cout << "end of test" << endl;
vector<Vec3f>::
const_iterator itc = circles.begin();
// Draws the circles on the source image
while (itc!=circles.end()) {
circle(src, // src_gray2
Point((*itc)[0], (*itc)[1]), // circle center
(*itc)[2], // circle radius
Scalar(0,0,255), // color
5); // thickness
++itc;
}
namedWindow("Threshold",CV_WINDOW_AUTOSIZE);
resize(imgThreshold, imgThreshold, Size(src.cols/2,src.rows/2)); // resizes it so it fits on our screen
imshow("Threshold",imgThreshold); // displays the source iamge
namedWindow("HSV Color Space",CV_WINDOW_AUTOSIZE);
resize(hsv_image, hsv_image, Size(src.cols/2,src.rows/2)); // resizes it so it fits on our screen
imshow("HSV Color Space",hsv_image); // displays the source iamge
namedWindow("Source Image",CV_WINDOW_AUTOSIZE);
resize(src, src, Size(src.cols/2,src.rows/2)); // resizes it so it fits on our screen
imshow("Source Image",src); // displays the source iamge
waitKey(0);
return 0;
}
['inRange'](http://docs.opencv.org/2.4/modules/core/doc/operations_on_arrays.html#inrange)を'(28,50,100) 'の下限で呼び出すとします。 '(7,216,213)'の上限は?ドキュメントは、関数が何をしているかについてはっきりしています。この場合、チャネル0の場合、 '28 <= x <= 7'の結果を計算します。これは決して真実ではありません。個々のチャンネルのすべての結果と一緒にANDした結果、全体的な結果も決して真実ではありません。ドキュメントを読む! –
@DanMašekそれは正しくない、私はそれを呼び出すことを試みなかった。これは、(0,0,0)の下限に対してテストしたいくつかの_upper bounds_のラベルのないコメントでした。はい、私は徹底的にドキュメントをレビューしました。これが私が最初にやったことでした。 –
それでは、動作しない部分は何ですか?私は、その関数への呼び出しが1つだけで、あなたが書いたことに応じて「Scalar(0,0,0)に低しきい値を設定すると動作します。また、コメントが関係ない場合は、質問に表示しないでください(無関係のジャンクを削除するのに数秒かかる)。 –