Click here to Skip to main content
Licence CPOL
First Posted 10 Nov 2011
Views 6,134
Downloads 767
Bookmarked 25 times

Detect the angle of a line in an image

By | 10 Nov 2011 | Article
How to detect the angle of a line in an image.

Introduction

Today's image processing technology help us in many areas such as determining tumors, text extraction, checking images,... In this algorithm, we can get the angle of a line in an image. Of course there are several ways to do this and advances algorithms, but this is a simple algorithm.

Features

  • Works in real images with several colors.
  • Simple to implement.
  • Gets the length of the line.
  • Very light-weight code.

Source Code

I have commented the code clearly. First we must define a global CImage and then load the image file from hard disk:

CImage i;

After that, we need to draw an image when cleared with the OnPaint() function:

void CDetectangleoflineDlg::OnPaint()
{
  if(!i.IsNull()){//image isn't null
    //get handle device content from this dialog
	CClientDC dc(this);
	i.BitBlt(dc.m_hDC,0,0,SRCCOPY);
	//draw picture in dialog backgroun
  }
}

Next, we load the image:

void CDetectangleoflineDlg::OnBnClickedButton1()//load image
{
  CFileDialog f(1);//to call open file dialog
  TCHAR tc[260];CString s;GetCurrentDirectory(260,tc);s=tc;
  if(f.DoModal()==IDOK){//image selected
	if(!i.IsNull())//image isn't null
		i.Destroy();//destroy image
          i.Load(f.GetFolderPath()+_T("\\")+f.GetFileName());
          //load image to i (CImage)
	OnPaint();//call draw image
	b.EnableWindow(1);
  }
}

Finally, we use the Process algorithm to determine the angle:

void CDetectangleoflineDlg::OnBnClickedButton2()//process
{
	CImage i1;
	i1=i;//copy 'i' to 'i1'
	CDC cdc;//to get device content of 'i1'
	//get device content of i to cdc to draw or getbitmap
	cdc.Attach(i1.GetDC());
	//define pens and choose them in 'cdc'
	CPen p(PS_SOLID,1,RGB(255,255,0)),p1(PS_SOLID,1,RGB(0,0,255));
	cdc.SelectObject(&p);
	//define neccessary variables
	register int x1,x2,y1,y2;
	x1=x2=y1=y2=-1;
	double pi=3.1415926535;
	register long r,g,b,r1,g1,b1;
	register COLORREF c,c1;
	//'tol':toleranc;defference beetwen colors.
	//'d':the most width of line
	register int tol=30,d=20;
	//get first color as background color
	c=i1.GetPixel(0,0);r=GetRValue(c);g=GetGValue(c);b=GetBValue(c);
	for(register int y=0;y<i1.GetHeight();y++)//check all points in image
		for(register int x=0;x<i1.GetWidth();x++){
		    //get current point's color to compare
			c1=i1.GetPixel(x,y);r1=GetRValue(c1);
			g1=GetGValue(c1);b1=GetBValue(c1);

			if((abs(r-r1)>tol)&&(abs(g-g1)>tol)&&(abs(b-b1)>tol)){
			//line detect
				if(x1==-1){//first point of line
					x1=x2=x;y1=y2=y;
				}else if(sqrt(pow(x-x2,2.0)+pow(y-y2,2.0))<=d){
				 //next point
					x2=x;y2=y;
					cdc.SetPixel(x,y,RGB(255,255,0));
					//coloring line with yellow color
				}
			}
		}
    //compute line's length width: r^2=x^2+y^2
	register float radius=sqrt(pow(x1-x2,2.0)+pow(y1-y2,2.0));
	//end:to get angle of line
	float t=atan((float)(y2-y1)/(x2-x1))*180/pi;
	cdc.SelectObject(&p1);//set 'p1' for blue color
	//draw lines around Line
	cdc.MoveTo((x1+x2)/2-radius/2,(y1+y2)/2);
	cdc.LineTo((x1+x2)/2+radius/2,(y1+y2)/2);
	cdc.MoveTo((x1+x2)/2,(y1+y2)/2-radius/2);
	cdc.LineTo((x1+x2)/2,(y1+y2)/2+radius/2);
	CClientDC dc(this);//get device content of dialog to draw 'i1'
	if(t>=-180&&t<=180){//to skip error
	    //convert 't'int to 's'CString
		char a[10]="";itoa(t,a,10);CString s;s=a;
		dc.TextOut(0,300,s+_T(" degree"));
		//print the result
	}
	i1.ReleaseDC();
	cdc.Detach();
	i1.BitBlt(dc.m_hDC,i.GetWidth()+10,0,SRCCOPY);//draw 'i1'
	i1.Destroy();
}

Algorithm

First we need a color for the backcolor, 'c', and a color to get the points of the image, 'c1'. We have to find the first and last points of the line (x1,y1) and (x2,y2). We set -1 as the default value of x1. This means we don't find the first point yet. For detecting the first point, we move and look around the image at (x,y). When c1!=c && x==-1 we find (x1,y1). We imagine a virtual radius like 'd' and with a default value 10. After that we move and look again, and when c!=c && sqrt((x-x2)^2+(y-y2)^2))<=d, this point is related to the previous point and line. We continue this till the end. Finally, we'll find (x1,y2),(x2,y2) and we can get the length of the line and get the angle of the line with arctan.

teta=arttan((y2-y1)/(x2-x1))

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Mahdi Nejadsahebi



Iran (Islamic Republic Of) Iran (Islamic Republic Of)

Member

Have a Good Time
 
I'm college student in science computer.
i worked the visual basic 2006,visual c++ 2006,2008,2010,
and a bit delphi 2007,html,visual c#.
i like programming and i hope to become a really programmer in the world.
I like sport, specially karate.
 
always don't forget two things: 1st God ,2nd to Try
good luck,and god with you
 
e-mail: mahdiacuransx@yahoo.com

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralMy vote of 5 PinmemberMihai MOGA3:41 18 Dec '11  
GeneralRe: My vote of 5 PingroupMahdi Nejadsahebi4:47 24 Mar '12  
GeneralMy vote of 2 Pinmembernv322:08 15 Nov '11  
QuestionProblem in the sample OnPaint code PinmemberMukit, Ataul23:54 14 Nov '11  
AnswerRe: Problem in the sample OnPaint code PinmemberMukit, Ataul16:53 19 Nov '11  
GeneralRe: Problem in the sample OnPaint code PingroupMahdi Nejadsahebi4:50 24 Mar '12  
GeneralRe: Problem in the sample OnPaint code PinmemberMukit, Ataul16:27 24 Mar '12  
SuggestionFormatting concern PinmemberDavidCrow10:40 14 Nov '11  
GeneralRe: Formatting concern PingroupMahdi Nejadsahebi4:51 24 Mar '12  
GeneralMy vote of 5 PinmemberKanasz Robert22:54 10 Nov '11  
GeneralRe: My vote of 5 PingroupMahdi Nejadsahebi19:48 11 Nov '11  
GeneralMy vote of 5 PinmemberSergio Andrés Gutiérrez Rojas16:36 10 Nov '11  
GeneralRe: My vote of 5 PingroupMahdi Nejadsahebi19:51 11 Nov '11  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120517.1 | Last Updated 10 Nov 2011
Article Copyright 2011 by Mahdi Nejadsahebi
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid