霍夫变换

      霍夫变换,关于理论就不说了。我这里用到它的边缘点的连接。下面给出了代码的实现,本次代码因为时间的原因,写得很不规范。cpp文件如下:

// HoughTransform.cpp: implementation of the CHoughTransform class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MyDIP.h" #include "HoughTransform.h" #include "math.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CHoughTransform::CHoughTransform() { m_nLineAngleMix=-90; //直线角度的范围 m_nLineAngleMax=90; m_nLineDistMix=-256; //直线距离的范围 m_nLineDistMax=256; m_nLineAngleNum=36; //步长的个数 int nStart=m_nLineAngleMix; int nStep=(m_nLineAngleMax-m_nLineAngleMix)/m_nLineAngleNum; //步长数 for(int i=0;i-10&&nLineAngle<10) {//如果夹角为零,说明是平行于Y方向的一条直线 p1.x=nXMin; p1.y=nYMin; p2.x=nXMin; p2.y=nYMax; } else if(nLineAngle<-80||nLineAngle>80) { p1.x=nXMin; p1.y=nYMin; p2.x=nXMax; p2.y=nYMin; } else { p1.x=nXMin; p1.y=(long)((nLineDist-p1.x*cos(nLineAngle*PI/180))/sin(nLineAngle*PI/180)); if(p1.y>nYMax||p1.ynYMax||p2.ynYMax) p2.y=nYMax; else p2.y=nYMin; if(nLineAngle==90||nLineAngle==-90) p2.x=nXMax; else p2.x=(long)((nLineDist-p2.y*sin(nLineAngle*PI/180))/cos(nLineAngle*PI/180)); } } //对p1,p2放到图的中央 /* p1.x+=128; p1.y+=128; p2.x+=128; p2.y+=128; */ //画线p1,p2 dc.SetROP2(R2_BLACK); dc.MoveTo(p1); dc.LineTo(p2); } //对于每个点计算累加器计数 void CHoughTransform::ComputeAddCount() { double nDist1=0,nDist2=0; memset(m_nFinalLineAngle,0,LINENUMBER*sizeof(int)); memset(m_nFinalLineDist,0,LINENUMBER*sizeof(int)); memset(m_nFinalLineX1,0,LINENUMBER*sizeof(int)); memset(m_nFinalLineX2,0,LINENUMBER*sizeof(int)); memset(m_nFinalLineY1,0,LINENUMBER*sizeof(int)); memset(m_nFinalLineY2,0,LINENUMBER*sizeof(int)); for(int m=0;m=m_nLineDist1[k]&&nDist1=m_nLineDist1[k]&&nDist2m_PCoord[i].x) m_nLineX1[j][k]=m_PCoord[i].x; if(m_nLineX2[j][k]m_PCoord[i].y) m_nLineY1[j][k]=m_PCoord[i].y; if(m_nLineY2[j][k].h文件如下:// HoughTransform.h: interface for the CHoughTransform class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_HOUGHTRANSFORM_H__E7DC2F17_13C5_49C9_9522_F4F69EEF9D3D__INCLUDED_) #define AFX_HOUGHTRANSFORM_H__E7DC2F17_13C5_49C9_9522_F4F69EEF9D3D__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 /********************************************** *类名:霍夫变换 *目的:连接离散点实现边缘 *作者:无忧狂澜 *日期:2010-01-29 **********************************************/ #define LINENUMBER 100 //直线的个数 #define POINTNUMBER 500 //边缘点的个数 #define PI 3.1415926 class CHoughTransform { public: CHoughTransform(); virtual ~CHoughTransform(); private: int m_nPointNum; //图中点的个数(灰度为0) CPoint m_PCoord[POINTNUMBER]; //点的坐标 //int m_nAddNum; //累加器的个数.对应的是直线步进的个数 //int m_nLineAngle[LINENUMBER]; //直线的标准式 //int m_nLineDist[LINENUMBER]; int m_nLineAngleMix; //直线角度的范围 int m_nLineAngleMax; int m_nLineDistMix; //直线距离的范围 int m_nLineDistMax; int m_nAddCount[LINENUMBER][LINENUMBER]; //累加器计数 int m_nLineAngleNum; //步长的个数 int m_nLineAngle1[LINENUMBER]; //每个步长所对应的范围 int m_nLineAngle2[LINENUMBER]; int m_nLineAngleM[LINENUMBER]; //每个步长对应的中点 int m_nLineDistNum; //步长的个数 int m_nLineDist1[LINENUMBER]; int m_nLineDist2[LINENUMBER]; int m_nLineDistM[LINENUMBER]; int m_nLineX1[LINENUMBER][LINENUMBER]; //线段的边界点 int m_nLineX2[LINENUMBER][LINENUMBER]; int m_nLineY1[LINENUMBER][LINENUMBER]; //线段的边界点 int m_nLineY2[LINENUMBER][LINENUMBER]; //int m_nAddThresh; //累加器的阈值 int m_nAddNum; //取几个累加器 int m_nFinalLineAngle[LINENUMBER]; //最终连接好的直线 int m_nFinalLineDist[LINENUMBER]; int m_nFinalLineX1[LINENUMBER]; //线段的边界点 int m_nFinalLineX2[LINENUMBER]; int m_nFinalLineY1[LINENUMBER]; //线段的边界点 int m_nFinalLineY2[LINENUMBER]; /* int m_nFinalLineNum; //最终得到的直线的个数 int m_nFinalLineAngle[LINENUMBER]; //直线的标准式 int m_nFinalLineDist[LINENUMBER]; */ public: int GetPointNum() {return m_nPointNum;} void SetPointNum(int nPointNum) {m_nPointNum=nPointNum;} void SetCoordinate(int nPointNum,CPoint p[]); //设置坐标点 /* int GetAddNum() {return m_nAddNum;} void SetAddNum(int AddNum) {m_nAddNum=AddNum;} int GetLineAngle(int nLineIndex) {return m_nLineAngle[nLineIndex];} void SetLineAngle(int nLineIndex,int nLineAngle) {m_nLineAngle[nLineIndex]=nLineAngle;} int GetLineDist(int nLineIndex) {return m_nLineDist[nLineIndex];} void SetLineDist(int nLineIndex,int nLineDist) {m_nLineDist[nLineIndex]=nLineDist;} int GetFinalLineNum() {return m_nFinalLineNum;} void SetFinalLineNum(int nFinalLineNum) {m_nFinalLineNum=nFinalLineNum;} int GetFinalLineAngle(int nLineIndex) {return m_nFinalLineAngle[nLineIndex];} void SetFinalLineAngle(int nLineIndex,int nFinalLineAngle) {m_nFinalLineAngle[nLineIndex]=nFinalLineAngle;} int GetFinalLineDist(int nLineIndex) {return m_nFinalLineDist[nLineIndex];} void SetFinalLineDist(int nLineIndex,int nFinalLineDist) {m_nFinalLineDist[nLineIndex]=nFinalLineDist;} */ //操作处理函数 public: void DrawLine(CClientDC &dc, int nLineAngle, int nLineDist, int nXMin, int nXMax, int nYMin, int nYMax); //画一条直线 void ComputeAddCount(); //累加器计数 void SortAdd(); //累加器排序 void ConnectEdge(CClientDC &dc); //连接边缘 }; #endif // !defined(AFX_HOUGHTRANSFORM_H__E7DC2F17_13C5_49C9_9522_F4F69EEF9D3D__INCLUDED_)

 

      有需要的朋友可以直接把上面的代码复制为两个文件。

      霍夫变换,参数空间的分割步长是比较难的,要根据实际中边缘的方向及位置来设置。下图为处理前的图像:

 处理前

处理后的图像见下:

 处理后

 

 

本代码我相信还有好多问题,迫于时间及本人的理解等原因,还请大家多多提意见,期待大家的讨论!

 

 

你可能感兴趣的:(math.h,interface,im,file,class,c,图像处理)