`
java-mans
  • 浏览: 11424147 次
文章分类
社区版块
存档分类
最新评论

付丽叶变换图求水平线的斜率

 
阅读更多

付丽叶变换后的图,主要特点是中间有两条十字线,一横一竖,可能还有其他的线,研究不深,暂不做评论。十字线中间是亮线。如何获取该亮线的方程呢?假定中心点在图的中心,根据直线方程:

y=kx+b (1)

直线过点P(w/2,h/2),代入公式(1)得:

b=(h-kw)/2 (2)

因此直线方程可表示为:

y = k(x - w/2) + h/2 (3)

绕点P旋转,旋转步长为0.1度,最大倾角45度,因此总步长为450,求每个步长对应的直线,统计该线上的点的灰度累加值。越白的像素,灰度值越大,累加值最大的线为所求直线。

//倾斜校正
void CBmptestApp::OnLeanAdjust(){
 char* sMax = new char[100];
 
 int w = objCDib->GetWidth();
 int h = objCDib->GetHeight();
 DWORD size = w * h;

 BYTE* img = objCDib->GetData();
 BYTE* ftImg = new BYTE[size];
 memcpy(ftImg,img,size);

 CDC* pDC = m_pMainWnd->GetDC();
 int s = 27; /*工具条高度*/

 double pi = 3.1415926;
 int count = 450; //每次旋转0.1度
 long lines[450];
 
 for(int i=0;i<450;i++){
  lines[i] = 0;
 }

 AfxMessageBox("here0"); 

 for(i=0;i<count;i++){
  for(int j=0;j<w/2;j++){
   int x = w/2 + j;
   int y = tan(0.1*i*pi/180) * (x-w/2) + h/2;
   lines[i] += ftImg[w*y +x];
  }
 }

 AfxMessageBox("here1"); 

 int maxV = 0;
 int maxIdx = 0;
 for(i=0;i<count;i++){
  if(lines[i] > maxV){
   maxV = lines[i];
   maxIdx = i;
  }
 }


 sprintf(sMax,"maxV=%d,maxIdx=%d", maxV, maxIdx);
 AfxMessageBox(sMax); 
 delete[] sMax;


 //标识倾斜线
 int h0 = h/2 + w/2 * tan(0.1*maxIdx*pi/180) + s;
 CPen* pPen = new CPen;
 pPen->CreatePen(PS_SOLID,2,RGB(255,0,0));   
 // 选中新画笔
 CGdiObject* pOldPen = pDC->SelectObject(pPen);

 pDC->MoveTo(0,0);
 pDC->LineTo(w,0);

 pDC->MoveTo(0,s);
 pDC->LineTo(w,s);

 pDC->MoveTo(w/2,h/2+s);
 pDC->LineTo(w,h0);

 pDC->MoveTo(w/2,h/2+s);
 pDC->LineTo(w,h/2+s);

 // 选回以前的画笔
 pDC->SelectObject(pOldPen);
 delete pPen;

 //旋转图片
 BYTE* newImg =new BYTE[size];
 rotateImage(ftImg, w, h, newImg, w, h, -0.1*maxIdx);
 int rv = ShowGrayImg(pDC,3,s,newImg,w,h,NULL,NULL);
 delete[] ftImg;
}


原图:



标注水平线和亮线的图:


旋转后:


这只是一个简单的测试,仅仅根据图像的特征来求的直线,实际上是说:最亮的一条线怎么得到?

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics