Hi there,
I making logo detection program that uses the SIFT method to detect a logo on image. The latest version of code version is
#include <core.hpp>
#include <highgui.hpp>
#include <imgproc.hpp>
#include <cv.hpp>
#include <imgcodecs.hpp>
#include <xfeatures2d.hpp>
#include <vector>
using namespace cv;
using namespace cv::xfeatures2d;
using std::vector;
vector<Mat> images, templates;
Mat temf = imread("C://DataSet_pic//reference//LEGO_logo.jpg"),
teml = imread("C://DataSet_pic//reference//logo-blend-a-med.png");
Mat detectLogo(const Mat &source, const Mat &template_)
{
Ptr<Feature2D> sift = SIFT::create();
vector<KeyPoint> keypoints_s, keypoints_t;
Mat descriptors_s, descriptors_t;
sift->detect(source, keypoints_s);
sift->detect(template_, keypoints_t);
sift->compute(source, keypoints_s, descriptors_s);
sift->compute(template_, keypoints_t, descriptors_t);
BFMatcher matcher;
vector<vector<DMatch>> matches;
matcher.knnMatch(descriptors_t, descriptors_s, matches, 2);
vector<DMatch> good_matches;
for(vector<DMatch> vdm : matches)
for(DMatch dm : vdm)
if(vdm.data()->distance < dm.distance / 2)
good_matches.push_back(*(vdm.data()));
Mat img_matches;
if(good_matches.empty())
return img_matches;
drawMatches(template_, keypoints_t, source, keypoints_s,
good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
vector<Point2f> templt, scene;
for(unsigned int i = 0; i < good_matches.size(); i++)
{
templt.push_back( keypoints_t[ good_matches[i].queryIdx ].pt );
scene.push_back( keypoints_s[ good_matches[i].trainIdx ].pt );
}
if(templt.size() < 4 || scene.size() < 4)
{
img_matches.release();
return img_matches;
}
Mat homogr = findHomography(templt, scene, CV_RANSAC);
vector<Point2f> templ_corners(4);
templ_corners[0] = cvPoint(0,0);
templ_corners[1] = cvPoint(template_.cols, 0);
templ_corners[2] = cvPoint(template_.cols, template_.rows);
templ_corners[3] = cvPoint(0, template_.rows);
vector<Point2f> scene_corners(4);
perspectiveTransform(templ_corners, scene_corners, homogr);
Point p1 = scene_corners[0] + Point2f( template_.cols, 0),
p2 = scene_corners[1] + Point2f( template_.cols, 0),
p3 = scene_corners[2] + Point2f( template_.cols, 0),
p4 = scene_corners[3] + Point2f( template_.cols, 0);
line( img_matches, p1, p2, Scalar(0, 255, 0), 4 );
line( img_matches, p2, p3, Scalar( 0, 255, 0), 4 );
line( img_matches, p3, p4, Scalar( 0, 255, 0), 4 );
line( img_matches, p4, p1, Scalar( 0, 255, 0), 4 );
return img_matches;
}
void showFirstLogoMatch()
{
imshow("Logo detection", detectLogo(images[0], temf));
}
void showLastLogoMatch()
{
imshow("Logo detection", detectLogo(images[images.size()-1], teml));
}
void showLogoMatch(unsigned short int index)
{
Mat image = images[index];
Mat img = image.clone();
if(img.size().width == 1280 && img.size().height == 720)
{
Rect roi(Point(img.size().width / 2 - img.size().width / 4 + 50, img.size().height),
Point(img.size().width / 2 + img.size().width / 4 + 50, 0));
Mat image_(img, roi);
img = image_;
}
else if(img.size().width >= 500 && img.size().height >= 370)
resize(img, img, Size(), 0.5, 0.5);
for(Mat mat : templates)
{
if( (mat.size().width >= 1280 || mat.size().width >= 324) && mat.size().height >= 324)
resize(mat, mat, Size(), 0.5, 0.5);
Mat logo = detectLogo(img, mat);
if(logo.empty())
continue;
else
{
imshow("Logo detection", logo);
waitKey(0);
}
}
}
int main()
{
vector<String> paths, paths_t;
String folder = "C://DataSet_pic//", folder_t = "C://DataSet_pic//reference//";
glob(folder, paths);
glob(folder_t, paths_t);
for(String str : paths)
images.push_back(imread(str));
for(String str : paths_t)
templates.push_back(imread(str));
unsigned int index = 0;
resize(temf, temf, Size(), 0.1667, 0.1667);
resize(images[0], images[0], Size(), 3, 3);
showFirstLogoMatch();
resize(teml, teml, Size(), 0.5, 0.5);
resize(images[images.size()-1], images[images.size()-1], Size(), 0.333, 0.333);
//imshow("image", images[0]);
while(1)
{
char key = waitKey(0);
if(key == '1')
showFirstLogoMatch();
if(key == '/')
showLastLogoMatch();
if(key == '+')
{
index++;
showLogoMatch(index);
//imshow("image", images[index]);
}
if(key == '-')
{
index--;
showLogoMatch(index);
//imshow("image", images[index]);
}
if(index == 0)
{
showFirstLogoMatch();
index++;
}
if(index == images.size()-1)
{
showLastLogoMatch();
index--;
}
if(key == 27)
break;
}
destroyAllWindows();
return 0;
}
The folder with source images and logos("references" folder) is
here. When I scrolling results of drawmatches(), program falling on image "13380-sony.jpg" with text in console: "OpenCV Error: Assertion failed (scn + 1 == m.cols) in perspectiveTransform, file "my_opencv_dir"\sources\modules\core\src\matmul.cpp, line 2125
terminate called after throwing an instance of 'cv::Exception'
what(): "opencv_dir"...\matmul.cpp:2125: error: (-215) scn + 1 == m.cols in function perspectiveTransform".
What could be the problem? And how a source code could be optimized?
P.S. Sorry my English.
P.P.S. I am beginner in OpenCV.