comlib.cpp

来自「图像处理软件,功能比较基础」· C++ 代码 · 共 2,466 行 · 第 1/4 页

CPP
2,466
字号
	for(int j=0;j<col;j++)
	{
		if (max<fimg[i][j]) max = fimg[i][j];
		if (min>fimg[i][j]) min = fimg[i][j];
	}

	for(i=0;i<row;i++)
	for(int j=0;j<col;j++)
	{
		Des[i][j] = (unsigned char)(255*(fimg[i][j]-min)/(max-min));
	}
	
	ffree_2d((void** ) fimg, row);

	return Des;
}

// 图象放大(三次线性插值)
BYTE ** CComlib::ImgScaleCubicLinear(BYTE ** src , int row, int col, int desR , int desC )
{
	float deltax=(double)(col-3)/(double)(desC-1);
	float deltay=(double)(row-3)/(double)(desR-1);

	float xx , yy , dxx , dyy;
	float ck0 , cl0;
	int x[4] , y[4] , yk , xl;

	BYTE ** des = (BYTE**) fspace_2d( desR , desC , sizeof(BYTE));

	for(int i=0;i<desR;i++)
	{
		yy = 1.0+(float) i*deltay;
		y[1] = (int)yy;
		y[0] = y[1]-1;
		y[2] = y[1]+1;
		y[3] = y[1]+2;
		
		for( int j=0;j< desC ;j++)
		{
			xx = 1.0+(float)j*deltax;
			x[1]=(int) xx;
			x[0]=x[1]-1;
			x[2]=x[1]+1;
			x[3]=x[1]+2;
			
			float zz = 0;
			
			for(int k=0;k<4;k++)
			{
				dyy  = fabs(yy-y[k]);
				
				if(dyy < 1.0) 
					ck0 = 1.0 - 2.0*dyy*dyy + dyy*dyy*dyy;
				else
				{
					if ( dyy < 2.0)
						ck0 = 4.0 - 8.0*dyy + 5.0*dyy*dyy - dyy*dyy*dyy;
					else          
						ck0=0.0;
				}
				
				if (y[k]> row - 1 )
					yk = row - 1;
				else         
					yk = y[k];

				for(int l=0;l<4;l++)
				{
					dxx = fabs(xx-x[l]);

					if( dxx < 1.0 )  
						cl0 = 1.0 - 2.0*dxx*dxx + dxx*dxx*dxx;
					else
					{
						if( dxx < 2.0 ) 
							cl0 = 4.0 - 8.0*dxx + 5.0*dxx*dxx - dxx*dxx*dxx;
						else
							cl0=0;
					}
					
					if (x[l]> col - 1) 
						xl = col - 1;
					else  
						xl = x[l];
					
					zz += src[yk][xl]*ck0*cl0;
				}
			}

			int gray = (int) (zz+0.5);
			if(gray > 255 ) 
				gray = 255;
			if(gray < 0)  
				gray = 0;
			
			des[i][j] = gray;
		}
	}

	return des;
}

// 图象按整数比例缩小
void CComlib::ImgSmooth(BYTE **Src,int nRow,int nCol,int nrRatio, int ncRatio, BYTE **Des)
{
	int i,j;
	int m,n;
	int nDesRow,nDesCol;
	long lTemp;

	nDesRow = nRow/nrRatio;
	nDesCol = nCol/ncRatio;
	for (i=0;i<nDesRow;i++)
	for (j=0;j<nDesCol;j++) 
	{
		lTemp = 0;
		for (m=0;m<nrRatio;m++) 
		for (n=0;n<ncRatio;n++) 
		{
			lTemp += Src[i*nrRatio+m][j*ncRatio+n];
		}
		Des[i][j] = (BYTE) ((float) lTemp/(nrRatio*ncRatio)+0.5);
	}
}

BYTE ** CComlib::ImgRotate(BYTE ** src , int sr, int sc , int& dr, int& dc, float theta , BOOL dir, BYTE nBackgrd )
{
	// Rotate matrix
	float a11, a12, a21, a22;
	a11 = cos(theta);
	a12 = sin(theta);
	a22 = cos(theta);
	a21 = - sin(theta);

	if(dir == NOCLOCKWISE)
	{
		a12 *= -1;
		a21 *= -1;
	}

	float sx0 = (sc-1) / 2.0;    // center cord
	float sy0 = (sr-1) / 2.0;
	float rad = sqrt(sx0*sx0+sy0*sy0);
	float alpha0 = atan( sr /(float) sc );
	float alphaY = alpha0 + theta;
	float alphaX = alpha0 - theta;

	dr = int (2*rad*sin(alphaY) + 0.5);
	dc = int (2*rad*cos(alphaX) + 0.5);
	float x0 = (dc-1)/2.0;
	float y0 = (dr-1)/2.0;

	BYTE ** des = (BYTE**) fspace_2d( dr, dc, sizeof(BYTE));

	for( int i=0 ; i<dr; i++)
	for( int j=0 ; j<dc; j++)
	{
/*
		int m = int ( a11*(j - x0) + a12*(i - y0) );  // x
		int n = int ( a21*(j - x0) + a22*(i - y0) );  // y
		int x = int ( m + sx0 ) ;
		int y = int ( n + sy0 );
*/
		// modified here , for the interplation
		float x = a11*(j - x0) + a12*(i - y0) + sx0 ;
		float y = a21*(j - x0) + a22*(i - y0) + sy0 ;

		if( x>=0 && x<sc-1 && y>=0 && y<sr-1 )
		{
			int m = (int) floor(x);
			int n = (int) floor(y);
			float R = x-m;
			float S = y-n;

			des[i][j] = (BYTE)((1-R)*(1-S)*src[m][n] +
				R*(1-S)*src[m][n+1] + (1-R)*S*src[m+1][n] +
				R*S*src[m+1][n+1]);
		}
		else 
			des[i][j] = nBackgrd;
	}

	return des ;
}
	
// 图像反转
void CComlib::Inverse(BYTE** lpOrgImg, BYTE** lpOutImg, int Row, int Col)
{
	ASSERT(lpOrgImg!=NULL && lpOutImg!=NULL);

	for(int i=0;i<Row;i++)
	for(int j=0;j<Col;j++)
		lpOutImg[i][j] = MAXGRAYLEVEL-lpOrgImg[i][j];
	
	return;
}

void CComlib::ImgScale(BYTE ** src , int sr, int sc, BYTE ** des , int dr, int dc , int nScaleFactor)
{
	// 如果是等尺寸大小,则拷贝后返回
	if(sr == dr && sc == dc)
	{
		for(int i=0;i<sr;i++)
		for(int j=0;j<sc;j++)
			des[i][j] = src[i][j];

		return ;
	}

	if(sr > dr && sc > dc) 
		nScaleFactor = max( min(sr/dr, sc/dc), 2);

	int  mr = dr * nScaleFactor ;
	int  mc = dc * nScaleFactor ;

	while ( mr > sr*nScaleFactor ) mr /= nScaleFactor ;
	while ( mc > sc*nScaleFactor ) mc /= nScaleFactor ;

	while ( mr < sr ) mr *= nScaleFactor ;
	while ( mc < sc ) mc *= nScaleFactor ;

	int rRatio = mr / dr ;
	int cRatio = mc / dc ;

	float  fRowFactor = mr / sr;
	float  fColFactor = mc / sc;
	
	BYTE ** MidImg = ImgScaleCubicLinear( src , sr , sc , mr , mc);

//	OutputImageWithName(MidImg , sr , sc , "midimg.pic");

	ImgSmooth(MidImg , mr , mc , rRatio , cRatio, des) ;

	ffree_2d( (void**) MidImg , mr );

	return ;
}

BOOL CComlib::TransPicToBmp(CString PicFileName, CString OutFileName, float fScale, int x1, int x2, int y1, int y2, BOOL bPic)
{
	BOOL bRet = TRUE;

	int Row, Col;
	BYTE ** lpImgData = InputImageWithName( &Row, &Col , PicFileName );
	if( lpImgData == NULL)
	{
		AfxMessageBox("NOT pic file!");
		return FALSE;
	}

	unsigned char ** box = lpImgData;
	int row = Row;
	int col = Col;

	BOOL bDig = TRUE;
	// 截取图像大小
	if(x1 < 0 || y1 < 0 || x1>=x2 || y1>=y2)  // 不需截取
	{
		bDig = FALSE;
	}
	else
	{
		if(y2 > Row) y2=Row;
		if(x2 > Col) x2=Col;

		col = x2-x1;
		row = y2-y1;
		
		unsigned char ** box1 = ( unsigned char **) fspace_2d( row, col, sizeof(char));
		ASSERT(box1 != NULL);
		for(int i=y1;i<y2;i++)
		for(int j=x1;j<x2;j++)
		{
			box1[i-y1][j-x1] = lpImgData[i][j];
		}

		ffree_2d((void**)lpImgData, Row);

		box = box1;
	}

	// 尺度变换
	if(fScale != 1 && fScale>0)
	{
		int desR = fScale*row;
		int desC = fScale*col;
		BYTE ** out = ImgScaleCubicLinear(box , row, col, desR , desC);
		if(bPic)
			OutputImageWithName( out , desR ,desC , OutFileName );
		else
			BOOL bRet = WriteAsBmp( out , desR ,desC , OutFileName );
		ffree_2d((void**)out, desR);
	}
	else
	{
		if(bPic)
			OutputImageWithName( box , row, col, OutFileName );
		else
			BOOL bRet = WriteAsBmp( box , row, col, OutFileName );
	}

	ffree_2d((void**)box, row);

	return bRet;
}

BOOL CComlib::WriteAsBmp(BYTE ** image , int Row , int Col ,CString FileName)
{
	int nBits = 8;    // 位平面数
	int nPaletteSize = pow( 2, nBits);  // 调色板大小
	int nWidth = Col ;
	int nHeight = Row ;
	
	DWORD dwLineBytes=((DWORD) nWidth*nBits + 31 )/32;    // 每行所需字节数
	dwLineBytes *= 4;

	DWORD dwBMHLength = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+ 
               sizeof(RGBQUAD) * nPaletteSize;    //  BMP文件头长度

	DWORD dwLength = dwBMHLength + dwLineBytes * nHeight; 

	char * lpBuf=(char *) fspace_1d( dwLength, sizeof(char) );
	if(!lpBuf)
	{
		AfxMessageBox("Unable to allocate DIB memory");
		return FALSE;
	}

	LPBITMAPFILEHEADER lpBMFH=(LPBITMAPFILEHEADER) lpBuf;
	LPBITMAPINFOHEADER lpBMIH=(LPBITMAPINFOHEADER)(lpBuf+sizeof(BITMAPFILEHEADER));
	LPBITMAPINFO lpBMI =(LPBITMAPINFO) lpBMIH;

	TRACE("BMFHSize = %d , BMIH = %d ,\n", sizeof(BITMAPFILEHEADER),sizeof(BITMAPINFOHEADER));
	TRACE("BMHLength = %d , BMLength = %d ,\n", dwBMHLength ,dwLength);
	TRACE("LineBytes = %d \n", dwLineBytes );

	lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
	lpBMIH->biWidth = nWidth;
	lpBMIH->biHeight = nHeight;
	lpBMIH->biPlanes = 1;
	lpBMIH->biBitCount = nBits; // 8 Gray
	lpBMIH->biCompression = BI_RGB;

	lpBMIH->biSizeImage = 0;
	lpBMIH->biXPelsPerMeter = 0;
	lpBMIH->biYPelsPerMeter = 0;
	lpBMIH->biClrUsed = 0;
	lpBMIH->biClrImportant =0;

	LPRGBQUAD lpRGBPalette = (RGBQUAD * ) (lpBuf + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)) ;
	for(int k=0;k<nPaletteSize;k++)
	{
		lpRGBPalette[k].rgbBlue 
			= lpRGBPalette[k].rgbGreen 
			= lpRGBPalette[k].rgbRed = k;
		lpRGBPalette[k].rgbReserved = 0;
	}

	LPSTR lpData = (LPSTR) lpBMIH + sizeof(BITMAPINFOHEADER) +
			  sizeof(RGBQUAD) * nPaletteSize;
	lpBMFH->bfType = 0x4d42; // 'BM'
	lpBMFH->bfSize = dwLength;
	lpBMFH->bfReserved1 = 0;
	lpBMFH->bfReserved2 = 0;
	lpBMFH->bfOffBits = (char far *) lpData -lpBuf;

	int n=0;
	for(int i = 0;i<nHeight;i++)
	{
		for(int j = 0 , n = i*dwLineBytes ;j<nWidth;j++, n++)
		{
			*(lpData + n) = (BYTE) image[nHeight-1-i][j];
		}

		int nGap = (4 - nWidth%4) % 4 ;  // fill the remainer byte of one row
		while(nGap--)
		{
			*(lpData + n) = 0x0 ;
			n++;
		}
	}

	TRY
	{
		CFile f( FileName, CFile::modeCreate | CFile::modeWrite );
		f.WriteHuge(lpBuf, dwLength);
		f.Close();
	}
	CATCH (CException, e) 
	{
		AfxMessageBox("Write error--possible disk full condition");
		return FALSE;
	}
	END_CATCH

	ffree_1d((void*) lpBuf);

	return TRUE;
}

///////////////////////////////////////
//
// add new function here in version 2.2
//
///////////////////////////////////////
SEMULT *  CComlib::ReadEmultProcessItem( int &numb , CString filename)
{
	numb = 0 ;
	SEMULT * ret = NULL ;

	FILE *fp = fopen(filename , "rt"); 
	CString err = filename + "  open  Error!";
	if(! ASSERTVALIDPOINTER(fp, err)) return NULL;

	char version[20];
	fscanf(fp, "Version=%s\n", version);
	if( strcmp(version, VERSION)!=0 )
	{
		AfxMessageBox("Error Version batch file!");
		numb=-1;
		return ret;
	}

	fscanf(fp, "numbs = %d\n", &numb);
	if( numb <= 0 ) return NULL;
	ret = (SEMULT * ) fspace_1d(numb , sizeof(SEMULT) );

	for(int i=0;i<numb;i++)
	{
		BOOL bType = ISREL;  // default 0

		float hight  , fFlightRate , fScanRate ,fStartScanAngle ,res ;
		float fdstScale, fdstTheta;
		int numbs ,scale , bFlightDir ,bScanDir ;
		int nExtOrgimage = 0;
		float fScanTheta;  // 成像扫描角度 DBS

		char SarFile[80], RelFile[80], PosFile[80], PathName[80];

		//Emult hight numbs scale bFlightDir fFlightRate bScanDir fScanRate fStartScanAngle res PathName SarFile RelFile PosFile
		fscanf(fp, "Emult Isdbs=%d hight=%f numbs=%d scale=%d PathName=%s nExtOrgimage=%d fdstScale=%f fdstTheta=%f bFlightDir=%d fFlightRate=%f bScanDir=%d fScanRate=%f fStartScanAngle=%f fScanTheta=%f res=%f SarFile=%s RelFile=%s PosFile=%s\n",
			&bType , &hight, &numbs ,&scale , PathName , &nExtOrgimage, &fdstScale, &fdstTheta , &bFlightDir ,&fFlightRate ,&bScanDir ,&fScanRate ,&fStartScanAngle , &fScanTheta , &res , SarFile ,RelFile ,PosFile);
	
		ret[i].bType = bType ; 

		ret[i].hight = hight ; 
		ret[i].numbs = numbs ;
		ret[i].scale = scale ;
		ret[i].res = res ;
		
		ret[i].nExtOrgimage = nExtOrgimage ;
		ret[i].fdstScale = fdstScale ;
		ret[i].fdstTheta = fdstTheta ;
		ret[i].fScanTheta = fScanTheta;

		ret[i].bFlightDir = bFlightDir;
		ret[i].fFlightRate = fFlightRate;
		ret[i].bScanDir = bScanDir;
		ret[i].fScanRate = fScanRate;
		ret[i].startscanangle = fStartScanAngle;

		strcpy(ret[i].PathName , PathName);
		strcpy(ret[i].pos , PosFile);
		strcpy(ret[i].rel , RelFile);
		strcpy(ret[i].sar , SarFile);
		
		ret[i].brel = 1;
		ret[i].bsar = 1;
		
		// 如果输入分辨率,则按照输入的分辨率计算,否则重新计算分辨率
		if(ret[i].bType == ISREL)
		{
			float fRes = 2*hight*tan(THETA2 * PI/180) / RELIMGSIZE;
			ret[i].res = (res == 0 ) ? fRes : res;
		}
		else if(ret[i].bType == ISDBS)
		{
			float fRes = hight*(tan(THETA2 * PI/180)-tan(THETA1 * PI/180)) / RELIMGSIZE;
			ret[i].res = (res == 0 ) ? fRes : res;
		}
	}
	fclose(fp);

	return ret;
}

