Ask Your Question

How to find the rotated angle of object

asked 2015-10-30 02:09:22 -0600

prakash gravatar image

updated 2015-11-23 09:02:04 -0600

I am using the homographythis tutorial for pattern matching. It is working but i need to find the degree of rotation of that object in scene. See the template image and scene image with output . I need to find the angle based on template.

edit retag flag offensive close merge delete


What do you mean by rotation? in plan (which one?), in space?

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-10-30 03:11:07 -0600 )edit

Ok. I am having two images one is template and another is scene which captured from webcam. While i am doing the surf detection it finds the match. but i need to detect the angle of rotation in the scene with respect to the template

prakash gravatar imageprakash ( 2015-10-30 03:50:30 -0600 )edit

So, I am asking you again, what angle do you need: in the plane of the photo?

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-10-30 06:21:13 -0600 )edit

See the template image and scene image with output . I need
to find the angle based on template.

prakash gravatar imageprakash ( 2015-10-30 09:19:46 -0600 )edit

so, you got the homography matrix, and can apply Rodrigues() on it, to get the euler angles.

but think of it, there will be 3 angles involved, not one.

berak gravatar imageberak ( 2015-11-01 01:09:37 -0600 )edit

I'm pretty new on openCV and I'm using python, does anyone have a python syntax for it?

