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

📄 suanfa.cpp

📁 基于图象理解的汽车牌照自动识别系统是智能交通系统(ITS)的一个重要分支
💻 CPP
📖 第 1 页 / 共 2 页
字号:
*
* 参数:
*   LPSTR lpDIBBits    - 指向源DIB图像指针
*   LONG  lWidth       - 源图像宽度(象素数)
*   LONG  lHeight      - 源图像高度(象素数)
*   INT*  iLeft        - 车牌左边缘
*   INT*  iRight       - 车牌右边缘
* 返回值:
*   BOOL               - 成功返回TRUE,否则返回FALSE。
*
* 说明:
*   该函数用于对含车牌图像进行垂直投影运算,求取车牌子图像的左右边缘位置
*
************************************************************************/
BOOL myVprojectDIB(LPSTR lpDIB, LONG lWidth, LONG lHeight, 
				   int* iLeft, int* iRight) 
{
	CDib m_dib;
	LPSTR lpDIBBits;                   //指向DIB的象素的指针
	
    LONG lLineBytes;                   // 图像每行的字节数
	unsigned char * lpSrc;             //指向原图像象素点的指针
	
	unsigned char pixel;				//像素值
	
	int i,j;
	
	// 计算结果
	INT* iResult;
	
	INT pzLeft,pzRight;
	
	bool findPZ=false;
	
	// 找到DIB图像象素起始位置
	lpDIBBits = m_dib.FindDIBBits(lpDIB);
	
	// 计算图像每行的字节数
	lLineBytes = WIDTHBYTES(lWidth * 8);
	
	iResult=new INT[lWidth];
	
	for(i=0;i<lWidth;i++)
		iResult[i]=0;
	
	for(i=lWidth/5;i<lWidth*0.8;i++)
	{
		iResult[i]=0;
		for(j=0;j<lHeight;j++)
		{
			lpSrc=(unsigned char*)lpDIBBits+lLineBytes*j+i;
			pixel=(unsigned char)(*lpSrc);
			if(pixel==255)
			{
				iResult[i]++;
			}
		}
		if((!findPZ)&&iResult[i]>10)
		{
			pzLeft=i;
			findPZ=true;
		}
		pzRight=pzLeft+150;
	}
	
	*iLeft=pzLeft-10;
	*iRight=pzRight+10;
	return true;
}

/*************************************************************************
*
* 函数名称:
*   MedianFilter()
*
* 参数:
*   LPSTR lpDIBBits		- 指向源DIB图像指针
*   LONG  lWidth		- 源图像宽度(象素数)
*   LONG  lHeight		- 源图像高度(象素数)
*   int   iFilterH		- 滤波器的高度
*   int   iFilterW		- 滤波器的宽度
*   int   iFilterMX		- 滤波器的中心元素X坐标
*   int   iFilterMY		- 滤波器的中心元素Y坐标
*
* 返回值:
*   BOOL				- 成功返回TRUE,否则返回FALSE。
*
* 说明:
*   该函数对DIB图像进行中值滤波。
*
************************************************************************/

BOOL myMedianFilter(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, 
					int iFilterH, int iFilterW, 
					int iFilterMX, int iFilterMY)
{
	
	// 指向源图像的指针
	unsigned char*	lpSrc;
	
	// 指向要复制区域的指针
	unsigned char*	lpDst;
	
	// 指向复制图像的指针
	LPSTR			lpNewDIBBits;
	HLOCAL			hNewDIBBits;
	
	// 指向滤波器数组的指针
	unsigned char	* aValue;
	HLOCAL			hArray;
	
	// 循环变量
	LONG			i;
	LONG			j;
	LONG			k;
	LONG			l;
	
	// 图像每行的字节数
	LONG			lLineBytes;
	
	// 计算图像每行的字节数
	lLineBytes = WIDTHBYTES(lWidth * 8);
	
	// 暂时分配内存,以保存新图像
	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);
	
	// 判断是否内存分配失败
	if (hNewDIBBits == NULL)
	{
		// 分配内存失败
		return FALSE;
	}
	
	// 锁定内存
	lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
	
	// 初始化图像为原始图像
	memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * lHeight);
	
	// 暂时分配内存,以保存滤波器数组
	hArray = LocalAlloc(LHND, iFilterH * iFilterW);
	
	// 判断是否内存分配失败
	if (hArray == NULL)
	{
		// 释放内存
		LocalUnlock(hNewDIBBits);
		LocalFree(hNewDIBBits);
		
		// 分配内存失败
		return FALSE;
	}
	
	// 锁定内存
	aValue = (unsigned char * )LocalLock(hArray);
	
	// 开始中值滤波
	// 行(除去边缘几行)
	for(i = iFilterMY; i < lHeight - iFilterH + iFilterMY + 1; i++)
	{
		// 列(除去边缘几列)
		for(j = iFilterMX; j < lWidth - iFilterW + iFilterMX + 1; j++)
		{
			// 指向新DIB第i行,第j个象素的指针
			lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j;
			
			// 读取滤波器数组
			for (k = 0; k < iFilterH; k++)
			{
				for (l = 0; l < iFilterW; l++)
				{
					// 指向DIB第i - iFilterMY + k行,第j - iFilterMX + l个象素的指针
					lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i + iFilterMY - k) + j - iFilterMX + l;
					
					// 保存象素值
					aValue[k * iFilterW + l] = *lpSrc;
				}
			}
			
			// 获取中值
			* lpDst = myGetMedianNum(aValue, iFilterH * iFilterW);
		}
	}
	
	// 复制变换后的图像
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
	
	// 释放内存
	LocalUnlock(hNewDIBBits);
	LocalFree(hNewDIBBits);
	LocalUnlock(hArray);
	LocalFree(hArray);
	
	// 返回
	return TRUE;
}

/*************************************************************************
*
* 函数名称:
*   GetMedianNum()
*
* 参数:
*   unsigned char * bpArray	 - 指向要获取中值的数组指针
*   int   iFilterLen		 - 数组长度
*
* 返回值:
*   unsigned char            - 返回指定数组的中值。
*
* 说明:
*   该函数用冒泡法对一维数组进行排序,并返回数组元素的中值。
*
************************************************************************/

unsigned char myGetMedianNum(unsigned char * bArray, int iFilterLen)
{
	// 循环变量
	int		i;
	int		j;
	
	// 中间变量
	unsigned char bTemp;
	
	// 用冒泡法对数组进行排序
	for (j = 0; j < iFilterLen - 1; j ++)
	{
		for (i = 0; i < iFilterLen - j - 1; i ++)
		{
			if (bArray[i] > bArray[i + 1])
			{
				// 互换
				bTemp = bArray[i];
				bArray[i] = bArray[i + 1];
				bArray[i + 1] = bTemp;
			}
		}
	}
	
	// 计算中值
	if ((iFilterLen & 1) > 0)
	{
		// 数组有奇数个元素,返回中间一个元素
		bTemp = bArray[(iFilterLen + 1) / 2];
	}
	else
	{
		// 数组有偶数个元素,返回中间两个元素平均值
		bTemp = (bArray[iFilterLen / 2] + bArray[iFilterLen / 2 + 1]) / 2;
	}
	
	// 返回中值
	return bTemp;
}

/*************************************************************************
*
* 函数名称:
*   myCropDIB()
*
* 参数:
*   HDIB hDIB          - 指向源DIB图像句柄
*   LPRECT lpRect      - 指向要剪裁的矩形区域
*
* 返回值:
*   HDIB               - 返回裁剪后的矩形区域图像句柄。
*
* 说明:
* 该函数用于对指定图像进行指定区域裁剪操作。
* 
* 要求目标图像为255个灰度值的灰度图像。
************************************************************************/

