⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imagetestdoc.cpp

📁 原创:根据里面的PPT自己编写的角点定位算子Forstner,该方法对图象清晰的效果好
💻 CPP
字号:
// imagetestDoc.cpp : implementation of the CImagetestDoc class
// 山东大学信息科学与工程学院 数字图像处理编程讲义程序
// 作者:赵辉 bugzhao@sdu.edu.cn 
// 完成于:2005.11.15

#include "stdafx.h"
#include "imagetest.h"

#include "imagetestDoc.h"
#include "ParaInput1.h"
#include "input2.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//定义模板运算函数
//im:输入图像  tp:模板参数
double * mbys(double * im,int imW,int imH,double *tp,int tpW,int tpH)
{
	double * out=new double[imW*imH];
	memset(out, 0, imW*imH*sizeof(double));
	int i,j,m,n;
	#define im(ROW,COL) im[imW*(ROW)+(COL)]
	#define tp(ROW,COL) tp[tpW*(ROW)+(COL)]
	#define out(ROW,COL) out[imW*(ROW)+(COL)]
	double a;
	for(i=0;i<imH;i++)
		for(j=0;j<imW;j++)
		{
			a=0;
			//去掉靠近边界的行
			if(i>int(tpH/2) && i<imH-int(tpH/2) && j>int(tpW/2) && j<imW-int(tpW/2))
				for(m=0;m<tpH;m++)
					for(n=0;n<tpW;n++)
					{
						a+=im(i+m-int(tpH/2),j+n-int(tpW/2))*tp(m,n);
					}
			out(i,j)=a;
		}
	return out;
}


double * mbys3(double * im,int imW,int imH,int tpW,int tpH)
{
	double * out=new double[imW*imH];
	memset(out, 0, imW*imH*sizeof(double));
	int i,j,m,n;
	#define im(ROW,COL) im[imW*(ROW)+(COL)]
	
	#define out(ROW,COL) out[imW*(ROW)+(COL)]
	double a;
	for(i=0;i<imH;i++)
		for(j=0;j<imW;j++)
		{
			a=0;
			//去掉靠近边界的行
			if(i>int(tpH/2) && i<imH-int(tpH/2) && j>int(tpW/2) && j<imW-int(tpW/2))
				for(m=0;m<tpH;m++)
					for(n=0;n<tpW;n++)
					{
						a+=im(i+m-int(tpH/2),j+n-int(tpW/2));
					}
			out(i,j)=a/(tpW*tpH);
		}
	return out;
}



/////////////////////////////////////////////////////////////////////////////
// CImagetestDoc

IMPLEMENT_DYNCREATE(CImagetestDoc, CDocument)

BEGIN_MESSAGE_MAP(CImagetestDoc, CDocument)
	//{{AFX_MSG_MAP(CImagetestDoc)
	ON_COMMAND(ID_IMG_REVERSE_COLOR, OnImgReverseColor)
	ON_COMMAND(ID_IMG_CONVERT_GRAY, OnImgConvertGray)
	ON_COMMAND(ID_IMG_INCREASE_BRIGHTNESS, OnImgIncreaseBrightness)
	ON_COMMAND(ID_IMG_EDGE_BLUR, OnImgEdgeBlur)
	ON_COMMAND(IDM_Forstner, OnForstner)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CImagetestDoc construction/destruction

CImagetestDoc::CImagetestDoc()
{
	// TODO: add one-time construction code here
	m_nDocSize.cx = 800;
	m_nDocSize.cy = 800;

	m_palDIB = NULL;
	m_hDIB = NULL;
}

CImagetestDoc::~CImagetestDoc()
{
	if (m_hDIB != NULL)
	{
		::GlobalFree((HGLOBAL) m_hDIB);
		m_hDIB=NULL;
	}	
	if (m_palDIB != NULL)
	{
		delete m_palDIB;
		m_palDIB=NULL;
	}

}

BOOL CImagetestDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)
	m_hDIB = NewDIB(m_nDocSize.cx, m_nDocSize.cy,24);
	InitDIBData();
	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CImagetestDoc serialization

void CImagetestDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CImagetestDoc diagnostics

