ip.cpp

来自「自己用VC6.0编写的用遗传算法进行图像分割的软件」· C++ 代码 · 共 2,526 行 · 第 1/4 页

CPP
2,526
字号
	if (!hFilteredBits) 
	{
		WaitCursorEnd();
		return FALSE;
	}
	LPBYTE lpDestImage = (LPBYTE)GlobalLock(hFilteredBits);

	// get bits address in DIB
	LPBITMAPINFO lpbmi=(LPBITMAPINFO)GlobalLock(hNewDib);
	DWORD buffersize=GlobalSize(lpbmi);
	LPBYTE lpDIBits=(LPBYTE)lpbmi+buffersize-dwImageSize;
//	LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);
//	LPBYTE lpDIBits = FindDIBBits(lpDIB);
//	LPBITMAPINFO lpbm=(LPBITMAPINFO)lpDIB;
	if (!lpDIBits) 
	{
		WaitCursorEnd();
		return FALSE;
	}
	// convolute...
	for (int i=1; i<wDIBHeight-2; i++) 
		for (int j=1; j<wDIBWidth-2; j++) 
		{
			double gray=0;
			for (int k=0; k<nKernelNum; ++k)
			{
				float g=0;
				DoConvoluteDIB(&g, i, j, 
					wBytesPerLine, lpDIBits, lpKernel+k);
				if(g>gray)
					gray=g;
	//			gray +=g;
				//red += r; green += g; blue += b;
			}
			// original RGB value in center pixel  (j, i)
			LONG lOffset= PIXEL_OFFSET(i,j, wBytesPerLine);
			BYTE OLDG=*(lpDIBits+lOffset);
			// When we get here, red, green and blue have the new RGB value.
			if (Strength != 10) 
			{
				gray=OLDG+(((gray - OLDG) * Strength) / 10);
			}
			else
				OLDG=(BYTE) BOUND(gray, 0, 255);
			*(lpDestImage + lOffset)   =OLDG;
		}

	// a filtered image is available in lpDestImage
	// copy it to DIB bits
	memcpy(lpDIBits, lpDestImage, dwImageSize);

	// cleanup temp buffers
	GlobalUnlock(hFilteredBits);
	GlobalFree(hFilteredBits);
	//GlobalUnlock(hNewDib);

	// rebuild hDib
	//HDIB hTmp = NULL;
//	if (wBitCount != 24)
//		hTmp = ConvertDIBFormat(hNewDib, wBitCount, NULL);
//	else
//		hTmp = CopyHandle(hNewDib);
	//hTmp = CopyHandle(hNewDib);
	//GlobalFree(hNewDib);
	DWORD dwSize = GlobalSize(hNewDib);
	memcpy((LPBYTE)GlobalLock(hDib), (LPBYTE)GlobalLock(hNewDib), dwSize);
	GlobalUnlock(hNewDib);
	GlobalFree(hNewDib);
	GlobalUnlock(hDib);
	WaitCursorEnd();

	return TRUE;
}

// local function: perform convolution to DIB with a kernel
//void DoConvoluteDIB(int *red, int *green, int *blue, int i, int j, 
//			WORD wBytesPerLine, LPBYTE lpDIBits, KERNEL *lpKernel)
void DoConvoluteDIB(float *gray,int i,int j,
					WORD wBytesPerLine, LPBYTE lpDIBits, KERNEL *lpKernel)
{
	BYTE g[9];
	LONG lOffset;	
	lOffset= PIXEL_OFFSET((i-1),(j-1), wBytesPerLine);
	g[0] = *(lpDIBits + lOffset);
	BYTE g0=g[0];
	lOffset= PIXEL_OFFSET(i-1,j, wBytesPerLine);
	g[1] = *(lpDIBits + lOffset);
	BYTE g1=g[1];
	lOffset= PIXEL_OFFSET(i-1,j+1, wBytesPerLine);
	g[2] = *(lpDIBits + lOffset);
	BYTE g2=g[2];
	lOffset= PIXEL_OFFSET(i,j-1, wBytesPerLine);
	g[3] = *(lpDIBits + lOffset);
	BYTE g3=g[3];
	lOffset= PIXEL_OFFSET(i,j, wBytesPerLine);
	g[4] = *(lpDIBits + lOffset);
	BYTE g4=g[4];
	lOffset= PIXEL_OFFSET(i,j+1, wBytesPerLine);
	g[5] = *(lpDIBits + lOffset);
	BYTE g5=g[5];
	lOffset= PIXEL_OFFSET(i+1,j-1, wBytesPerLine);
	g[6] = *(lpDIBits + lOffset);
	BYTE g6=g[6];
	lOffset= PIXEL_OFFSET(i+1,j, wBytesPerLine);
	g[7] = *(lpDIBits + lOffset);
	BYTE g7=g[7];
	lOffset= PIXEL_OFFSET(i+1,j+1, wBytesPerLine);
	g[8] = *(lpDIBits + lOffset);
	BYTE g8=g[8];
	for (int k=0; k<9; ++k)
	{
		*gray+=lpKernel->Element[k]*g[k];
	}

	if (lpKernel->Divisor != 1) 
	{
		*gray/=lpKernel->Divisor;
	}
//	*gray=(*gray>=0)?*gray:-*gray;
//	*gray=abs(*gray);
}

// local function: perform median filter to DIB
void DoMedianFilterDIB(int *red, int *green, int *blue, int i, int j, 
			WORD wBytesPerLine, LPBYTE lpDIBits)
{
	BYTE b[9], g[9], r[9];
	LONG lOffset;
	
	lOffset= PIXEL_OFFSET(i-1,j-1, wBytesPerLine);
	b[0] = *(lpDIBits + lOffset++);
	g[0] = *(lpDIBits + lOffset++);
	r[0] = *(lpDIBits + lOffset);

	lOffset= PIXEL_OFFSET(i-1,j, wBytesPerLine);
	b[1] = *(lpDIBits + lOffset++);
	g[1] = *(lpDIBits + lOffset++);
	r[1] = *(lpDIBits + lOffset);

	lOffset= PIXEL_OFFSET(i-1,j+1, wBytesPerLine);
	b[2] = *(lpDIBits + lOffset++);
	g[2] = *(lpDIBits + lOffset++);
	r[2] = *(lpDIBits + lOffset);

	lOffset= PIXEL_OFFSET(i,j-1, wBytesPerLine);
	b[3] = *(lpDIBits + lOffset++);
	g[3] = *(lpDIBits + lOffset++);
	r[3] = *(lpDIBits + lOffset);

	lOffset= PIXEL_OFFSET(i,j, wBytesPerLine);
	b[4] = *(lpDIBits + lOffset++);
	g[4] = *(lpDIBits + lOffset++);
	r[4] = *(lpDIBits + lOffset);

	lOffset= PIXEL_OFFSET(i,j+1, wBytesPerLine);
	b[5] = *(lpDIBits + lOffset++);
	g[5] = *(lpDIBits + lOffset++);
	r[5] = *(lpDIBits + lOffset);

	lOffset= PIXEL_OFFSET(i+1,j-1, wBytesPerLine);
	b[6] = *(lpDIBits + lOffset++);
	g[6] = *(lpDIBits + lOffset++);
	r[6] = *(lpDIBits + lOffset);

	lOffset= PIXEL_OFFSET(i+1,j, wBytesPerLine);
	b[7] = *(lpDIBits + lOffset++);
	g[7] = *(lpDIBits + lOffset++);
	r[7] = *(lpDIBits + lOffset);

	lOffset= PIXEL_OFFSET(i+1,j+1, wBytesPerLine);
	b[8] = *(lpDIBits + lOffset++);
	g[8] = *(lpDIBits + lOffset++);
	r[8] = *(lpDIBits + lOffset);

    qsort(r, 9, 1, compare);
    qsort(g, 9, 1, compare);
    qsort(b, 9, 1, compare);

	*red   = r[0];
	*green = g[0];
	*blue  = b[0];
}

// function used to sort in the call of qsort
int compare(const void *e1, const void *e2)
{
	if (*(BYTE *)e1 < *(BYTE *)e2)
		return -1;
	if (*(BYTE *)e1 > *(BYTE *)e2)
		return 1;

	return 0;
}

/************************************************************************* 
 * 
 * ReverseDIB() 
 * 
 * Parameters: 
 * 
 * HDIB hDib        - objective DIB handle
 * 
 * Return Value: 
 * 
 * BOOL             - True is success, else False
 * 
 * Description: 
 * 
 * This function reverse DIB
 * 
 ************************************************************************/ 
BOOL ReverseDIB(HDIB hDib) 
{
	WaitCursorBegin();

	HDIB hNewDib = NULL;
	// only support 256 grayscale image
	WORD wBitCount = DIBBitCount(hDib);
	if (wBitCount != 8)
	{
		WaitCursorEnd();
		return FALSE;
	}

	// the maxium pixel value
	int  nMaxValue = 256;

	// source pixel data
    LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDib);
	if (! lpSrcDIB)
	{
		WaitCursorBegin();
		return FALSE;
	}

	// new DIB attributes
	LPSTR lpPtr;
	LONG lHeight = DIBHeight(lpSrcDIB);
	LONG lWidth = DIBWidth(lpSrcDIB);
	DWORD dwBufferSize = GlobalSize(lpSrcDIB);
	int nLineBytes = BytesPerLine(lpSrcDIB);

	// convolute...
	for (long i=0; i<lHeight; i++) 
		for (long j=0; j<lWidth; j++) 
		{
			lpPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-i*nLineBytes)+j;
			*lpPtr = nMaxValue - *lpPtr;
		}

	// cleanup
	GlobalUnlock(hDib);
	WaitCursorEnd();

	return TRUE;
}

/************************************************************************* 
 * 
 * ErosionDIB() 
 * 
 * Parameters: 
 * 
 * HDIB hDib        - objective DIB handle
 * BOOL bHori	    - erosion direction
 * 
 * Return Value: 
 * 
 * BOOL             - True is success, else False
 * 
 * Description: 
 * 
 * This function do erosion with the specified direction
 * 
 ************************************************************************/ 
BOOL ErosionDIB(HDIB hDib, BOOL bHori)
{
	// start wait cursor
	WaitCursorBegin();

    // Old DIB buffer
	if (hDib == NULL)
	{
		WaitCursorEnd();
        return FALSE;
	}

	// only support 256 color image
	WORD wBitCount = DIBBitCount(hDib);
	if (wBitCount != 8)
	{
		WaitCursorEnd();
        return FALSE;
	}

	// new DIB
	HDIB hNewDIB = CopyHandle(hDib);
	if (! hNewDIB)
	{
		WaitCursorEnd();
        return FALSE;
	}

	// source dib buffer
    LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDib);
	if (! lpSrcDIB)
	{
		WaitCursorBegin();
		return FALSE;
	}
    // New DIB buffer
    LPBITMAPINFO lpbmi = (LPBITMAPINFO)GlobalLock(hNewDIB);
	if (! lpbmi)
	{
		WaitCursorBegin();
		return FALSE;
	}

	// start erosion...
	LPSTR lpPtr;
	LPSTR lpTempPtr;
	LONG  x,y;
	BYTE  num, num0;
	int   i;
	LONG lHeight = DIBHeight(lpSrcDIB);
	LONG lWidth = DIBWidth(lpSrcDIB);
	DWORD dwBufferSize = GlobalSize(lpSrcDIB);
	int nLineBytes = BytesPerLine(lpSrcDIB);
	if(bHori)
	{
		for (y=0; y<lHeight; y++)
		{
			lpPtr=(char *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes)+1;
			lpTempPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes)+1;
			for (x=1; x<lWidth-1; x++)
			{
				num0 = num = 0 ;
				for(i=0;i<3;i++)
				{
					num=(unsigned char)*(lpPtr+i-1);
					if(num > num0)
						num0 = num;
				}
				*lpTempPtr=(unsigned char)num0;
				/*
				num=(unsigned char)*lpPtr;
				if (num==0)
				{
					*lpTempPtr=(unsigned char)0;
					for(i=0;i<3;i++)
					{
						num=(unsigned char)*(lpPtr+i-1);
						if(num==255)
						{
							*lpTempPtr=(unsigned char)255;
							break;
						}
					}
				}
				else 
					*lpTempPtr=(unsigned char)255;
				*/
				lpPtr++;
				lpTempPtr++;
			}
		}
	}
	else		// Vertical
	{
		for (y=1; y<lHeight-1; y++)
		{
			lpPtr=(char *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes);
			lpTempPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes);
			for (x=0; x<lWidth; x++)
			{
				num0 = num = 0 ;
				for(i=0;i<3;i++)
				{
					num=(unsigned char)*(lpPtr+i-1);
					if(num > num0)
						num0 = num;
				}
				*lpTempPtr=(unsigned char)num0;
				/*
				num=(unsigned char)*lpPtr;
				if (num==0)
				{
					*lpTempPtr=(unsigned char)0;
					for(i=0;i<3;i++)
					{
						num=(unsigned char)*(lpPtr+(i-1)*nLineBytes);
						if(num==255)
						{
							*lpTempPtr=(unsigned char)255;
							break;
						}
					}
				}
				else 
					*lpTempPtr=(unsigned char)255;
				*/
				lpPtr++;
				lpTempPtr++;
			}
		}
	}

	// cleanup
	GlobalUnlock(hDib);
	GlobalUnlock(hNewDIB);
	GlobalFree(hNewDIB);
	WaitCursorEnd();

	return TRUE;
}

/************************************************************************* 
 * 
 * DilationDIB() 
 * 
 * Parameters: 
 * 
 * HDIB hDib        - objective DIB handle
 * BOOL bHori	    - dilation direction
 * 
 * Return Value: 
 * 
 * BOOL             - True is success, else False
 * 
 * Description: 
 * 
 * This function do dilation with the specified direction
 * 
 ************************************************************************/ 
BOOL DilationDIB(HDIB hDib, BOOL bHori)
{
	// start wait cursor
	WaitCursorBegin();

    // Old DIB buffer
	if (hDib == NULL)
	{
		WaitCursorEnd();
        return FALSE;
	}

	// only support 256 color image
	WORD wBitCount = DIBBitCount(hDib);
	if (wBitCount != 8)
	{
		WaitCursorEnd();
        return FALSE;
	}

	// new DIB
	HDIB hNewDIB = CopyHandle(hDib);
	if (! hNewDIB)
	{
		WaitCursorEnd();
        return FALSE;
	}

	// source dib buffer
    LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDib);
	if (! lpSrcDIB)
	{
		WaitCursorBegin();
		return FALSE;
	}
    // New DIB buffer
    LPBITMAPINFO lpbmi = (LPBITMAPINFO)GlobalLock(hNewDIB);
	if (! lpbmi)
	{
		WaitCursorBegin();
		return FALSE;
	}

	// start erosion...
	LPSTR lpPtr;
	LPSTR lpTempPtr;
	LONG  x,y;
	BYTE  num, num0;
	int   i;
	LONG lHeight = DIBHeight(lpSrcDIB);
	LONG lWidth = DIBWidth(lpSrcDIB);
	DWORD dwBufferSize = GlobalSize(lpSrcDIB);
	int nLineBytes = BytesPerLine(lpSrcDIB);
	if(bHori)
	{
		for(y=0;y<lHeight;y++)
		{
			lpPtr=(char *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes)+1;
			lpTempPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes)+1;
			for(x=1;x<lWidth-1;x++)
			{
				num0 = num = 255;
				for(i=0;i<3;i++)
				{
					num=(unsigned char)*(lpPtr+i-1);
					if(num < num0)
						num0 = num;
				}
				*lpTempPtr=(unsigned char)num0;
				/*
				num=(unsigned char)*lpPtr;
				if (num==255)
				{
					*lpTempPtr=(unsigned char)255;
					for(i=0;i<3;i++)
					{
						num=(unsigned char)*(lpPtr+i-1);
						if(num==0)
						{
							*lpTempPtr=(unsigned char)0;
							break;
						}
					}
				}
				else 
					*lpTempPtr=(unsigned char)0;
				*/
				lpPtr++;
				lpTempPtr++;
			}
		}
	}
	else
	{
		for(y=1;y<lHeight-1;y++)
		{
			lpPtr=(char *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes);
			lpTempPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes);
			for(x=0;x<lWidth;x++)
			{
				num0 = num = 255;
				for(i=0;i<3;i++)
				{
					num=(unsigned char)*(lpPtr+i-1);
					if(num < num0)
						num0 = num;
				}
				*lpTempPtr=(unsigned char)num0;
				/*
				num=(unsigned char)*lpPtr;
				if (num==255)
				{
					*lpTempPtr=(unsigned char)255;
					for(i=0;i<3;i++)
					{
						num=(unsigned char)*(lpPtr+(i-1)*nLineBytes);
						if(num==0)
						{
							*lpTempPtr=(unsigned char)0;
							break;
						}
					}
				}
				else 
					*lpTempPtr=(unsigned char)0;
				*/
				lpPtr++;
				lpTempPtr++;
			}
		}
	}

	// cleanup
	GlobalUnlock(hDib);
	GlobalUnlock(hNewDIB);
	GlobalFree(hNewDIB);
	WaitCursorEnd();

	return TRUE;
}

/************************************************************************* 
 * 
 * MorphOpenDIB() 
 * 
 * Parameters: 
 * 
 * HDIB hDib        - objective DIB handle
 * BOOL bHori	    - open direction
 * 
 * Return Value: 
 * 
 * BOOL             - True is success, else False
 * 
 * Description: 
 * 
 * This function do open with the specified direction
 * 
 ************************************************************************/ 
BOOL MorphOpenDIB(HDIB hDib, BOOL bHori)
{
	// Step 1: erosion
	if (! ErosionDIB(hDib, bHori))
		return FALSE;

	// Step 2: dilation	
	if (! DilationDIB(hDib, bHori))
		return FALSE;

	return TRUE;
}

/************************************************************************* 
 * 
 * MorphCloseDIB() 
 * 
 * Parameters: 
 * 
 * HDIB hDib        - objective DIB handle
 * BOOL bHori	    - close direction
 * 
 * Return Value: 
 * 
 * BOOL             - True is success, else False
 * 
 * Description: 
 * 
 * This function do close with the specified direction
 * 
 ************************************************************************/ 
BOOL MorphCloseDIB(HDIB hDib, BOOL bHori)
{
	// Step 1: dilation	
	if (! DilationDIB(hDib, bHori))
		return FALSE;

	// Step 2: erosion
	if (! ErosionDIB(hDib, bHori))

⌨️ 快捷键说明

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