# Orientation of two contours

I try to calculate the orientation of 2 contours. At the end i want to rotate one contour, so it is in cover with the other one. With my code I get a result, but it isn't that accurate. Also I get the same orientations although the contours is rotated around 90 degrees.

Here is my code:

   Moments moments_dxf;
Moments moments_img;

moments_dxf = moments( mcontours_dxf[ alargest_contour_index_dxf ], true );
double theta_dxf_outer = 0.5 * atan( ( 2 * moments_dxf_outer.mu11 ) / ( moments_dxf_outer.mu20 - moments_dxf_outer.mu02 ) );

moments_img = moments( mcontours_image[ alargest_contour_index_img ], true );
double theta_img_outer = 0.5 * atan( ( 2 * moments_img_outer.mu11 ) / ( moments_img_outer.mu20 - moments_img_outer.mu02 ) );


has anyone an idea?

edit retag close merge delete

A quick question, is your contour rectangular shaped?

( 2016-11-16 06:11:38 -0500 )edit

no they are not.

( 2016-11-16 07:52:18 -0500 )edit

so i get the rigth angle with:

double atheta_res = (( -atheta_dxf_outer + atheta_img_outer ) /2;


But I have to add an offset of either 0 or pi/2 or poi or 3/pi*2. I tried to match the shapes with

matchShapes(...);


for each angle + offset (I thougth I get the smalles value if the contour has the rigth orientation). But the function return the smallest value altough it's not the contour with the rigth offset. So does anyone has an idea to solve this???

( 2016-11-16 08:50:59 -0500 )edit

Sort by ยป oldest newest most voted

Hi! Here is my Simple Iterative based algorithm for comparing Two Contours! Here i have used only one shape image to demonstrate contour orientation comparison! Hope you will find this useful!

Here is the Sample Outputs:

Output : Angle: 0.000000 , Score: 0.018856

// OpenCV_Find_Contour_Orientation.cpp : Defines the entry point for the console application.

#include <opencv2\opencv.hpp>
#include "opencv2\core.hpp"
#include "opencv2/shape.hpp"

#include "opencv2\opencv_modules.hpp"
#include <iostream>
#include <conio.h>
#include <fstream>
#include <string.h>

#define NOMINMAX

using namespace cv;
using namespace std;

Point RotatePoint(const Mat &R, const Point &p)
{
Point2f rp;
rp.x = (float)(R.at<double>(0,0)*p.x + R.at<double>(0,1)*p.y + R.at<double>(0,2));
rp.y = (float)(R.at<double>(1,0)*p.x + R.at<double>(1,1)*p.y + R.at<double>(1,2));
return rp;
}

bool FindBlobs(Mat mI,vector<vector<Point>> &contours,vector<Point2f> &MassCentre,vector<float>&DiagonalLength)
{
if(mI.empty()||mI.depth()!=CV_8UC1)
{
cout<<"Invalid Input Image!";
return 0;
}

vector<Vec4i> hierarchy;
/// Find contours
findContours( mI, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0) );

vector<Rect> boundRect( contours.size() );
vector<Moments> mu(contours.size() );

for( size_t i = 0; i < contours.size(); i++ )
{
/// Find Minimum bounding Rect
boundRect[i] = boundingRect( Mat(contours[i]) );

/// Get the moments
mu[i] = moments( contours[i], false );

/// Find the Mass Centre
MassCentre.push_back(Point2f( static_cast<float>(mu[i].m10/mu[i].m00) , static_cast<float>(mu[i].m01/mu[i].m00) ));

//Find Distance between the TopLeft  and Bottrom Right Points
DiagonalLength.push_back((float)norm(boundRect[i].tl()-boundRect[i].br()));
}
return 1;
}

bool TransformContour(vector<vector<Point>> contours,vector<vector<Point>> &contours_Trans,Vec2f Translate)
{
if(contours.size()==0)
{
cout<<"Invalid input!";
return 0;
}

contours_Trans=contours;

for( size_t i = 0; i < contours.size(); i++ )
{
for (int idx = 0; idx < contours[i].size(); idx++)
{
contours_Trans[i][idx]=Point(contours[i][idx].x+ Translate(0),contours[i][idx].y+ Translate(1));
}
}
return 1;
}

bool RotateContour(vector<vector<Point>> contours,vector<vector<Point>> &contours_Rotated,double Angle,Point2f Centre)
{
if(contours.size()==0)
{
cout<<"Invalid input!";
return 0;
}

Mat mRot= getRotationMatrix2D(Centre,Angle,1.0);
contours_Rotated=contours;

for( size_t i = 0; i < contours.size(); i++ )
{
for (int idx = 0; idx < contours[i].size(); idx++)
{
contours_Rotated[i][idx]=RotatePoint(mRot,contours[i][idx]);
}
}
return 1;
}

static vector<Point> simpleContour( vector<vector<Point> > _contoursQuery, int n=300 )
{
vector <Point> contoursQuery;
for (size_t border=0; border<_contoursQuery.size(); border++)
{
for (size_t p=0; p<_contoursQuery[border].size(); p++)
{
contoursQuery.push_back( _contoursQuery[border][p] );
}
}

// In case actual number of points is less than n
int dummy=0;
{
}

// Uniformly sampling
random_shuffle(contoursQuery.begin(), contoursQuery.end());
vector<Point> cont;
for (int i=0; i<n; i++)
{
cont.push_back(contoursQuery[i]);
}
return cont;
}

int _tmain(int argc, _TCHAR* argv[])
{
string sFileName="OpenCV\\opencv-master\\samples\\data\\shape_sample\\6.png";
Mat mSrc;

if (mSrc.empty()) {
std::cerr << "[Error] imread() ...filename="<<sFileName ...
more

1

thank you very much for your great answer. I finally solved the problems with the Hu Moments. :-)

( 2016-11-18 07:10:25 -0500 )edit

Nice example. How about submitting it to the repo with some tutorial?

( 2017-08-10 04:38:48 -0500 )edit

Official site

GitHub

Wiki

Documentation