初二如何快速提高成绩:VC++6.0 bmp 灰度二值化

来源:百度文库 编辑:偶看新闻 时间:2024/05/11 05:56:15
用VC++6.0显示BMP文件,,A图
2)在这个图旁边设一个0-100的条,随着灰度数值变化,图像变化,。。B图
急求一个完成程序,好心的大哥大姐们帮帮忙吧
ghsotwolf413 - 一级
其他回答    共 2 条
这玩意你求程序有P用啊。。自己学去吧。
二值化实现只要设定一个阈值,大的变255,小的变0即可~
woshizzza - 五级  2010-6-5 06:28
class CBmp
{
public:
PBITMAPINFO pBmi; //位图信息头+调色板指针
PBYTE pBits; //图像数据指针
public:
CBmp();
//CBMp(const CBmp &bmpObj);
CBmp& operator=( const CBmp &bmpObj );
virtual ~CBmp();
public:
BOOL Read( const CString &Filename ); //读入一幅bmp图像
BOOL Write( const CString &Filename ); //保存一幅bmp图像
int GetWidth( ) const; //获得图像的宽度(像素)
int GetHeight( ) const; //获得图像的高度(像素)
int GetPaletteSize( ) const; //获得调色板长度
int GetBytesPerLine( ) const; //获得存储每行的字节数
BOOL IsValid( ) const; //判断图像是否存在该类对象中
BOOL IsGrayScaleImage( ) const; //判断是否灰度图
BOOL ToGrayScaleImage( ); //转化为灰度图
void Binarize( int threshold ); //对图像进行二值化处理
private:
BOOL ToGrayScaleImage_2Color( ); //单色图像转化为灰度图
BOOL ToGrayScaleImage_16Color( ); //4位位图转化为灰度图
BOOL ToGrayScaleImage_256Color( ); //8位位图转化为灰度图
BOOL ToGrayScaleImage_TrueColor( ); //真彩色位图转化为灰度图
};
CBmp::CBmp()
{
pBmi = NULL;
pBits = NULL;
}
/*
CBmp::CBMp(const CBmp &bmpObj)
{
int nInfoSize = sizeof(BITMAPINFOHEADER) + bmpObj.GetPaletteSize() * sizeof(RGBQUAD);
pBmi = (PBITMAPINFO)new BYTE[nInfoSize];
memcpy( (PVOID)pBmi, (PVOID)bmpObj.pBmi,nInfoSize);
int nImageSize = pBmi->bmiHeader.biSizeImage;
pBits = new BYTE[nImageSize];
memcpy((PVOID)pBits,(PVOID)bmpObj.pBits,nImageSize);
}
*/
CBmp& CBmp::operator=( const CBmp &bmpObj )
{
if ( this == &bmpObj ) //等号两边的对象若是同一个,则不必再做后续操作
return *this;
//销毁原数据
if ( pBmi ) delete pBmi;
if ( pBits ) delete pBits;
//生成新的位图信息头+调色板
int nInfoSize = sizeof( BITMAPINFO ) + bmpObj.GetPaletteSize( ) * sizeof( RGBQUAD );
pBmi = (PBITMAPINFO)new BYTE[ nInfoSize ];
memcpy( (PVOID)pBmi, (PVOID)bmpObj.pBmi, nInfoSize );
//生成新的位图数据
int nImageSize = pBmi->bmiHeader.biSizeImage;
pBits = new BYTE[ nImageSize ];
memcpy( (PVOID)pBits, (PVOID)bmpObj.pBits, nImageSize );
return *this;
}
CBmp::~CBmp()
{
if ( pBmi )
{
delete pBmi;
pBmi = NULL;
}
if ( pBits )
{
delete pBits;
pBits = NULL;
}
}
BOOL CBmp::Read( const CString &FileName )
{
CFile file;
BITMAPFILEHEADER bmfh;
//打开文件
if ( !file.Open(FileName,CFile::modeRead) )
{
AfxMessageBox( \"文件打开错误!\" );
return FALSE;
}
//读文件信息头
file.Read( (PVOID)&bmfh, sizeof(BITMAPFILEHEADER) );
if ( bmfh.bfType != 0x4d42 )
{
AfxMessageBox( \"不是位图文件!\");
return FALSE;
}
//销毁原数据
if ( pBmi )
{
delete pBmi;
pBmi = NULL;
}
if ( pBits )
{
delete pBits;
pBits = NULL;
}
//读位图信息头和调色板
int nInfoSize = bmfh.bfOffBits - sizeof( BITMAPFILEHEADER );
pBmi = (PBITMAPINFO)new BYTE[ nInfoSize ];
file.Read( (PVOID)pBmi, nInfoSize );
if ( pBmi->bmiHeader.biBitCount!=1 && pBmi->bmiHeader.biBitCount!=4 &&
pBmi->bmiHeader.biBitCount!=8 && pBmi->bmiHeader.biBitCount!=24 )
{
CString s;
s.Format( \"%d\", pBmi->bmiHeader.biBitCount );
AfxMessageBox( (CString)\"颜色位数为\"+s+(CString)\"位,不满足处理要求!\" );
delete pBmi;
pBmi = NULL;
return FALSE;
}
//读像素数据
int nImageSize = pBmi->bmiHeader.biSizeImage;
pBits = new BYTE[ nImageSize ];
file.Read( (PVOID)pBits, nImageSize );
file.Close( );
return TRUE;
}
BOOL CBmp::Write( const CString &Filename )
{
CFile file;
BITMAPFILEHEADER bmfh;
if ( !(pBmi && pBits ) )
{
AfxMessageBox( \"数据无效!\" );
return FALSE;
}
//创建文件
if ( !file.Open(Filename,CFile::modeWrite|CFile::modeCreate) )
{
AfxMessageBox( \"创建文件错误!\" );
return FALSE;
}
//计算长度数据
int nBitsSize = pBmi->bmiHeader.biSizeImage; //像素数据部分
int nInfoSize = sizeof(BITMAPINFOHEADER) + GetPaletteSize() * sizeof(RGBQUAD); //位图信息头+调色板
int nHeaderSize = sizeof(bmfh) + nInfoSize; //文件信息头+位图信息头+调色板
int nFileSize = nHeaderSize + nBitsSize; //文件信息头+位图信息头+调色板+像素数据部分
//填写文件信息头
bmfh.bfType = 0x4d42;
bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
bmfh.bfOffBits = nHeaderSize;
bmfh.bfSize = nFileSize;
//文件信息头写入文件
file.Write( (PVOID)&bmfh, sizeof(bmfh) );
file.Write( (PVOID)pBmi, nInfoSize );
file.Write( (PVOID)pBits, nBitsSize );
file.Close( );
return TRUE;
}
//获得图像宽度(像素)
int CBmp::GetWidth( ) const
{
if ( pBmi )
return pBmi->bmiHeader.biWidth;
else
return 0;
}
//获得图像高度(像素)int CBmp::GetHeight( ) const { if ( pBmi ) return pBmi-bmiHeader.biHeight; else return 0; } //获得调色板长度 int CBmp::GetPaletteSize( ) const { if ( !pBmi ) return -1; switch ( pBmi-bmiHeader.
(float)pRGB[nColor].rgbGreen * 0.587 +
(float)pRGB[nColor].rgbBlue * 0.114 );
}
}
//修改调色板
for ( int i = 0; i < 256; i++ )
pRGB[i].rgbRed = pRGB[i].rgbGreen = pRGB[i].rgbBlue = i;
return TRUE;
}
//真彩色位图转为灰度图
BOOL CBmp::ToGrayScaleImage_TrueColor( )
{
//计算几组数据
int nBytesPerLine1 = GetBytesPerLine( ); //原 图像每行字节数
int nBytesPerLine2 = ( (GetWidth()+3)/4 ) * 4; //新 图像每行字节数
int nImageSize2 = nBytesPerLine2 * GetHeight( ); //新 像素数据长度
int nInfoSize2 = sizeof( BITMAPINFOHEADER ) + 256 * sizeof( RGBQUAD ); //新 位图信息头+调色板 长度
//定义新图像结构
PBITMAPINFO pBmi2 = (PBITMAPINFO)new BYTE[ nInfoSize2 ];
PBYTE pBits2 = new BYTE[ nImageSize2 ];
//为新位图信息头赋值
memcpy( (PVOID)&(pBmi2->bmiHeader), (PVOID)&(pBmi->bmiHeader),sizeof(BITMAPINFOHEADER) );
pBmi2->bmiHeader.biBitCount = 8;
pBmi2->bmiHeader.biSizeImage = nImageSize2;
//初始化新调色板
LPRGBQUAD pRGB = pBmi2->bmiColors;
for ( int i = 0; i < 256; i++ )
pRGB[i].rgbRed = pRGB[i].rgbGreen = pRGB[i].rgbBlue = i;
//填写新图像的各像素
int nLineStart1; //原 图像每行的起始位置
int nLineStart2; //新 图像每行的起始位置
for ( int h = 0; h < GetHeight(); h++ )
{
nLineStart1 = nBytesPerLine1 * h;
nLineStart2 = nBytesPerLine2 * h;
for ( int w = 0; w < GetWidth(); w++ )
pBits2[nLineStart2+w] = int( (float)pBits[nLineStart1 + 3 * w] * 0.114 +
(float)pBits[nLineStart1 + 3 * w + 1] * 0.587 +
(float)pBits[nLineStart1 + 3 * w + 2] * 0.299 );
}
//删除原图像信息并赋新值
delete pBmi;
pBmi = pBmi2;
delete pBits;
pBits = pBits2;
return TRUE;
}
//二值化
void CBmp::Binarize( int threshold )
{
if ( !IsGrayScaleImage() )
{
AfxMessageBox( \"不是灰度图!\" );
return;
}
int nLineStart; //每行开始的字节号
for ( int h = 0; h < GetHeight(); h++ )
{
nLineStart = GetBytesPerLine( ) * h;
for ( int w = 0; w < GetWidth(); w++ )
if ( pBits[nLineStart+w] < threshold )
pBits[ nLineStart+w ] = 0;
else
pBits[ nLineStart+w ] = 255;
}
}
wise_111 - 六级  2010-6-6 16:49