#ifdef _DEBUG
void CImagetestDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CImagetestDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CImagetestDoc commands

BOOL CImagetestDoc::InitDIBData()
{
	if (m_palDIB != NULL)
	{
		delete m_palDIB;
		m_palDIB = NULL;
	}
	if (m_hDIB == NULL)
	{
		return FALSE;
	}
	m_palDIB = new CPalette;
	if (m_palDIB == NULL)
	{
		// we must be really low on memory
		::GlobalFree((HGLOBAL) m_hDIB);
		m_hDIB = NULL;
		return FALSE;
	}

	if (::CreateDIBPalette(m_hDIB, m_palDIB) == NULL)
	{
		// DIB may not have a palette
		delete m_palDIB;
		m_palDIB = NULL;
	}

	return TRUE;
}

BOOL CImagetestDoc::ReadImgFile(CString sName)
{
	if (m_hDIB != NULL)
	{
		::GlobalFree((HGLOBAL) m_hDIB);
		m_hDIB=NULL;
	}	
	if (m_palDIB != NULL)
	{
		delete m_palDIB;
		m_palDIB=NULL;
	}

	// replace calls to Serialize with ReadDIBFile function
	CFile nFile;
	if(!nFile.Open(sName,CFile::modeRead))
		return false;
	m_hDIB = ReadDIBFile(nFile);
	nFile.Close();
	InitDIBData();

	if (m_hDIB == NULL)
		return FALSE;
	return TRUE;
}

BOOL CImagetestDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
	if (!CDocument::OnOpenDocument(lpszPathName))
		return FALSE;
	
	// TODO: Add your specialized creation code here
	BOOL b = ReadImgFile(lpszPathName);
	if(b )
	{
		LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
		m_nDocSize.cx = (int) ::DIBWidth(lpDIB);         // Size of DIB - x
		m_nDocSize.cy = (int) ::DIBHeight(lpDIB);        // Size of DIB - y
		::GlobalUnlock((HGLOBAL) m_hDIB);
	}
	POSITION pos;
	pos = GetFirstViewPosition();
	while(pos != NULL)
	{
		CScrollView * pView = (CScrollView *)GetNextView(pos);
		if(pView != NULL)
		{
			pView->SetScrollSizes(MM_TEXT, m_nDocSize);

		}
	}

	return b;
}


BOOL CImagetestDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
	// TODO: Add your specialized code here and/or call the base class
	CFile nFile;
	if(m_hDIB == NULL)
		return  false;
	nFile.Open(lpszPathName,CFile::modeWrite | CFile::modeCreate);
	SaveDIB(m_hDIB, nFile);
	nFile.Close();
	return true;
//	return CDocument::OnSaveDocument(lpszPathName);
}

void CImagetestDoc::OnImgReverseColor() 
{
	//计算操作所用时间-计时开始
	TimeCountStart;
	
	int i,j;
    unsigned char *lpSrc;
	LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)m_hDIB);
	int cxDIB = (int) ::DIBWidth(lpDIB);         // Size of DIB - x
	int cyDIB = (int) ::DIBHeight(lpDIB);        // Size of DIB - y
	LPSTR lpDIBBits=::FindDIBBits (lpDIB);
	// 计算图像每行的字节数
	long lLineBytes = WIDTHBYTES(cxDIB * 8);
	// 每行
	for(i = 0; i < cyDIB; i++)
	{
		// 每列
		for(j = 0; j < cxDIB; j++)
		{
			// 指向DIB第i行,第j个象素的指针(这里的行为从上到下的)
			lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j;
			
			// 计算新的灰度值
			*(lpSrc) = BYTE(255-*lpSrc);
		}
	}
	::GlobalUnlock((HGLOBAL) m_hDIB);
    UpdateAllViews(NULL, 0, NULL);

	//显示操作所用时间
	TimeCountEnd;
}