SMATCH *  CComlib::ReadMatchProcessItem( int &numb , CString filename)
{
	numb = 0 ;
	SMATCH * ret = NULL ;

	FILE *fp = fopen(filename , "rt"); 
	CString err = filename + "  open  Error!";
	if(! ASSERTVALIDPOINTER(fp, err)) return NULL;

	char version[20];
	fscanf(fp, "Version=%s\n", version);
	if( strcmp(version, VERSION)!=0 )
	{
		AfxMessageBox("Error Version batch file!");
		numb=-1;
		return ret;
	}

	fscanf(fp, "numbs = %d\n", &numb);
	if( numb <= 0 ) return NULL;
	ret = (SMATCH * ) fspace_1d(numb , sizeof(SMATCH) );

	for(int i=0;i<numb;i++)
	{
		float hight  ,res ;
		int numbs ,TSize , nErrMax;
		int bFlightDir ;
		float fRatioLR;
		float fScanTheta ;
		BOOL bVerL , bVerR ;
		BOOL nType;
		char RefFile[80], RelFile[80], PosFile[80], CorFile[80] , ResultFile[80], PathName[80];

		// Match hight numbs scale bFlightDir fFlightRate bScanDir fScanRate fStartScanAngle res SarFile RelFile PosFile
		fscanf(fp, "Match Isdbs=%d fRatioLR=%f bVerL=%d bVerR=%d bFlightDir=%d fScanTheta=%f hight=%f res=%f numbs=%d TSize=%d nErrMax=%d PathName=%s RefFile=%s RelFile=%s CorFile=%s PosFile=%s ResultFile=%s\n",
			&nType , &fRatioLR , &bVerL , &bVerR, &bFlightDir , &fScanTheta, &hight, &res ,&numbs , &TSize , &nErrMax , PathName ,RefFile ,RelFile ,CorFile ,PosFile ,ResultFile);
	
		ret[i].bType = nType ; 
		ret[i].height = hight ; 
		ret[i].numbs = numbs ;
		
		ret[i].fRatioLR = fRatioLR ;
		ret[i].bVerL = bVerL ;
		ret[i].bVerR = bVerR ;
		ret[i].bFlightDir = bFlightDir ;
		ret[i].fScanTheta = fScanTheta ;

		strcpy(ret[i].PathName , PathName );
		strcpy(ret[i].RefFile , RefFile );
		strcpy(ret[i].RelFile , RelFile );
		strcpy(ret[i].CorFile , CorFile );
		strcpy(ret[i].PosFile , PosFile );
		strcpy(ret[i].ResultFile , ResultFile );

		ret[i].nErrMax = nErrMax;
		ret[i].bsize = TSize;
		
		// 如果输入分辨率,则按照输入的分辨率计算,否则重新计算分辨率
		if( nType == ISREL)
		{
			float fRes = 2*hight*tan(THETA2 * PI/180) / RELIMGSIZE;
			ret[i].res = (res == 0 ) ? fRes : res;

			ret[i].rad0 = (int)(hight*tan(THETA1 * PI/180)/ret[i].res+0.5);
			ret[i].rad1 = (int)(hight*tan(THETA2 * PI/180)/ret[i].res+0.5);
		}
		else if(nType==ISDBS)
		{
		}
	}

	fclose(fp);


	return ret;
}


SPRCSCALE *  CComlib::ReadPrcScaleItem( int &numb , CString filename)
{
	numb = 0 ;
	SPRCSCALE * ret = NULL ;

	FILE *fp = fopen(filename , "rt"); 
	CString err = filename + "  open  Error!";
	if(! ASSERTVALIDPOINTER(fp, err)) return NULL;

	char version[20];
	fscanf(fp, "Version=%s\n", version);
	if( strcmp(version, VERSION)!=0 )
	{
		AfxMessageBox("Error Version batch file!");
		numb=-1;
		return ret;
	}

	fscanf(fp, "numbs = %d\n", &numb);
	if( numb <= 0 ) return NULL;
	ret = (SPRCSCALE * ) fspace_1d(numb , sizeof(SPRCSCALE) );

	for(int i=0;i<numb;i++)
	{
		int row, col, nHalfSize;
		char SrcFile[80], DesFile[80], PathName[80];

		// PrcScale dRow dCol PathName SrcFile DesFile
		fscanf(fp, "PrcScale dRow=%d dCol=%d nHalfSize=%d PathName=%s SrcFile=%s DesFile=%s\n",
			&row, &col , &nHalfSize , PathName , SrcFile , DesFile);
	
		ret[i].row = row ; 
		ret[i].col = col ; 
		ret[i].nHalfSize = nHalfSize ; 
		
		strcpy(ret[i].PathName , PathName );
		strcpy(ret[i].SrcFile , SrcFile );
		strcpy(ret[i].DesFile , DesFile );
	}

	fclose(fp);

	return ret;
}

BOOL CComlib::PrcThenScale( SPRCSCALE in)
{
	BOOL ret = TRUE;

	int sRow, sCol;
	int HalfSize = in.nHalfSize;
	int dRow = in.row;
	int dCol = in.col;

⌨️ 快捷键说明

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