Ask Your Question
2

Orientation of two contours

asked 2016-11-16 04:27:30 -0600

stan123 gravatar image

updated 2020-12-05 11:54:05 -0600

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 flag offensive close merge delete

Comments

A quick question, is your contour rectangular shaped?

StevenPuttemans gravatar imageStevenPuttemans ( 2016-11-16 06:11:38 -0600 )edit

no they are not.

stan123 gravatar imagestan123 ( 2016-11-16 07:52:18 -0600 )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???

stan123 gravatar imagestan123 ( 2016-11-16 08:50:59 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
6

answered 2016-11-18 05:12:49 -0600

updated 2017-08-09 08:27:43 -0600

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

image description image description image description image description

// 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;
    for (int add=(int)contoursQuery.size()-1; add<n; add++)
    {
        contoursQuery.push_back(contoursQuery[dummy++]); //adding dummy values
    }

    // 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;   
    mSrc= imread(sFileName,0);

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

Comments

1

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

stan123 gravatar imagestan123 ( 2016-11-18 07:10:25 -0600 )edit

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

StevenPuttemans gravatar imageStevenPuttemans ( 2017-08-10 04:38:48 -0600 )edit

Opencv2 does not have Shape.hpp or shape folder

mrid gravatar imagemrid ( 2019-12-19 05:22:12 -0600 )edit

Question Tools

3 followers

Stats

Asked: 2016-11-16 04:27:30 -0600

Seen: 6,568 times

Last updated: Aug 09 '17