0

I'm trying to use opencv to detect components in electronic diagrams photos. I am using ORB feature detector with BFMathcer.To detect the multiple occurences I'm using a sliding window approach for now. In my first test I tried to detect diodes on a circuit image, but end up with no key points detected on the diode template.

My first solution was to stretch the image before detecting key points, but I was getting poor matches.

Diode template

1

Circuit used

2

(Sorry about the links, can`t embed images...)

Is there a better way to extract key points? Or any other suggestions?

It would be good if the solution was scale/rotation invariant.

            cv::Mat template_img, capture;

            std::vector<cv::KeyPoint> mTemplate_key_points;
            cv::Mat mTemplate_descriptors;
            std::vector<cv::KeyPoint> key_pts;
            cv::Mat descriptors;

            auto ORB = cv::ORB::create(2000);
            ORB->detectAndCompute(template_img, cv::noArray(), mTemplate_key_points, mTemplate_descriptors);
            ORB->detectAndCompute(capture, cv::noArray(), key_pts, descriptors);

            cv::BFMatcher matcher(cv::NORM_HAMMING);
            std::vector< std::vector<cv::DMatch> > nn_matches;
            matcher.knnMatch(mTemplate_descriptors, descriptors, nn_matches,2);

            std::vector<cv::KeyPoint> matched1, matched2;
            float feature_distance =0;
            for (auto& descriptor_match: nn_matches)
            {
                float dist1 = descriptor_match[0].distance;
                float dist2 = descriptor_match[1].distance;
                feature_distance += dist2 -dist1;
                if(dist1 < 0.8f * dist2)
                {
                    matched1.push_back(mTemplate_key_points[descriptor_match[0].queryIdx]);
                    matched2.push_back(key_pts[descriptor_match[0].trainIdx]);
                }
            }

            std::vector<cv::Point2f> template_hom;
            for (auto pt : matched1)
            {
                template_hom.push_back(pt.pt);
            }
            std::vector<cv::Point2f> image_hom;
            for (auto pt : matched2)
            {
                image_hom.push_back(pt.pt);
            }

            auto my_homography = cv::findHomography(image_hom, template_hom);

            cv::Mat cuted_component;
            cv::warpPerspective(distorted, cuted_component, my_homography, cv::Size(300,300));
大陸北方網友
  • 3,696
  • 3
  • 12
  • 37
Giuliano
  • 1
  • 2
  • 3
    I'm not sure if key point matching is a good fit for black and white schematics. [`matchTemplate`](https://docs.opencv.org/master/de/da9/tutorial_template_matching.html) should work really well for stuff like this. The drawback for this method is that it is not rotationally invariant. So you'll have to create a separate template image for every orientation of diode you are likely to see. For sure, you'd want at least 4 orientations and maybe 8 if you allow 45 degree rotation. – bfris Sep 16 '20 at 03:06
  • *scale/rotation invariant* this is difficult – Yunus Temurlenk Sep 16 '20 at 05:09

0 Answers0