Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 多模板匹配,使用ORB检测电子元件_C++_Opencv_Image Processing_Computer Vision_Template Matching - Fatal编程技术网

C++ 多模板匹配,使用ORB检测电子元件

C++ 多模板匹配,使用ORB检测电子元件,c++,opencv,image-processing,computer-vision,template-matching,C++,Opencv,Image Processing,Computer Vision,Template Matching,我正在尝试使用opencv检测电子图表和照片中的组件。我正在使用带有BFMathcer的ORB特征检测器。为了检测多个事件,我现在正在使用滑动窗口方法。 在我的第一次测试中,我尝试在电路图像上检测二极管,但最终没有在二极管模板上检测到关键点 我的第一个解决方案是在检测关键点之前拉伸图像,但我得到的匹配结果很差 二极管模板 使用的电路 (很抱歉链接,无法嵌入图像…) 是否有更好的方法提取关键点? 还有其他建议吗 如果解决方案是缩放/旋转不变的,那就好了 cv::Mat

我正在尝试使用opencv检测电子图表和照片中的组件。我正在使用带有BFMathcer的ORB特征检测器。为了检测多个事件,我现在正在使用滑动窗口方法。 在我的第一次测试中,我尝试在电路图像上检测二极管,但最终没有在二极管模板上检测到关键点

我的第一个解决方案是在检测关键点之前拉伸图像,但我得到的匹配结果很差

二极管模板

使用的电路

(很抱歉链接,无法嵌入图像…)

是否有更好的方法提取关键点? 还有其他建议吗

如果解决方案是缩放/旋转不变的,那就好了

            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));
cv::Mat template\u img,捕获;
std::向量模板关键点;
cv::Mat mTemplate_描述符;
std::向量密钥;
cv::Mat描述符;
自动ORB=cv::ORB::create(2000);
ORB->detectAndCompute(模板、cv::noArray()、mTemplate\u关键点、mTemplate\u描述符);
ORB->detectAndCompute(捕获,cv::noArray(),关键点,描述符);
cv::BFMatcher matcher(cv::NORM_HAMMING);
std::vectornn_匹配;
knnMatch(mTemplate_描述符,描述符,nn_匹配,2);
std::向量匹配1,匹配2;
浮动特性_距离=0;
用于(自动和描述符匹配:nn\u匹配)
{
float dist1=描述符匹配[0]。距离;
float dist2=描述符匹配[1]。距离;
特征距离+=dist2-dist1;
如果(距离1<0.8f*2)
{
matched1.push_back(mTemplate_key_points[descriptor_match[0].queryIdx]);
matched2.push_back(键值[descriptor_match[0].trainIdx]);
}
}
std::向量模板;
用于(自动pt:matched1)
{
模板向后推(pt.pt);
}
std::矢量图像;
用于(自动pt:matched2)
{
图像向后推(pt.pt);
}
自动my_单纯形=cv::FindHome(图像、模板);
cv::垫切_组件;
cv::warpPerspective(扭曲、剪切的_组件、my_单应性、cv::Size(300300));

我不确定关键点匹配是否适合黑白示意图。这样的东西应该很好用。这种方法的缺点是它不是旋转不变的。因此,您必须为可能看到的每个方向的二极管创建单独的模板图像。当然,你至少需要4个方向,如果允许45度旋转,可能需要8个方向。缩放/旋转不变性这很难