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

📄 bippro.cpp

📁 变化检测源程序
💻 CPP
字号:
// bippro.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "bippro.h"
#include "Bip.h"

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

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;
#define  WIDTH 496
#define  HEIGHT 496
#define BandNum 6
using namespace std;

BOOL RemoveSmallArea(LPBYTE lpImg, int ImgWid,int ImgHei,int nArea)
{
	// 指向源图像的指针
	BYTE *	lpSrc;

	//图象的宽度和高度
	LONG    lWidth;
	LONG    lHeight;

	// 图像每行的字节数
	LONG	lLineBytes=ImgWid;
	
	lWidth  = ImgWid;
	lHeight = ImgHei;	
	
	
	//图像数据的指针
	LPBYTE  lpDIBBits = lpImg;
	// 循环变量
	int i, j, s, n;

	// 空穴的数目以及面积阈值
	int nHoleNum,nMinArea;;

	int nBlackPix, temp;

	// 正向和反响传播标志
	int nDir1,nDir2;

	// 用来存储的一位数组
	int *pnBinary;

	pnBinary =new int[lHeight*lLineBytes];

	// 小区域的阈值面积为20个象素点
	nMinArea = nArea;

	// 将图象二值化
	for (j = 0; j < lHeight; j++)
	{
		for(i = 0; i < lWidth; i++)
		{
			// 指向源图像倒数第j行,第i个象素的指针			
			lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;

			// 白色象素为背景,存成0
			if(*lpSrc > 200)
			{
				pnBinary[lLineBytes * j + i] = 0;
			}
			// 黑象素存成-1
			else
			{
				pnBinary[lLineBytes * j + i] = -1;
			}
		}		
	}
	
	// 空穴数赋初值
	nHoleNum = 1;
	
	do
	{
		s=0;
		
		// 寻找每个空穴的初始象素值 
		for (j = 1; j < lHeight - 1; j++)
		{
			for(i = 1; i < lWidth - 1; i++)
			{
				// 找到初始象素
				if(pnBinary[lLineBytes * j + i] == -1)
				{
					s = 1;
					// 将象素值改成当前的空穴数值
					pnBinary[lLineBytes * j + i] = nHoleNum;
					
					// 跳出循环
					j = lHeight;			
					i = lLineBytes;
				}
			}
		}

		//没有初始象素,跳出循环
		if(s == 0)
		{
			break;
		}
		else
		{
			do
			{
				// 正向和反响传播系数赋初值0
				nDir1 = 0;
				nDir2 = 0;

				// 正向扫描
				for (j = 1; j < lHeight-1; j++)
				{
					for(i = 1; i < lWidth-1; i++)
					{
						nBlackPix = pnBinary[lLineBytes * j + i];
						
						// 如果象素已经被扫描,或者是背景色,进行下一个循环
						if(nBlackPix != -1)
							continue;

						// 如果上侧或者左侧的象素值已经被扫描,且属于当前的空穴,当前的象素值
						// 改成空穴的数值
						nBlackPix=pnBinary[lLineBytes * (j-1) + i];
						if(nBlackPix == nHoleNum)
						{
							pnBinary[lLineBytes * j + i] = nHoleNum;
							nDir1 = 1;
							
							continue;
						}

						nBlackPix =pnBinary[lLineBytes * j + i - 1];
						
						if(nBlackPix == nHoleNum)
						{
							pnBinary[lLineBytes * j + i] = nHoleNum;
							nDir1 = 1;
						}
					
					}
				}

				// 正向象素全部被扫描,跳出循环
				if(nDir1 == 0)
				{
					break;
				}

				// 反向扫描
				for (j = lHeight-2; j >= 1 ; j--)
				{
					for(i = lWidth-2; i >= 1 ; i--)
					{
						nBlackPix = pnBinary[lLineBytes * j + i];						
						
						// 如果象素已经被扫描,或者是背景色,进行下一个循环
						if(nBlackPix != -1)
						{
							continue;
						}
						
						// 如果下侧或者右侧的象素值已经被扫描,且属于当前的空穴,当前的象素值
						// 改成空穴的数值
						nBlackPix=pnBinary[lLineBytes * (j+1) + i];

						if(nBlackPix == nHoleNum)
						{
							pnBinary[lLineBytes * j + i] = nHoleNum;
							nDir2 = 1;
							
							continue;
						}

						nBlackPix =pnBinary[lLineBytes * j + i + 1];						
						if(nBlackPix == nHoleNum)
						{
							pnBinary[lLineBytes * j + i] = nHoleNum;
							nDir2 = 1;
						}
					}
				}

				if(nDir2 == 0)
				{
					break;
				}
			}
			while(1);
		}
		// 空穴数增加
		nHoleNum++;
	}
	while(1);

	nHoleNum -- ;

	// 寻找面积小于阈值的空穴区域
	for(n = 1; n <= nHoleNum; n++)
	{
		s = 0;
		for (j = 0; j < lHeight - 1; j++)
		{
			for(i = 0; i < lWidth - 1; i++)
			{
				nBlackPix =pnBinary[lLineBytes * j + i];
				
				if(nBlackPix == n)
					s++;

				// 如果区域面积已经大于阈值,跳出循环
				if(s > nMinArea)
				{
					break;
				}
			}

			if(s > nMinArea)
			{
					break;
			}
		}

		// 小于阈值的区域,赋以与背景一样的颜色,进行消去
		if(s <= nMinArea)
		{			
			for (j = 0; j < lHeight - 1; j++)
			{
				for(i = 0; i < lWidth - 1; i++)
				{
					nBlackPix =pnBinary[lLineBytes * j + i + 1];
				
					if(nBlackPix == n)
					{
						pnBinary[lLineBytes * j + i + 1] = 0;
					}			

				}
			}

		}

	}

	// 存储象素值,输出
	for(j = 0; j < lHeight; j++)
	{
		// 列
		for(i = 0; i < lWidth; i++)
		{
			// 二值图象
		    temp = pnBinary[j * lLineBytes + i] ;
			
			// 指向位图i行j列象素的指针
			lpSrc = (unsigned char*)lpDIBBits + lLineBytes * j + i;
			
			// 更新源图像
			if(temp != 0)
				* (lpSrc) = 0;
			else
				* (lpSrc) = 255;
		}
	}

	delete []pnBinary;
    pnBinary = NULL;

	return true;

}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;
	
	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		cerr << _T("Fatal Error: MFC initialization failed") << endl;
		nRetCode = 1;
	}
	else
	{
		// TODO: code your application's behavior here.
		CString strHello;
		strHello.LoadString(IDS_HELLO);
		cout << (LPCTSTR)strHello << endl;
	}
	
	const char strbase[]="e:\\changetest4\\98newbip";
	const char strchange[]="e:\\changetest4\\20newbip";
	const char stryanmu[]="e:\\changetest4\\yanmutrain2.raw";
	FILE *fp_inbase,*fp_inchange,*fp_yanmu;
	fp_inbase=fopen(strbase,"rb");
	fp_inchange=fopen(strchange,"rb");
	fp_yanmu=fopen(stryanmu,"rb");
	int nsize=WIDTH*HEIGHT;
	unsigned char* pchange=new unsigned char[nsize*BandNum+1];
	unsigned char* pbase=new unsigned char[nsize*BandNum+1];
	unsigned char* pyanmu=new unsigned char[nsize+1];
	if(pbase==NULL||pchange==NULL||pyanmu==NULL)
		printf("内存不足!\n");
	fread(pbase,1,nsize*BandNum,fp_inbase);//读入数据
	fread(pchange,1,nsize*BandNum,fp_inchange);
	fread(pyanmu,1,nsize,fp_yanmu);
	
	int i,j,k;
	BYTE **bimage=new BYTE*[HEIGHT];
	for(i=0;i<HEIGHT;i++)
		bimage[i]=pbase+i*BandNum*WIDTH;
	BYTE **aimage=new BYTE*[HEIGHT];
	for(i=0;i<HEIGHT;i++)
		aimage[i]=pchange+i*BandNum*WIDTH;
	int nNum=0;
	
	CString svmtrainfilename="c:\\temp\\traina";
	FILE *fptxt;
	fptxt=fopen(svmtrainfilename+".txt","w");
	for (i=0;i<HEIGHT;i++)
	{
		for (j=0;j<WIDTH;j++)
		{
			if (pyanmu[i*WIDTH+j]==0)
			{
				CString str1="";
				str1.Format("+1 ");
				for (k=0;k<BandNum;k++)
				{
					CString strtemp;
					strtemp.Format("%d:%d ",(k+1),aimage[i][j*BandNum+k]);
					str1+=strtemp;
				}	
				str1+="\n";
				fprintf(fptxt,str1);
				//nNum++;
			}
			
		}
	}
	fclose(fptxt);
