OpenCV provides many tools for pattern recognition, including through contour analysis. In the third version of the framework, almost everything related to contour comparison was allocated to a separate module with the telling name Shape Distance and Matching .
The author of the question did not specify with which figures (sets of figures) the infinity sign will be compared, and noted only that only the fact of the candidate’s similarity to the desired object is of interest.
Obviously, by itself, the concept of "infinity" will not say anything to the machine, and therefore will have to offer it a certain image in the form of a reference. Let this image look like this ( model1.jpg file):

Meanwhile, in order to make sure that the method disclosed further allows us to distinguish other figures, we will add several more different images to the reference model ( model2.jpg , model3.jpg and model4.jpg files, respectively):



In fact, all images are the same size and are shown in a reduced form only to save space on the page.
We start by selecting the object whose image was provided by the author of the question:
cv::Mat tst_src_mat = cv::imread("test.jpg", cv::IMREAD_GRAYSCALE); if(tst_src_mat.empty()) return; cv::Mat tst_bin_mat; cv::threshold(tst_src_mat, tst_bin_mat, 0, 255 , cv::THRESH_OTSU | cv::THRESH_BINARY_INV);
After binarization, it turns out that in addition to the object of interest in the image in the lower left corner there is also an artifact:

It is possible to get rid of it through a simple and somewhat philosophical approach — to ignore, leaving only that outline in sight, which, on the contrary, is of interest. This can be done, for example, by focusing on the maximum area and the corresponding index in the vector:
std::vector<std::vector<cv::Point> > tst_cs; cv::findContours(tst_bin_mat.clone(), tst_cs , cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); int ci = -1; double max_area = 0.; for(int i = 0, n = tst_cs.size(); i < n; ++i) { const double area = cv::contourArea(tst_cs.at(i)); if(area > max_area) {max_area = area; ci = i;} } if(ci == -1) return;
This is followed by a nuance that implies that any contours being compared should have the same number of points in its composition. Of course, various figures usually will not follow such a rule, which means they will have to help them “on the handbrake” by simply adding the required number of points, but only with those coordinates that are already in the figure:
const int num_pts = 300; for(int i = tst_cs.at(ci).size()-1, d = 0; i < num_pts; ++i) tst_cs[ci].push_back(tst_cs[ci][d++]);
The constant num_pts is an arbitrary number. In principle, it depends on the complexity of the work. Ideally, it should be equal to the maximum number of points at the very uh-uh ... multi-point contour of the compared.
Perhaps it is time to move on to the previously reviewed benchmark and images that are very different from the test pieces:
// Герой настоящей статьи, который собственно // и будет производить сравнение контуров. cv::Ptr<cv::ShapeContextDistanceExtractor> sc = cv::createShapeContextDistanceExtractor(); for(int i = 0; i < 4; ++i) { std::string fname = std::string("model") + std::to_string(i+1) + std::string(".jpg"); cv::Mat src_mat = cv::imread(fname, cv::IMREAD_GRAYSCALE); if(src_mat.empty()) return -1; cv::Mat bin_mat; cv::threshold(src_mat, bin_mat, 0, 255 , cv::THRESH_OTSU | cv::THRESH_BINARY_INV); std::vector<std::vector<cv::Point> > cs; cv::findContours(bin_mat.clone(), cs , cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); for(int i = cs.at(0).size()-1, d = 0; i < num_pts; ++i) cs[0].push_back(cs[0][d++]); std::cout << fname << " - " << sc->computeDistance(tst_cs[ci], cs[0]) << std::endl; }
The result of the code will be the following values:
model1.jpg - 2.84489
model2.jpg - 112.033
model3.jpg - 32.8308
model4.jpg - 524.659
The image model1.jpg contains the infinity sign, and accordingly has the smallest distance differences with the test figure. Images with the sign "dogs" ( model2.jpg ) and "sickle with a hammer" ( model4.jpg ) in view of the obvious differences complete the list of dissimilarity. But who would have thought that the “Batman” ( model3.jpg ) will get second place here. And yet, if you look closely, it is quite possible to catch the features common to infinity.