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()){ CClientDC dc(this);
i.BitBlt(dc.m_hDC,0,0,SRCCOPY);
}
}
Next, we load the image:
void CDetectangleoflineDlg::OnBnClickedButton1(){
CFileDialog f(1); TCHAR tc[260];CString s;GetCurrentDirectory(260,tc);s=tc;
if(f.DoModal()==IDOK){ if(!i.IsNull()) i.Destroy(); 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(){
CImage i1;
i1=i; CDC cdc; cdc.Attach(i1.GetDC());
CPen p(PS_SOLID,1,RGB(255,255,0)),p1(PS_SOLID,1,RGB(0,0,255));
cdc.SelectObject(&p);
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;
register int tol=30,d=20;
c=i1.GetPixel(0,0);r=GetRValue(c);g=GetGValue(c);b=GetBValue(c);
for(register int y=0;y<i1.GetHeight();y++) for(register int x=0;x<i1.GetWidth();x++){
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)){
if(x1==-1){ x1=x2=x;y1=y2=y;
}else if(sqrt(pow(x-x2,2.0)+pow(y-y2,2.0))<=d){
x2=x;y2=y;
cdc.SetPixel(x,y,RGB(255,255,0));
}
}
}
register float radius=sqrt(pow(x1-x2,2.0)+pow(y1-y2,2.0));
float t=atan((float)(y2-y1)/(x2-x1))*180/pi;
cdc.SelectObject(&p1); 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); if(t>=-180&&t<=180){ char a[10]="";itoa(t,a,10);CString s;s=a;
dc.TextOut(0,300,s+_T(" degree"));
}
i1.ReleaseDC();
cdc.Detach();
i1.BitBlt(dc.m_hDC,i.GetWidth()+10,0,SRCCOPY); 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))