4

キャプチャした画像から昆虫を識別するための分類子を作成したいと考えています。最初は HuMoments を使用しましたが、HuMoments はスケール バリアントであるため、異なる解像度でキャプチャされた画像は正しくない結果をもたらしました。インターネットで検索したところ、SIFT と SURF を使用すると問題が解決することがわかったので、SIFT を使用するとどうなるかを調べてみました。下の最初の 2 つの画像は、異なる種類の昆虫に属しています。400 個の特徴のうちすべてが一致していたため、結果は奇妙でした (3 番目の画像を参照)。

ここに画像の説明を入力 ここに画像の説明を入力 ここに画像の説明を入力

int main()
{
Mat src = imread(firstInsect);
Mat src2 = imread("secondInsect");

if(src.empty() || src2.empty())
{
    printf("Can not read one of the image\n");
    return -1;
}

//Detect key point in the image
SiftFeatureDetector detector(400);
vector<KeyPoint> keypoints;
detector.detect(src, keypoints);

//cout << keypoints.size() << " of keypoints are found" << endl;

cv::FileStorage fs(firstInsectXML, FileStorage::WRITE);
detector.write(fs);
fs.release();


SiftFeatureDetector detector2(400);
vector<KeyPoint> keypoints2;
detector.detect(src2, keypoints2);

cv::FileStorage fs2(secondInsectXML,  FileStorage::WRITE);
detector.write(fs2);
fs2.release();


//Compute the SIFT feature descriptors for the keypoints
//Multiple features can be extracted from a single keypoint, so the result is a
//matrix where row "i" is the list of features for keypoint "i"

SiftDescriptorExtractor extractor;
Mat descriptors;
extractor.compute(src, keypoints, descriptors);

SiftDescriptorExtractor extractor2;
Mat descriptors2;
extractor.compute(src2, keypoints2, descriptors2);


//Print some statistics on the matrices returned
//Size size = descriptors.size();
//cout<<"Query descriptors height: "<<size.height<< " width: "<<size.width<< " area: "<<size.area() << " non-zero: "<<countNonZero(descriptors)<<endl;



//saveKeypoints(keypoints, detector);


Mat output;
drawKeypoints(src, keypoints, output, Scalar(0, 0, 255), DrawMatchesFlags::DEFAULT);
imwrite(firstInsectPicture, output);

Mat output2;
drawKeypoints(src2, keypoints2, output2, Scalar(0, 0, 255), DrawMatchesFlags::DEFAULT);
imwrite(secondInsectPicture, output2); 


//Corresponded points
BFMatcher matcher(NORM_L2);
vector<DMatch> matches;
matcher.match(descriptors, descriptors2, matches);

cout<< "Number of matches: "<<matches.size()<<endl;

Mat img_matches;
drawMatches(src, keypoints, src2, keypoints2, matches, img_matches);
imwrite(resultPicture, img_matches); 

system("PAUSE");
waitKey(10000);

return 0;}

質問 1: これら 2 つの画像ですべての特徴が一致しているのはなぜですか?

質問 2: 分類ツリー (ランダム ツリー) でトレーニングするために画像の特徴を保存できる方法 (XML ファイルなど) はどうすればよいですか?

4

2 に答える 2

2

SIFT エッセンシャルはトレーニング画像を取得し、関心のあるポイントを抽出します。これらのポイントはフィルター処理され、コントラストの低いポイントは破棄されます。オブジェクトまたはシーンを説明するために、計算後のハイ コントラスト ポイントが使用されます。これらの基本的な ROI は、均一なスケール、方向などが変化した場合でも、類似のパッチを識別するために使用できます。

ここにはいくつかの問題があります。まず、SIFT を非剛体サーフェス レジストレーションの目的で使用します。これは、共通の機能によってさまざまなバグを (グループ内で) 分類しようとすることを意味しますが、実際には、この目的のために意図されたことはありません。また、バグは実際にはかなり異なっており、共通点はほとんどないようです。次に、本質的にバイナリ マスクのみである非常に低品質の入力ソース (低品質の特徴点) で SIFT を使用します。

オブジェクト登録のさまざまな方法を試す場合は、最初によく知られて広く使用されているおもちゃのデータセットを利用することをお勧めします。これにより、問題が単純化され、簡単なケースで何が機能し、何が機能しないかを確認できるようになります。実際のデータセットに戻ります。

グループ内登録に適していると思われる多くの興味深い方法があります。

于 2013-05-23T22:21:55.353 に答える
1

境界がかなり明確なバイナリ イメージがある場合は、Shape Contextの使用を検討してください。

于 2013-09-10T20:27:59.320 に答える