void CImagetestDoc::OnImgConvertGray() 
{
	int i,j;
    unsigned char *lpSrc,*lpDst;//一个指向源、目的像素的移动指针

	//对源图像进行操作
	LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)m_hDIB);
	int cxDIB = (int) ::DIBWidth(lpDIB);         
	int cyDIB = (int) ::DIBHeight(lpDIB);        
	LPSTR lpDIBBits=::FindDIBBits (lpDIB);	//找到源图像中图像数据区起始位置
	long lLineBytesSrc = WIDTHBYTES(cxDIB * 8 * 3);// 计算源24位真彩图像每行的字节数

	int numColors=(int) ::DIBNumColors((char *)lpDIB);
    if (numColors!=0)  //如果numColors是0,则表示目前图像为24位真彩图
	{
		::GlobalUnlock((HGLOBAL) m_hDIB);
		return;
	}

	//新创建一个8位(256级灰度)的DIB句柄
	HDIB grayhDIB=NewDIB(cxDIB, cyDIB,8);
	LPSTR glpDIB=(LPSTR)::GlobalLock((HGLOBAL)grayhDIB);
	LPSTR glpDIBBits=::FindDIBBits (glpDIB);
	long lLineBytesDst = WIDTHBYTES(cxDIB * 8);// 计算目标8位灰度图像每行的字节数
	// 每行
	for(i = 0; i < cyDIB; i++)
	{
		//每列
		for(j = 0; j < cxDIB; j++)
		{
			// 指向DIB第i行,第j个象素的指针(这里的行为从上到下的)
			lpSrc = (unsigned char*)lpDIBBits + lLineBytesSrc * (cyDIB - 1 - i) + j*3;
			lpDst = (unsigned char*)glpDIBBits + lLineBytesDst * (cyDIB - 1 - i) + j;
			*lpDst=(*lpSrc)/3+(*(lpSrc+1))/3+(*(lpSrc+2))/3;
		}
	}

	m_hDIB=grayhDIB;
	::GlobalUnlock((HGLOBAL) m_hDIB);
	::GlobalUnlock((HGLOBAL) grayhDIB);
	UpdateAllViews(NULL, 0, NULL);	
}

void CImagetestDoc::OnImgIncreaseBrightness() 
{
	//获取输入参数作为亮度提升间隔
	CParaInput1 input1;
	input1.m_input1 =10;
	if(input1.DoModal ()!=IDOK) 
		return;
	int i,j,increment=10;
	increment=input1.m_input1 ;
    unsigned char *lpSrc;//一个指向源、目的像素的移动指针
	LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)m_hDIB);
	int cxDIB = (int) ::DIBWidth(lpDIB);         // Size of DIB - x
	int cyDIB = (int) ::DIBHeight(lpDIB);        // Size of DIB - y
	LPSTR lpDIBBits=::FindDIBBits (lpDIB);
	// 计算图像每行的字节数
	long lLineBytes = WIDTHBYTES(cxDIB * 8);
	// 每行
	for(i = 0; i < cyDIB; i++)
	{
		// 每列
		for(j = 0; j < cxDIB; j++)
		{
			// 指向DIB第i行,第j个象素的指针(这里的行为从上到下的)
			lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j;
			
			// 计算新的灰度值
			if(*lpSrc<255-increment)
				*(lpSrc) = BYTE(increment+*lpSrc);
		}
	}
	::GlobalUnlock((HGLOBAL) m_hDIB);
    UpdateAllViews(NULL, 0, NULL);
}

void CImagetestDoc::OnImgEdgeBlur() 
{
	int i,j;
    unsigned char *lpSrc;//一个指向源、目的像素的移动指针
	LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)m_hDIB);
	int cxDIB = (int) ::DIBWidth(lpDIB);         // Size of DIB - x
	int cyDIB = (int) ::DIBHeight(lpDIB);        // Size of DIB - y
	LPSTR lpDIBBits=::FindDIBBits (lpDIB);
	// 计算图像每行的字节数
	long lLineBytes = WIDTHBYTES(cxDIB * 8);
	int FrameWidth=15;
	TRACE("%d ",FrameWidth);
	// 每行
	for(i = 0; i < cyDIB; i++)
	{
		// 每列
		for(j = 0; j < cxDIB; j++)
		{
			if(i<=FrameWidth || i>cyDIB-FrameWidth || j<=FrameWidth || j>cxDIB-FrameWidth)
			{	// 指向DIB第i行,第j个象素的指针(这里的行为从上到下的)
				lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j;
				if((*lpSrc-40)>0) 
					*lpSrc=*lpSrc-40;	
			}
			if(i<=FrameWidth-10 || i>cyDIB-FrameWidth+10 || j<=FrameWidth-10 || j>cxDIB-FrameWidth+10)
			{	// 指向DIB第i行,第j个象素的指针(这里的行为从上到下的)
				lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j;
				if((*lpSrc+45)<255)
					*lpSrc=*lpSrc+45;	
			}
		
		}
	}
	::GlobalUnlock((HGLOBAL) m_hDIB);
    UpdateAllViews(NULL, 0, NULL);
}
 