///////////////////////////
	CString svmtrainfilenameb="c:\\temp\\trainb";
	FILE *fptxtb;
	fptxtb=fopen(svmtrainfilenameb+".txt","w");
	for (i=0;i<HEIGHT;i++)
	{
		for (j=0;j<WIDTH;j++)
		{
			if (pyanmu[i*WIDTH+j]==0)
			{
				CString str1="";
				str1.Format("+1 ");
				for (k=0;k<BandNum;k++)
				{
					CString strtemp;
					strtemp.Format("%d:%d ",(k+1),bimage[i][j*BandNum+k]);
					str1+=strtemp;
				}
				
				str1+="\n";
				fprintf(fptxtb,str1);
				
			}
			
		}
	}
	fclose(fptxtb);
//////////////////////////////////
/*

	CString svmtrainfilenameab="c:\\temp\\trainab";
	FILE *fptxtab;
	fptxtab=fopen(svmtrainfilenameab+".txt","w");
	for (i=0;i<HEIGHT;i++)
	{
		for (j=0;j<WIDTH;j++)
		{
			if (pyanmu[i*WIDTH+j]==0)
			{
				CString str1="";
				str1.Format("+1 ");
				for (k=0;k<BandNum;k++)
				{
					CString strtemp;
					strtemp.Format("%d:%d:%d ",(k+1),aimage[i][j*BandNum+k],bimage[i][j*BandNum+k]);
					str1+=strtemp;
				}
				
				str1+="\n";
				fprintf(fptxtab,str1);
				nNum++;

			}
			
		}
	}
	fclose(fptxtab);
////////////////////////////////////////////////
	
	unsigned char*yanmu=new unsigned char[nsize];
	memset(yanmu,255,nsize);
	int tt=30;
	int a1,a2,a3,a4,a5,a6;
	for (i=0;i<HEIGHT;i++)
	{
		for (j=0;j<WIDTH;j++)
		{
			a1=abs(aimage[i][j*BandNum+0]-bimage[i][j*BandNum+0]);
			a2=abs(aimage[i][j*BandNum+1]-bimage[i][j*BandNum+1]);
			a3=abs(aimage[i][j*BandNum+2]-bimage[i][j*BandNum+2]);
			a4=abs(aimage[i][j*BandNum+3]-bimage[i][j*BandNum+3]);
			a5=abs(aimage[i][j*BandNum+4]-bimage[i][j*BandNum+4]);
			a6=abs(aimage[i][j*BandNum+5]-bimage[i][j*BandNum+5]);

			//if (a1>tt||a2>tt||a3>tt||a4>tt||a5>tt||a6>tt)
		    if (a1<tt&&a2<tt&&a3<tt&&a4<tt&&a5<tt&&a6<tt)

			{
				yanmu[i*WIDTH+j]=0;
				nNum++;
			}
			
		}
	}
	RemoveSmallArea(yanmu,WIDTH,HEIGHT,100);
	FILE *pResult;
	pResult=fopen("c:\\temp\\b.raw","wb");
    fwrite(yanmu,sizeof(unsigned char),nsize,pResult);
	// 关闭文件
	fclose(pResult);
	delete []yanmu;

	unsigned char*yanmu=new unsigned char[nsize];
	memset(yanmu,255,nsize);
	int tt=0;
	int a1,a2,a3,a4,a5,a6;
	for (i=3;i<HEIGHT-3;i++)
	{
		for (j=3;j<WIDTH-3;j++)
		{
			a1=aimage[i][j*BandNum+0];
			a2=aimage[i][j*BandNum+1];
			a3=aimage[i][j*BandNum+2];
			a4=aimage[i][j*BandNum+3];
			a5=aimage[i][j*BandNum+4];
			a6=aimage[i][j*BandNum+5];

			//if (a1==tt||a2==tt||a3==tt||a4==tt||a5==tt||a6==tt)
		    if (a1==tt&&a2==tt&&a3==tt&&a4==tt&&a5==tt&&a6==tt)
			{
				yanmu[i*WIDTH+j]=0;
				nNum++;
			}
			
		}
	}
	FILE *pResult;
	pResult=fopen("c:\\temp\\b.raw","wb");
    fwrite(yanmu,sizeof(unsigned char),nsize,pResult);
	// 关闭文件
	fclose(pResult);
	delete []yanmu;
*/


	printf("%d\n",nNum);
	//printf("%d %f %f\n",nNum,(double)nNum/74317,(double)4011/nNum);
	fclose(fp_inbase);//=fopen(strbase,"rb");
	fclose(fp_inchange);//=fopen(strchange,"rb");
	fclose(fp_yanmu);//=fopen(stryanmu,"rb");
	delete []pchange;
	delete []pbase;
	delete []pyanmu;
	delete []bimage;
	delete []aimage;
	return nRetCode;
}


⌨️ 快捷键说明

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