аватар question@mail.ru · 01.01.1970 03:00

Recognition of an infinity sign

"

n

how can I recognize the sign of infinity (namely by him) in the photo or video?

n

I will be grateful if you bring the code to the answer.

n

upd: Explain how, for example, to understand whether there is an infinity sign in the photograph (there may be a complete connection in the center, a person may be visible, he may be kept, the color is not kept. Important).

аватар question@mail.ru · 01.01.1970 03:00

"

OpenCV provides many tools for patte recognition, including through contour analysis. In the third version of the framework, almost everything related to contour comparison was isolated into a separate module with a telling name.

The author of the question did not specify which shapes (sets of shapes) the infinity sign would be compared with, and only noted that the only thing of interest is the fact that the candidate resembles the desired object.

Obviously, the concept of "infinity" in itself will not say anything to the machine, and therefore it will have to offer it some kind of image in the form of a standard. Let this image look like this ( filemodel1.jpg ):

Meanwhile, to make sure that the method described below allows us to distinguish between other shapes, we will add several more different images to the reference model ( filesmodel2.jpg , model3.jpg and model4.jpg respectively):

In fact, all the images are the same size and are reduced in size only to save space on the page.

Let's start by selecting an object, the image provided by the author of the question:

cv::Mat tst_src_mat = cv::imread(""test.jpg"", cv::IMREAD_GRAYSCALE);if(tst_src_mat.empty()) retu;cv>retu;cv::Mat tst_bin_mat;cv::threshold(tst_src_mat, tst_bin_mat, 0, 255    , cv::THRESH_OTSU | cv::THRESH_BINARY_INV)SH_BINARY_INV);

After the binarization, it will be, that in addition to the object of interest, there is also an artifact in the image in the lower left coer:

You can get rid of it by using a simple and somewhat philosophical approach - ignore it, leaving only the contour that is of interest in the field of view. 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_EXTEAL, cv::CHAIN_APPROX_SIMPLE);int ci = -1; double max_area =le 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) retu;

e>

This is followed by a nuance that implies that any contours being compared must have the same number of points in their composition. Of course, various shapes will not usually follow this rule, which means that you will have to help them with this by simply adding the necessary number of points, but only with the coordinates that are already available in the figure:

const int num_pts = 300;forn class="">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 figures to be worked with. Ideally, it should be equal to the maximum number of points at the uh itself... a multipoint contour from the compared ones.

Perhaps it's time to move on to the previously discussed reference and images of shapes that are very different from the test one:

// The hero of this article, who will make the contour comparison himself.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"");    cv::Mat src_mat = cv::imread(fname, cv::IMREAD_GRAYSCALE);    if(src_mat.empty()) retu - -1;    cv::Mat bin_mat;    cv::threshold(src_mat, bin_mat, 0, 255        , cv::THRE  , cv::THRESH_OTSU | cv::THRESH_BINARY_INV);    std::vector<std::vector<cv::Point> > cs;    cv::findContours(bin_mat.clone(), cs        , cv::RETR_EXTEAL, 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

Image model1.jpg contains a character infinity, and therefore has the smallest difference distance with the test figure. Images with the sign "dogs" (model2.jpg ) and "hammer and sickle" (model4.jpg ) in view of the obvious differences, they complete the list of dissimilarities. But who would have thought that "batman" (model3.jpg ) here you will get the second place. However, if you look closely, it is quite possible to catch common features with infinity.

"

Latest

Similar