void CImagetestDoc::OnForstner() 
{
	// TODO: Add your command handler code here
	
	unsigned char *lpSrc;//一个指向源、目的像素的移动指针
	LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)m_hDIB);
	int cxDIB = (int) ::DIBWidth(lpDIB);         // 图像宽度
	int cyDIB = (int) ::DIBHeight(lpDIB);        // 图像高度
	LPSTR lpDIBBits=::FindDIBBits (lpDIB);
	long lLineBytes = WIDTHBYTES(cxDIB * 8);     // 计算灰度图像每行的字节数

	//创建I、Gu、Gv、mx、corner数组
	double *I=new double[cxDIB*cyDIB];
	double *Gu=new double[cxDIB*cyDIB];
	double *Gv=new double[cxDIB*cyDIB];
	double *Gu2=new double[cxDIB*cyDIB];
	double *Gv2=new double[cxDIB*cyDIB];
	double *Guv=new double[cxDIB*cyDIB];
	double *DetN=new double[cxDIB*cyDIB];
	double *trN=new double[cxDIB*cyDIB];
	double *w=new double[cxDIB*cyDIB];
	double *q=new double[cxDIB*cyDIB];
	bool *houxian=new bool[cxDIB*cyDIB];
	double *Tw=new double[cxDIB*cyDIB];
	double *mx=new double[cxDIB*cyDIB];

	corner=new bool[cxDIB*cyDIB];
	memset(corner, 0, cxDIB*cyDIB*sizeof(bool));
	memset(houxian, 0, cxDIB*cyDIB*sizeof(bool));
	memset(mx, 0, cxDIB*cyDIB*sizeof(double));

	//定义宏以方便访问元素
	#define I(ROW,COL) I[cxDIB*(ROW)+(COL)]
	#define Gu(ROW,COL) Gu[cxDIB*(ROW)+(COL)]
	#define Gu2(ROW,COL) Gu2[cxDIB*(ROW)+(COL)]
	#define Gv(ROW,COL) Gv[cxDIB*(ROW)+(COL)]
	#define Gv2(ROW,COL) Gv2[cxDIB*(ROW)+(COL)]
	#define Guv(ROW,COL) Guv[cxDIB*(ROW)+(COL)]
	#define DetN(ROW,COL) DetN[cxDIB*(ROW)+(COL)]
	#define trN(ROW,COL) trN[cxDIB*(ROW)+(COL)]
	#define w(ROW,COL) w[cxDIB*(ROW)+(COL)]
	#define q(ROW,COL) q[cxDIB*(ROW)+(COL)]
	#define corner(ROW,COL) corner[cxDIB*(ROW)+(COL)]
	#define houxian(ROW,COL) w[cxDIB*(ROW)+(COL)]
	#define Tw(ROW,COL) Tw[cxDIB*(ROW)+(COL)]
	#define mx(ROW,COL) mx[cxDIB*(ROW)+(COL)]

   int i,j;

	//将图像灰度值复制到I中,这步很重要!想想为什么?
	for(i = 0; i < cyDIB; i++)
	{
		for(j = 0; j < cxDIB; j++)
		{			
			lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j;
			//将256级灰度图像转化为double型
			I(i,j)=double(*lpSrc);
		}
	}

  	//计算Gu
	double du[9]={0,0,0,0,-1,0,0,0,1};
	Gu=mbys(I,cxDIB,cyDIB,du,3,3);

	//计算Gv
	double dv[9]={0,0,0,0,0,-1,0,1,0};
	Gv=mbys(I,cxDIB,cyDIB,dv,3,3);


	//计算Gu2
	int m,n;
	memset(Gu2, 0, cxDIB*cyDIB*sizeof(double));
	for(i=0;i<cyDIB;i++)
		for(j=0;j<cxDIB;j++)
		{
			double a=0;
			//去掉靠近边界的行
			if(i>int(5/2) && i<cyDIB-int(5/2) && j>int(5/2) && j<cxDIB-int(5/2))
				for(m=0;m<5;m++)
					for(n=0;n<5;n++)
					{
						a+=Gu(i+m-int(5/2),j+n-int(5/2))*Gu(i+m-int(5/2),j+n-int(5/2));
						
					}
					Gu2(i,j)=a;
					
					
		}
		//计算Gv2
		memset(Gv2, 0, cxDIB*cyDIB*sizeof(double));
		for(i=0;i<cyDIB;i++)
			for(j=0;j<cxDIB;j++)
			{
				double a=0;
				//去掉靠近边界的行
				if(i>int(5/2) && i<cyDIB-int(5/2) && j>int(5/2) && j<cxDIB-int(5/2))
					for(m=0;m<5;m++)
						for(n=0;n<5;n++)
						{
							a+=Gv(i+m-int(5/2),j+n-int(5/2))*Gv(i+m-int(5/2),j+n-int(5/2));
							
						}
						Gv2(i,j)=a;
						
						
			}

		//计算Guv
	memset(Guv, 0, cxDIB*cyDIB*sizeof(double));
	for(i=0;i<cyDIB;i++)
		for(j=0;j<cxDIB;j++)
		{
			double a=0;
				//去掉靠近边界的行
			if(i>int(5/2) && i<cyDIB-int(5/2) && j>int(5/2) && j<cxDIB-int(5/2))
				for(m=0;m<5;m++)
					for(n=0;n<5;n++)
					{
						a+=Gv(i+m-int(5/2),j+n-int(5/2))*Gu(i+m-int(5/2),j+n-int(5/2));
							
					}
					Guv(i,j)=a;
						
						
		}	


	//计算DetN trN w q
	for(i = 0; i < cyDIB; i++)
	{
		for(j = 0; j < cxDIB; j++)
		{
			//注意:要在分母中加入一个极小量以防止除数为零溢出
			DetN(i,j)=Gu2(i,j)*Gv2(i,j)-Guv(i,j)*Guv(i,j);
			trN(i,j)=Gu2(i,j)+Gv2(i,j);
			w(i,j) = DetN(i,j)/(trN(i,j)+0.0000001);
			q(i,j)=4*DetN(i,j)/(trN(i,j)*trN(i,j));
		}
	}
	double Tq=0.5;

	Tw=mbys3(w,cxDIB,cyDIB,5,5);
	for(i = 0; i < cyDIB; i++)
	{
		for(j = 0; j < cxDIB; j++)
		{
			if(q(i,j)>Tq&&w(i,j)>Tw(i,j))
				houxian(i,j)=1;			
		
		}
	}

	
	double max=-1000000;
	double max1=-1000000;



    for(i=0;i<cyDIB;i++)
		for(j=0;j<cxDIB;j++)
		{
		
			//去掉靠近边界的行
			if(i>int(5/2) && i<cyDIB-int(5/2) && j>int(5/2) && j<cxDIB-int(5/2))
				for(m=0;m<5;m++)
					for(n=0;n<5;n++)
					{
						if(houxian(i+m-int(5/2),j+n-int(5/2)))
						  if(Tw(i+m-int(5/2),j+n-int(5/2))>max/*&&q(i,j)>max1*/)
							  max=Tw(i+m-int(5/2),j+n-int(5/2));
						     // max1=q(i+m-int(5/2),j+n-int(5/2));
					}

			mx(i,j)=max;
		}

	for(i=0;i<cyDIB;i++)
		for(j=0;j<cxDIB;j++)
		{
		if(Tw(i,j)==mx(i,j))
				corner(i,j)=1;
		}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -