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

本文介绍了一种基于傅里叶变换图像特征的方法来检测最亮的直线。通过旋转图像并统计不同角度下直线的灰度累加值,找到累加值最大的直线作为目标直线,并进行了倾斜校正。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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; }


原图:



标注水平线和亮线的图:


旋转后:


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值