www.pudn.com > isee_code01231.zip > Filter.cpp


//	未完成文件 
#include "stdafx.h" 
#include "filter.h" 
#include "AdjustContrast.h" 
#include "System.h" 
#include "ConvoluteKernel.h" 
 
#define	FILTER1			1 
#define	FILTER2			2 
#define FILTER3			3 
 
void _fnSPE_Filter(int *red,int *green,int *blue,int i,int j, 
				   WORD wBytesPerLine,LPBYTE lpData,DWORD *dwFact) 
{ 
	BYTE b[9],g[9],r[9]; 
	LONG lOffset; 
//	DWORD dwGrayList[9],dwAddList[9]; 
	DWORD dwGrayTotal,dwDivisor,dwGray,dwTemp; 
 
	lOffset=(LONG)(i-1)*(LONG)wBytesPerLine+(LONG)((j-1)*4); 
//	dwAddList[0]=lOffset; 
	b[0]=*(lpData+lOffset++); 
	g[0]=*(lpData+lOffset++); 
	r[0]=*(lpData+lOffset); 
 
	lOffset=(LONG)(i-1)*(LONG)wBytesPerLine+(LONG)((j)*4); 
//	dwAddList[1]=lOffset; 
	b[1]=*(lpData+lOffset++); 
	g[1]=*(lpData+lOffset++); 
	r[1]=*(lpData+lOffset); 
 
	lOffset=(LONG)(i-1)*(LONG)wBytesPerLine+(LONG)((j+1)*4); 
//	dwAddList[2]=lOffset; 
	b[2]=*(lpData+lOffset++); 
	g[2]=*(lpData+lOffset++); 
	r[2]=*(lpData+lOffset); 
 
	lOffset=(LONG)(i)*(LONG)wBytesPerLine+(LONG)((j-1)*4); 
//	dwAddList[3]=lOffset; 
	b[3]=*(lpData+lOffset++); 
	g[3]=*(lpData+lOffset++); 
	r[3]=*(lpData+lOffset); 
 
	lOffset=(LONG)(i)*(LONG)wBytesPerLine+(LONG)((j)*4); 
//	dwAddList[4]=lOffset; 
	b[4]=*(lpData+lOffset++); 
	g[4]=*(lpData+lOffset++); 
	r[4]=*(lpData+lOffset); 
 
	lOffset=(LONG)(i)*(LONG)wBytesPerLine+(LONG)((j+1)*4); 
//	dwAddList[5]=lOffset; 
	b[5]=*(lpData+lOffset++); 
	g[5]=*(lpData+lOffset++); 
	r[5]=*(lpData+lOffset); 
 
	lOffset=(LONG)(i+1)*(LONG)wBytesPerLine+(LONG)((j-1)*4); 
//	dwAddList[6]=lOffset; 
	b[6]=*(lpData+lOffset++); 
	g[6]=*(lpData+lOffset++); 
	r[6]=*(lpData+lOffset); 
 
	lOffset=(LONG)(i+1)*(LONG)wBytesPerLine+(LONG)((j)*4); 
//	dwAddList[7]=lOffset; 
	b[7]=*(lpData+lOffset++); 
	g[7]=*(lpData+lOffset++); 
	r[7]=*(lpData+lOffset); 
 
	lOffset=(LONG)(i+1)*(LONG)wBytesPerLine+(LONG)((j+1)*4); 
//	dwAddList[8]=lOffset; 
	b[8]=*(lpData+lOffset++); 
	g[8]=*(lpData+lOffset++); 
	r[8]=*(lpData+lOffset); 
 
	dwGrayTotal=dwDivisor=0;	 
	for(int k=0;k<9;k++) 
	{ 
		dwGrayTotal+=((r[k]*30+g[k]*59+b[k]*11)/100)*dwFact[k]; 
		dwDivisor+=dwFact[k]; 
	} 
 
	dwGrayTotal /= dwDivisor;				 
	dwGray = (r[4]*30+g[4]*59+b[4]*11)/100; 
	lOffset=(LONG)(i)*(LONG)wBytesPerLine+(LONG)((j)*4); 
 
	if( dwGray != 0 )  
		dwTemp = ( ( *(lpData+lOffset++) * dwGrayTotal ) / dwGray ); 
	else  
		dwTemp = ( dwGrayTotal + dwGray ) / 2; 
	if( dwTemp > 255 )  
		dwTemp = 255; 
	*blue = (unsigned char) dwTemp; 
	if( dwGray != 0 ) 
		dwTemp = ( ( *(lpData+lOffset++) * dwGrayTotal ) / dwGray ); 
	else  
		dwTemp = ( dwGrayTotal + dwGray ) / 2; 
	if( dwTemp > 255 )  
		dwTemp = 255; 
	*green = (unsigned char) dwTemp; 
	if( dwGray != 0 )  
		dwTemp = ( ( *(lpData+lOffset++) * dwGrayTotal ) / dwGray ); 
	else  
		dwTemp = ( dwGrayTotal + dwGray ) / 2; 
	if( dwTemp > 255 )  
		dwTemp = 255; 
	*red = (unsigned char) dwTemp; 
} 
 
BOOL _fnCOM_HighFilter(LPIMAGEPROCSTR lpInfo,int nStrength,int nStype) 
{ 
	CopyMemory(lpInfo->_pdbdata ,lpInfo->_psbdata ,lpInfo->sImageInfo.width*lpInfo->sImageInfo.height*(lpInfo->sImageInfo.bitperpix/8)); 
 
	WORD skip=lpInfo->sImageInfo .byteperline ; 
	static DWORD dwFact[9]; 
 
	switch(nStype) 
	{ 
	case 0: 
		dwFact[0]=10; 
		dwFact[1]=10; 
		dwFact[2]=10; 
		dwFact[3]=10; 
		dwFact[4]=160+nStrength; 
		dwFact[5]=10; 
		dwFact[6]=10; 
		dwFact[7]=10; 
		dwFact[8]=10; 
		break; 
	case 1: 
		dwFact[0]=10; 
		dwFact[1]=10; 
		dwFact[2]=10; 
		dwFact[3]=10; 
		dwFact[4]=10; 
		dwFact[5]=10; 
		dwFact[6]=10; 
		dwFact[7]=10; 
		dwFact[8]=10; 
		break; 
	} 
 
	UINT i,j; 
	for(i=1;i<(UINT)lpInfo->sImageInfo.height-1;i++) 
	{ 
		for(j=1;j<(UINT)lpInfo->sImageInfo.width-1;j++) 
		{ 
			int red=0,green=0,blue=0; 
			 
			_fnSPE_Filter(&red,&green,&blue,i,j,skip,lpInfo->_psbdata,dwFact); 
			LONG lOffset=(LONG)(i*skip)+(LONG)(j*4); 
 
			*(lpInfo->_pdbdata+lOffset++)=(BYTE)((blue)<(0)?(0):((blue)>(255)?(255):(blue))); 
			*(lpInfo->_pdbdata+lOffset++)=(BYTE)((green)<(0)?(0):((green)>(255)?(255):(green))); 
			*(lpInfo->_pdbdata+lOffset)=(BYTE)((red)<(0)?(0):((red)>(255)?(255):(red))); 
		} 
	} 
 
	return PROCERR_SUCCESS; 
} 
 
void _fnSPE_MedianFilter(int *red,int *green,int *blue,int i,int j, 
						 int nPels,WORD wBytesPerLine,LPBYTE lpData, 
						 int nStype) 
{ 
	BYTE b[9],g[9],r[9]; 
	LONG lOffset; 
	DWORD dwMedianList[9],dwAddList[9]; 
 
	lOffset=(LONG)(i-1)*(LONG)wBytesPerLine+(LONG)((j-1)*4); 
	dwAddList[0]=lOffset; 
	b[0]=*(lpData+lOffset++); 
	g[0]=*(lpData+lOffset++); 
	r[0]=*(lpData+lOffset); 
 
	lOffset=(LONG)(i-1)*(LONG)wBytesPerLine+(LONG)((j)*4); 
	dwAddList[1]=lOffset; 
	b[1]=*(lpData+lOffset++); 
	g[1]=*(lpData+lOffset++); 
	r[1]=*(lpData+lOffset); 
 
	lOffset=(LONG)(i-1)*(LONG)wBytesPerLine+(LONG)((j+1)*4); 
	dwAddList[2]=lOffset; 
	b[2]=*(lpData+lOffset++); 
	g[2]=*(lpData+lOffset++); 
	r[2]=*(lpData+lOffset); 
 
	lOffset=(LONG)(i)*(LONG)wBytesPerLine+(LONG)((j-1)*4); 
	dwAddList[3]=lOffset; 
	b[3]=*(lpData+lOffset++); 
	g[3]=*(lpData+lOffset++); 
	r[3]=*(lpData+lOffset); 
 
	lOffset=(LONG)(i)*(LONG)wBytesPerLine+(LONG)((j)*4); 
	dwAddList[4]=lOffset; 
	b[4]=*(lpData+lOffset++); 
	g[4]=*(lpData+lOffset++); 
	r[4]=*(lpData+lOffset); 
 
	lOffset=(LONG)(i)*(LONG)wBytesPerLine+(LONG)((j+1)*4); 
	dwAddList[5]=lOffset; 
	b[5]=*(lpData+lOffset++); 
	g[5]=*(lpData+lOffset++); 
	r[5]=*(lpData+lOffset); 
 
	lOffset=(LONG)(i+1)*(LONG)wBytesPerLine+(LONG)((j-1)*4); 
	dwAddList[6]=lOffset; 
	b[6]=*(lpData+lOffset++); 
	g[6]=*(lpData+lOffset++); 
	r[6]=*(lpData+lOffset); 
 
	lOffset=(LONG)(i+1)*(LONG)wBytesPerLine+(LONG)((j)*4); 
	dwAddList[7]=lOffset; 
	b[7]=*(lpData+lOffset++); 
	g[7]=*(lpData+lOffset++); 
	r[7]=*(lpData+lOffset); 
 
	lOffset=(LONG)(i+1)*(LONG)wBytesPerLine+(LONG)((j+1)*4); 
	dwAddList[8]=lOffset; 
	b[8]=*(lpData+lOffset++); 
	g[8]=*(lpData+lOffset++); 
	r[8]=*(lpData+lOffset); 
 
//	以下应有更好的算法,不过我还没想好。 
/* 
	qsort(r,9,1,Compare);		 
	qsort(g,9,1,Compare); 
	qsort(b,9,1,Compare); 
 
	switch(nStype) 
	{ 
	case 0: 
		*red=r[4]; 
		*green=g[4]; 
		*blue=b[4]; 
		break; 
	case 1: 
		*red=r[0]; 
		*green=g[0]; 
		*blue=b[0]; 
		break; 
	case 2: 
		*red=r[8]; 
		*green=g[8]; 
		*blue=b[8]; 
		break; 
	} 
*/ 
 
//	新的算法,几乎快了3倍^_^ 
 
	for(int k=0;k<9;k++) 
	{ 
		dwMedianList[k]=(r[k]*30+g[k]*59+b[k]*11)/100; 
	}	 
	 
	for( i=1; i<9; i++ ) 
	{ 
		for( j=0; jj; k-- ) 
				{ 
					dwMedianList[k] = dwMedianList[k-1]; 
					dwAddList[k] = dwAddList[k-1]; 
				} 
				dwMedianList[j] = dwTmp; 
				dwAddList[j] = nTmp; 
				break; 
			} 
		} 
	} 
	switch(nStype) 
	{ 
	case 0: 
		*blue=*(lpData+dwAddList[4]++); 
		*green=*(lpData+dwAddList[4]++); 
		*red=*(lpData+dwAddList[4]); 
		break; 
	case 1: 
		*blue=*(lpData+dwAddList[0]++); 
		*green=*(lpData+dwAddList[0]++); 
		*red=*(lpData+dwAddList[0]); 
		break; 
	case 2: 
		*blue=*(lpData+dwAddList[8]++); 
		*green=*(lpData+dwAddList[8]++); 
		*red=*(lpData+dwAddList[8]); 
		break; 
	} 
 
} 
 
BOOL _fnCOM_MedianFilter(LPIMAGEPROCSTR lpInfo,int nPels,int nStype) 
{ 
	CopyMemory(lpInfo->_pdbdata ,lpInfo->_psbdata ,lpInfo->sImageInfo.width*lpInfo->sImageInfo.height*(lpInfo->sImageInfo.bitperpix/8)); 
 
	WORD skip=lpInfo->sImageInfo .byteperline ; 
 
	UINT i,j; 
	for(i=1;i<(UINT)lpInfo->sImageInfo.height-1;i++) 
	{ 
		for(j=1;j<(UINT)lpInfo->sImageInfo.width-1;j++) 
		{ 
			int red=0,green=0,blue=0; 
			 
			_fnSPE_MedianFilter(&red,&green,&blue,i,j,1,skip,lpInfo->_psbdata,nStype); 
			LONG lOffset=(LONG)(i*skip)+(LONG)(j*4); 
 
			*(lpInfo->_pdbdata+lOffset++)=(BYTE)((blue)<(0)?(0):((blue)>(255)?(255):(blue))); 
			*(lpInfo->_pdbdata+lOffset++)=(BYTE)((green)<(0)?(0):((green)>(255)?(255):(green))); 
			*(lpInfo->_pdbdata+lOffset)=(BYTE)((red)<(0)?(0):((red)>(255)?(255):(red))); 
		} 
	} 
 
	return PROCERR_SUCCESS; 
}