CVictory gravatar imageCVictory ( 2020-08-20 05:25:58 -0600 )edit
LBerger gravatar imageLBerger ( 2020-08-22 09:28:04 -0600 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2015-11-07 13:38:37 -0600

LBerger gravatar image

updated 2016-05-29 12:24:18 -0600

I have changed your image to write my program because i don't need rectangle. only shape object is needed.

Image is image description

program is based on this paper (appendix)

#include <opencv2/opencv.hpp> 
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <fstream>

using namespace cv;
using namespace std;
class MatchDescriptor {
public :
    vector<Point2d> sContour;
    vector<complex<float> > b;
    vector<complex<float> > a;
    vector<float> frequence;
    vector<float> rho,psi;
    double pi;
    int nbDesFit;

public :
    float AjustementRtSafe(vector<Point2d> &c,float &alphaMin,float &phiMin,float &sMin);
    float Ajustement(vector<Point2d> &c,float &alphaMin,float &phiMin,float &sMin);
    void falpha(float x,float *fn,float *df);
    void InitFrequence();
    float rtsafe(float x1,float x2,float xacc);
    float Distance(complex<float> r,float alpha)
    long            i;
    complex<float>      j(0,1);
    float       d=0;

    for (i=1;i<=nbDesFit;i++)
        d += abs(a[i]-b[i]*r*exp(j*float(alpha*frequence[i])))+ abs(a[a.size()-i]-b[a.size()-i]*r*exp(j*float(alpha*frequence[a.size()-i])));
    return d;


void MatchDescriptor::InitFrequence()
long i;
int nbElt=sContour.size();

for (i=0;i<=nbElt/2;i++)
    frequence[i] = 2*pi*(float)i/nbElt;
for (i=nbElt/2+1;i<nbElt;i++)
    frequence[i] = 2*pi*(float)(i-nbElt)/nbElt;

void MatchDescriptor::falpha(float x,float *fn,float *df)
long    n,nbElt = sContour.size();
float   s1=0,s2=0,s3=0,s4=0;
float   ds1=0,ds2=0,ds3=0,ds4=0;

for (n=1;n<=nbDesFit;n++)
    s1 +=   rho[n] * sin(psi[n]+frequence[n]*x) + 
            rho[nbElt-n] * sin(psi[nbElt-n]+frequence[nbElt-n]*x);
    s2 +=   frequence[n] * rho[n] * cos(psi[n]+frequence[n]*x) +
            frequence[nbElt-n] * rho[nbElt-n] * cos(psi[nbElt-n]+frequence[nbElt-n]*x);
    s3 +=   rho[n] * cos(psi[n]+frequence[n]*x) +
            rho[nbElt-n] * cos(psi[nbElt-n]+frequence[nbElt-n]*x);
    s4 +=   frequence[n] * rho[n] * sin(psi[n]+frequence[n]*x) +
            frequence[nbElt-n] * rho[nbElt-n] * sin(psi[nbElt-n]+frequence[nbElt-n]*x);
    ds1 +=  frequence[n]*rho[n] * cos(psi[n]+frequence[n]*x) +
            frequence[nbElt-n]*rho[nbElt-n] * cos(psi[nbElt-n]+frequence[nbElt-n]*x);
    ds2 +=  -frequence[n]*frequence[n] * rho[n] * sin(psi[n]+frequence[n]*x) - 
            frequence[nbElt-n]*frequence[nbElt-n] * rho[nbElt-n] * sin(psi[nbElt-n]+frequence[nbElt-n]*x);
    ds3 +=  -frequence[n]*rho[n] * sin(psi[n]+frequence[n]*x) -
            frequence[nbElt-n]*rho[nbElt-n] * sin(psi[nbElt-n]+frequence[nbElt-n]*x);
    ds4 +=  frequence[n]*frequence[n] * rho[n] * cos(psi[n]+frequence[n]*x) +
            frequence[nbElt-n]*frequence[nbElt-n] * rho[nbElt-n] * cos(psi[nbElt-n]+frequence[nbElt-n]*x);
*fn = s1 * s2 - s3 *s4;
*df = ds1 * s2 + s1 * ds2 - ds3 * s4 -  s3 * ds4;

float MatchDescriptor::AjustementRtSafe(vector<Point2d> &c,float &alphaMin,float &phiMin,float &sMin)
long            n,nbElt = sContour.size();
float           s1,s2,sign1,sign2,df,x1=nbElt,x2=nbElt,dx;
float           dist,distMin = 10000,alpha,s,phi;
complex<float>  j(0,1),zz;


b.resize(nbElt ...
edit flag offensive delete link more


Nice code @LBerger. Thank you for posting it !


My compiler complains about:

  • the line: alpha = alpha; (should be line 131)
  • I had to explicitly cast to double the line: Point2d p = Point2d(c[i % c.size()]) + d * (s - l1) / (l2 - l1); but I think that it is because I use an old version of OpenCV (2.4.9)
Eduardo gravatar imageEduardo ( 2015-11-07 15:01:28 -0600 )edit

thanks @Eduardo I have comment line alpha and I use VS2013 with opencv 3.0 i have posted this code with many compilers warnnings

I must say that AjustementRtSafe is a numercial recipes function to solve an equation using a newton raphson method

LBerger gravatar imageLBerger ( 2015-11-07 15:22:20 -0600 )edit

happy to know that's somebody use this code.

MAXIT : as it is written some code i have used come from NRC. That's case here see page 366.

nbDesFit : a contour of N point give you N terms in FFT. if you want to fit two curves (shapes) very often you don't need N terms nbDesFit is enough. Example 512 points give you 512 terms in FFT and to fit with other shapes very often 5 terms in FFT give you a very good fit.

becarefull a contour x is a complex signal not a real signal. Hence in FFT X of x X(n)<>conjugate(X(-n))

LBerger gravatar imageLBerger ( 2016-02-15 02:20:07 -0600 )edit

The link of the paper is down , here it's the name of the paper "Shape Discrimination Using Fourier Descrptors" by ERIC PERSOON, and others , and here its another link Paper link

essamzaky gravatar imageessamzaky ( 2016-03-22 11:15:39 -0600 )edit

What does the following line perform? vector<point2d> c = ReSampleContour(contours[ctrSelec[i]],1024); Why 1024? Has anyone understood it?

bob409 gravatar imagebob409 ( 2016-04-04 01:04:32 -0600 )edit

To match contour using fourier descriptors all contours must have same number of points. You can choose 1024 or any values. This value musn't destroy your shape...(At the end your contour will have N points)

LBerger gravatar imageLBerger ( 2016-04-04 01:56:34 -0600 )edit

What should be taken into consideration while choosing a value? Why have u chosen 1024, was it derived by experimental result? And where do u get the fourier descriptors in the code above? Have u made them scale and starting point invariant? If yes where?

bob409 gravatar imagebob409 ( 2016-04-04 02:20:15 -0600 )edit

Fourier descriptor :dft(z[i],Z[i],DFT_SCALE|DFT_REAL_OUTPUT);

Program results are scale, rotation and phase shift to apply to each contour to have best match between contour( least square methods)

LBerger gravatar imageLBerger ( 2016-04-04 02:26:15 -0600 )edit

I dnt nid fourier descriptor which are rotational invariant they just need to be translation and scale invariant. It means that u have 1024 fourier descriptors

bob409 gravatar imagebob409 ( 2016-04-04 02:37:51 -0600 )edit

I have read quickly your link. Program try to find transformation (translation scale and rotation) minimizing least square error. It is not like in your link. I think there a database of traffic sign using fourier descriptor with . zero dc-component and fixed energy and used algorithm in described p27-29.

LBerger gravatar imageLBerger ( 2016-05-28 05:07:26 -0600 )edit

Question Tools



Asked: 2015-10-30 02:09:22 -0600

Seen: 16,440 times

Last updated: May 29 '16