First time here? Check out the FAQ!

Ask Your Question
1

Template matching: find rotation of object on scene.

asked Dec 5 '17

michlvl gravatar image

updated Dec 6 '17

Hi,

I'm trying to detect some objects on scene and find angles of rotation relative to the axis.

Let me show more detailed.

I have got pictures from camera, something like this (there are some electronic components, they may be mixed and rotated in random way):

image description

I tried to use template matching. I used next image as template:

image description

After processing I got next result (with some drawings over it):

image description

How can I detect that one of them is rotated for 180 degrees?

I'm using template match tutorial as basic. Here is how image looks like after template matching (CV_TM_SQDIFF_NORMED): image description

Not sure that it is possible to say where is top side or bottom for mathched regions... Maybe I'm moving in wrong way and I need to use another algoritm?

One more thing: image description

As you can see, when objet is rotated at 90 degree, it is harder to find maching (even with normalization): image description

UPDATE

Here is what I want to get in final: image description

As I see in case I can find rotation - I can automatically find top of component (I want to make remark, that It may be ok to use color detection for fat brown strip on top of this component, but others (like two black diodes with 3 and 5 pins) may not be detectable by this way, so I'm pretty sure that I need use some kind of template here anyway).

here is code:

main:

int main(int argc, char** argv)
{
    Mat image_input, component_template;

    VideoCapture cap(0);
    cap >> image_input;

    //Mat image_input = imread("d:\\SRC.jpg");
    component_template = imread("d:\\TMP.jpg");

    vector<Point> match_centers = imageComparation(component_template, image_input, CV_TM_SQDIFF_NORMED, 0.9);
    drawMatch(component_template, image_input, match_centers);

    imshow("result", image_input);
    waitKey(0);
    return 0;
}

compare image function:

vector<point> imageComparation(Mat object, Mat scene, int match_method, float peek_percent) { Mat img_display; scene.copyTo(img_display);

// Create the result matrix
int result_cols = scene.cols - object.cols + 1;
int result_rows = scene.rows - object.rows + 1;

Mat result(result_cols, result_rows, CV_32FC1);

// match scene with template
matchTemplate(scene, object, result, match_method);
imshow("matched_template", result);

//normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());
normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());
imshow("normalized", result);

// Localizing the best match with minMaxLoc
double minVal; double maxVal; Point minLoc; Point maxLoc;
Point matchLoc;

// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better
if (match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED)
{
    matchLoc = minLoc;
    //threshold(result, result, 0.1, 1, CV_THRESH_BINARY_INV);
    threshold(result, result, 0.1, 1, CV_THRESH_BINARY_INV);
    imshow("threshold_1", result);
}
else
{
    matchLoc = maxLoc;
    threshold(result, result, 0.9, 1, CV_THRESH_TOZERO);
    imshow("threshold_2", result);
}

vector<Point> res;
maxVal = 1.f;
while (maxVal > peek_percent)
{
    minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());
    if (maxVal > peek_percent)
    {
        rectangle(result, Point(maxLoc.x - object.cols / 2, maxLoc.y - object.rows / 2), Point(maxLoc.x + object.cols / 2, maxLoc.y + object.rows / 2), Scalar::all(0), -1);
        res.push_back(maxLoc);
    }
}

return res;

}

drawing stuff:

void drawMatch(Mat object, Mat scene, vector<point> match_centers) {

for (size_t i = 0; i < match_centers ...
(more)
Preview: (hide)

Comments

1

why not build a cascade approach

  • start with a template matcher over different orientations, then warping back the result
  • then on the retrieved contour, test if the upper part is reddish or not (helps you define if the object is turned or not)

finding an all in one solutions is in most cases the worst approach

StevenPuttemans gravatar imageStevenPuttemans (Jan 15 '18)edit

1 answer

Sort by » oldest newest most voted
3

answered Dec 5 '17

LBerger gravatar image

I don't think that's possible using template matching.

You can use descriptors (ORB,SIFT, ....) and try to match shape : tutorial here

you can try fourier-mellin transform too

Preview: (hide)

Question Tools

1 follower

Stats

Asked: Dec 5 '17

Seen: 29,992 times

Last updated: Dec 06 '17