HDIB myCropDIB(HDIB hDIB, LPRECT lpRect)
{
	CDib m_dib;
	
	LPBITMAPINFO lpbmi = NULL; 
    LPBYTE       lpSourceBits, lpTargetBits, lpResult; 
    HDC			 hDC = NULL, hSourceDC, hTargetDC; 
    HBITMAP      hSourceBitmap, hTargetBitmap, hOldTargetBitmap, hOldSourceBitmap; 
    DWORD        dwSourceBitsSize, dwTargetBitsSize, dwTargetHeaderSize; 
	int			 nWidth, nHeight;
	HDIB		 hNewDIB;
	DWORD		 dwSize;
	
	if (! hDIB)
	{
		return NULL;
	}
	LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDIB);
	if (! lpSrcDIB)
	{
		return NULL;
	}
	
    // 得到位图信息 
    dwTargetHeaderSize = sizeof( BITMAPINFOHEADER ) + m_dib.PaletteSize((LPSTR)lpSrcDIB); 
    lpbmi = (LPBITMAPINFO)malloc( dwTargetHeaderSize ); 
	memcpy(lpbmi, lpSrcDIB, dwTargetHeaderSize);
	nWidth = RECTWIDTH(lpRect);
	nHeight = RECTHEIGHT(lpRect);
    lpbmi->bmiHeader.biWidth = nWidth; 
    lpbmi->bmiHeader.biHeight = nHeight; 
	
    //创建位图块 
	hDC = ::GetDC( NULL ); 
    hTargetBitmap = CreateDIBSection( hDC, lpbmi, DIB_RGB_COLORS, (VOID **)&lpTargetBits, NULL, 0 ); 
    hSourceBitmap = CreateDIBSection( hDC, lpSrcDIB, DIB_RGB_COLORS, (VOID **)&lpSourceBits, NULL, 0 ); 
    hSourceDC = CreateCompatibleDC( hDC ); 
    hTargetDC = CreateCompatibleDC( hDC ); 
	
    //匹配源DIB 
    dwSourceBitsSize = lpSrcDIB->bmiHeader.biHeight * m_dib.BytesPerLine((LPBYTE)&(lpSrcDIB->bmiHeader)); 
    dwTargetBitsSize = lpbmi->bmiHeader.biHeight * m_dib.BytesPerLine((LPBYTE)&(lpbmi->bmiHeader)); 
    memcpy( lpSourceBits, m_dib.FindDIBBits((LPSTR)lpSrcDIB), dwSourceBitsSize ); 
    lpbmi->bmiHeader.biSizeImage = dwTargetBitsSize; 
	
    //选择位图块到DC 
    hOldSourceBitmap = (HBITMAP)SelectObject( hSourceDC, hSourceBitmap ); 
    hOldTargetBitmap = (HBITMAP)SelectObject( hTargetDC, hTargetBitmap ); 
	
	//复制旧位图 
    BitBlt(hTargetDC, 0, 0, nWidth, nHeight, hSourceDC, lpRect->left, lpRect->top, SRCCOPY); 
	
    //清除DC
    SelectObject( hSourceDC, hOldSourceBitmap ); 
    SelectObject( hTargetDC, hOldTargetBitmap ); 
    DeleteDC( hSourceDC ); 
    DeleteDC( hTargetDC ); 
    ::ReleaseDC( NULL, hDC ); 
	
    GdiFlush(); 
	
    //分配内存给新的CF_DIB
	dwSize = dwTargetHeaderSize + dwTargetBitsSize;
	hNewDIB =(HDIB)GlobalAlloc(GHND, dwSize);
    lpResult = (LPBYTE)GlobalLock(hNewDIB);//malloc( dwTargetHeaderSize + dwTargetBitsSize ); 
    memcpy( lpResult, lpbmi, dwTargetHeaderSize ); 
    memcpy( m_dib.FindDIBBits( (LPSTR)lpResult ), lpTargetBits, dwTargetBitsSize ); 
	
    //释放内存
    DeleteObject( hTargetBitmap ); 
    DeleteObject( hSourceBitmap ); 
    free( lpbmi ); 
	GlobalUnlock(hDIB);
	GlobalUnlock(hNewDIB);
	
    return hNewDIB;
}

⌨️ 快捷键说明

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