레고 정렬 기계를 만들기 위해 레고 벽돌을 식별하고 싶습니다 (저는 opencv에서 C++을 사용합니다). 즉, 매우 비슷하게 보이는 오브젝트를 구별해야합니다.opencv로 개체 구별
벽돌이 내 카메라에 개별적으로 플랫 컨베이어에서 보입니다. 그러나 그들은 가능한 모든 방향으로 놓을 수 있습니다 : 거꾸로, 옆으로 또는 "정상".
나의 접근 방식은 벽돌을 다양한 위치와 회전으로 카메라로 찍어서 벽돌을 분류하는 것입니다. 각보기의 특징은 surf-algorythm에 의해 계산됩니다.
void calculateFeatures(const cv::Mat& image,
std::vector<cv::KeyPoint>& keypoints,
cv::Mat& descriptors)
{
// detector == cv::SurfFeatureDetector(10)
detector->detect(image,keypoints);
// extractor == cv::SurfDescriptorExtractor()
extractor->compute(image,keypoints,descriptors);
}
알 수없는 브릭 (내가 분류하고자하는 브릭)이 있으면 그 기능도 계산되고 알려진 것과 일치합니다. 이 책을 OpenCV이 요리 책에 설명 된대로 내가 계속 잘못 일치하는 기능을 찾으려면 :
일치 프로그램과를 양 방향에있는 두 개의 가장 가까운 이웃
를 검색한다 (CV : BFMatcher (CV : NORM_L2이) =)matcher.knnMatch(descriptorsImage1, descriptorsImage2, matches1, 2); matcher.knnMatch(descriptorsImage2, descriptorsImage1, matches2, 2);
내가 발견 한 가장 가까운 이웃의 거리 사이의 비율을 확인합니다. 두 거리가 매우 비슷한 경우 거짓 값이 사용됩니다.
// loop for matches1 and matches2 for(iterator matchIterator over all matches) if(((*matchIterator)[0].distance/(*matchIterator)[1].distance) > 0.65) throw away
마지막에만 symmatrical 일치 쌍은 허용됩니다. 이것은 n1이 피처 f1에 가장 가까운 이웃 일뿐만 아니라 f1이 n1에 가장 가까운 이웃 인 경우의 일치입니다.
for(iterator matchIterator1 over all matches) for(iterator matchIterator2 over all matches) if ((*matchIterator1)[0].queryIdx == (*matchIterator2)[0].trainIdx && (*matchIterator2)[0].queryIdx == (*matchIterator1)[0].trainIdx) // good Match
는 이제 꽤 좋은 경기가 남아있다. 좀 더 나쁜 성냥을 걸러 내려면 근본적인 모체를 사용하여 img2에 img1의 투영이 일치하는지 확인합니다.
std::vector<uchar> inliers(points1.size(),0);
cv::findFundamentalMat(
cv::Mat(points1),cv::Mat(points2), // matching points
inliers,
CV_FM_RANSAC,
3,
0.99);
std::vector<cv::DMatch> goodMatches
// extract the surviving (inliers) matches
std::vector<uchar>::const_iterator itIn= inliers.begin();
std::vector<cv::DMatch>::const_iterator itM= allMatches.begin();
// for all matches
for (;itIn!= inliers.end(); ++itIn, ++itM)
if (*itIn)
// it is a valid match
결과는 꽤 좋다. 그러나 극단적 인 alikeness 결함의 경우에는 여전히 발생합니다.
위의 그림에서 비슷한 벽돌이 잘 인식되어 있음을 알 수 있습니다.
그러나 두 번째 그림에서 잘못된 벽돌이 인식됩니다.
이제는 일치를 향상시킬 수있는 방법이 있습니다.
나는 두 개의 서로 다른 생각이 있었다 : 다시 정말 피팅 기능에 대한 두 번째 사진의 추적에성냥을하지만, 시야가 강렬하게 변경되는 경우에만 가능합니다. 벽돌을 인식하기 위해서는 어쨌든 (그림 3과 같이) 여러 다른 위치에서 비교해야합니다. 즉, 시각 필드를 최소한으로 변경할 수 있음을 알고 있습니다. 시야가 얼마나 강하게 변화하는지에 대한 정보는 기본 매트릭스에 숨겨져 있어야합니다. 이 매트릭스에서 방의 위치가 얼마나 바뀌 었는지 어떻게 알 수 있습니까?특히 회전과 강한 스케일링이 중요합니다. 벽돌이 한 번 왼쪽에 더 가볍게 찍혀 있다면 이것은 중요하지 않습니다.
두 번째 아이디어 :
내가이 사진에서 기본 행렬을 계산 돌기에 맞지 않는 기능 필터링 -이 세 개 이상의 사진을 사용하여 동일한 작업을 수행 할 수있는 방법 안을? (키워드 Trifocal tensor). 이 방법은 매칭이 더 안정적이어야합니다. 하지만 OpenCV를 사용하여이 작업을 수행하는 방법을 알지 못하거나이 정보를 Google에서 찾을 수 없었습니다.