📄 suanfa.cpp
字号:
/**************************************************************************
* 车牌定位函数库:
* myMedianFilter() - 图像中值滤波。
* myGetMedianNum() - 获取中值。被函数MedianFilter()调用来求中值。
* ConvertToGrayScale(); - 24位真彩色图转换成灰度图
* ThresholdTrans(); - 阀值变换
* myTemplate(); - 图像模板变换,通过改变模板,可以用它实现图像的平滑、锐化、边缘识别等操作。
* myHprojectDIB(); - 水平投影
* myVprojectDIB() ; - 垂直投影
* myCropDIB(); - 区域剪裁
*************************************************************************/
#include "stdafx.h"
#include "SuanFa.h"
#include <math.h>
/*************************************************************************
*
* 函数名称:
* ConvertToGrayScale()
*
* 参数:
* LPSTR lpDIB - 指向源DIB图像指针
*
* 返回值:
* BOOL - 成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数将24位真彩色图转换成256级灰度图
*
************************************************************************/
BOOL ConvertToGrayScale(LPSTR lpDIB)
{
CDib m_dib;
LPSTR lpDIBBits; //指向DIB的象素的指针
LPSTR lpNewDIBBits; //指向DIB灰度图图像(新图像)开始处象素的指针
LONG lLineBytes;
unsigned char * lpSrc; //指向原图像象素点的指针
unsigned char * lpdest; //指向目标图像象素点的指针
unsigned char *ired,*igreen,*iblue;
long lWidth; //图像宽度和高度
long lHeight;
long i,j; //循环变量
lWidth = m_dib.DIBWidth(lpDIB); //DIB 宽度
lHeight = m_dib.DIBHeight(lpDIB); //DIB 高度
RGBQUAD *lpRGBquad;
lpRGBquad = (RGBQUAD *)&lpDIB[sizeof(BITMAPINFOHEADER)]; //INFOHEADER后为调色板
if(m_dib.DIBNumColors(lpDIB) == 256) //256色位图不作任何处理
{
return TRUE;
}
if(m_dib.DIBNumColors(lpDIB) != 256) //非256色位图将它灰度化
{
lLineBytes = WIDTHBYTES(lWidth*8*3);
lpdest= new BYTE[lHeight*lWidth];
lpDIBBits = (LPSTR)lpDIB + sizeof(BITMAPINFOHEADER);//指向DIB象素
for(i = 0;i < lHeight; i++)
for(j = 0;j < lWidth*3; j+=3)
{
ired = (unsigned char*)lpDIBBits + lLineBytes * i + j + 2;
igreen = (unsigned char*)lpDIBBits + lLineBytes * i + j + 1;
iblue = (unsigned char*)lpDIBBits + lLineBytes * i + j ;
lpdest[i*lWidth + j/3] = (unsigned char)((*ired)*0.299 + (*igreen)*0.588 + (*iblue)*0.114);
}
//修改INFOHEADER、增加调色板、修改原图像灰度值
LPBITMAPINFOHEADER lpBI;
lpBI = (LPBITMAPINFOHEADER)lpDIB;
lpBI->biBitCount = 8;
//设置灰度调色板
for(i = 0;i < 256;i++)
{
lpRGBquad[i].rgbRed = (unsigned char)i;
lpRGBquad[i].rgbGreen = (unsigned char)i;
lpRGBquad[i].rgbBlue = (unsigned char)i;
lpRGBquad[i].rgbReserved = 0;
}
lpNewDIBBits= m_dib.FindDIBBits(lpDIB); //找到DIB图像象素起始位置
lLineBytes=WIDTHBYTES(lWidth * 8);
//修改灰度值
for(i = 0;i < lHeight; i++)
for(j = 0;j < lWidth; j++)
{
lpSrc = (unsigned char*)lpNewDIBBits + lLineBytes * i+ j ;
*lpSrc=lpdest[i*lWidth+j];
}
delete lpdest;
}
return true;
}
/*************************************************************************
*
* 函数名称:
* ThresholdTrans()
*
* 参数:
* LPSTR lpDIBBits - 指向源DIB图像指针
* LONG lWidth - 源图像宽度(象素数)
* LONG lHeight - 源图像高度(象素数)
* BYTE bThre - 阈值
*
* 返回值:
* BOOL - 成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数用来对图像进行阈值变换。对于灰度值小于阈值的象素直接设置
* 灰度值为0;灰度值大于阈值的象素直接设置为255。
*
************************************************************************/
BOOL ThresholdTrans(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, BYTE bThre)
{
CDib m_dib;
// 指向源图像的指针
unsigned char* lpSrc;
// 循环变量
LONG i;
LONG j;
// 图像每行的字节数
LONG lLineBytes;
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
// 每行
for(i = 0; i < lHeight; i++)
{
// 每列
for(j = 0; j < lWidth; j++)
{
// 指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
// 判断是否小于阈值
if ((*lpSrc) < bThre)
{
// 直接赋值为0
*lpSrc = 0;
}
else
{
// 直接赋值为255
*lpSrc = 255;
}
}
}
// 返回
return TRUE;
}
/*************************************************************************
*
* 函数名称:
* myTemplate()
*
* 参数:
* LPSTR lpDIBBits - 指向源DIB图像指针
* 返回值:
* BOOL - 成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数用指定的模板来对图像进行操作,使相邻像素灰度值相减。
*
************************************************************************/
BOOL myTemplate(LPSTR lpDIB)
{
CDib m_dib;
// 指向复制图像的指针
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits;
// 指向要复制区域的指针
unsigned char* lpDst;
LPSTR lpDIBBits; //指向DIB的象素的指针
LONG lLineBytes; // 图像每行的字节数
unsigned char * lpSrc; //指向原图像象素点的指针
long lWidth; //图像宽度和高度
long lHeight;
// 计算结果
INT fResult;
// 找到DIB图像象素起始位置
lpDIBBits = m_dib.FindDIBBits(lpDIB);
lWidth = m_dib.DIBWidth(lpDIB); //DIB 宽度
lHeight = m_dib.DIBHeight(lpDIB); //DIB 高度
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
// 暂时分配内存,以保存新图像
hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);
// 判断是否内存分配失败
if (hNewDIBBits == NULL)
{
// 分配内存失败
return false;
}
// 锁定内存
lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
// 初始化图像为原始图像
memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * lHeight);
long i,j; //循环变量
//每行
for(i = 0; i < lHeight-1; i++)
{
// 每列
for(j = 0; j < lWidth-1; j++)
{
// 指向新DIB第i行,第j个象素的指针
lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j;
// 指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
fResult=(*lpSrc)-(*(lpSrc+1));
// 取绝对值
if(fResult<0) fResult=-fResult;
// 判断是否超过255
if(fResult > 255)
{
// 直接赋值为255
* lpDst = 255;
}
else
{
// 赋值
* lpDst = (unsigned char) (fResult + 0.5);
}
}
}
// 复制变换后的图像
memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
// 释放内存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
// 返回
return TRUE;
}
/*************************************************************************
*
* 函数名称:
* myHprojectDIB()
*
* 参数:
* LPSTR lpDIBBits - 指向源DIB图像指针
* LONG lWidth - 源图像宽度(象素数)
* LONG lHeight - 源图像高度(象素数)
* INT* iTop - 车牌上边缘
* INT* iBottom - 车牌下边缘
* 返回值:
* BOOL - 成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数用于对含车牌图像进行水平投影运算,求取车牌子图像的上下边缘位置
*
************************************************************************/
BOOL myHprojectDIB(LPSTR lpDIB, LONG lWidth, LONG lHeight,
int* iTop, int* iBottom)
{
CDib m_dib;
LPSTR lpDIBBits; //指向DIB的象素的指针
LONG lLineBytes; // 图像每行的字节数
unsigned char * lpSrc; //指向原图像象素点的指针
unsigned char pixel; //像素值
int i,j;
// 计算结果
INT* iResult;
INT pzBottom,pzTop;
bool findPZ=false;
// 找到DIB图像象素起始位置
lpDIBBits = m_dib.FindDIBBits(lpDIB);
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
iResult=new INT[lHeight];
for(i=0;i<lHeight;i++)
iResult[i]=0;
for(j=lHeight/5;j<lHeight*0.8;j++)
{
iResult[j]=0;
for(i=0;i<lWidth;i++)
{
lpSrc=(unsigned char*)lpDIBBits+lLineBytes*j+i;
pixel=(unsigned char)(*lpSrc);
if(pixel==255)
{
iResult[j]++;
}
}
if((!findPZ)&&iResult[j]>12)
{
pzBottom=j;
findPZ=true;
}
if(findPZ&&iResult[j]<12)
{
pzTop=j;
break;
}
}
pzTop=pzBottom+55;
pzBottom=pzBottom-20; //微量调整
*iBottom=lHeight-pzBottom;
*iTop=lHeight-pzTop;
return true;
}
/*************************************************************************
*
* 函数名称:
* myVprojectDIB()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -