简单的bmp验证码识别 (c++)

  菜鸟学习笔记供新手学习参考,一个有着很多限制的小程序,大神路过多多指点。


  不废话,正题如下:


  bmp验证码识别的流程大概分为

    1、获取bmp图片中识别需要用到的数据,包括像素高度像素宽度以及位图数据。

    2、对获取的数据进行必要的处理,包括灰度化、二值化、去噪等。

    3、对处理后的数据(一个二值化的数组)进行扫描,分割出各个字符(即确定多对数组下标)

    4、建立字符模板库,将分割出的字符与模板一一对比,找出对应的字符。


  下面具体讲解:

  1、获取数据。

    bmp文件结构与读取遍地都是,细节不赘述

    需要注意:1)简单识别用到的也就是biWidth(19-22字节),biHeight(23-26字节),以及位图数据(>54字节

                       2)位图数据是倒着存放,读取或处理的时候要进行处理。

                               位图数据每行会自动填充字节为4的倍数,读取或处理时最好跳过相应数目的字节。

                        3)每个像素有3个分量RGB,对应3个字节。

                       4关于调色板:由于现在基本都是24位真彩图,所以这个基本可以不考虑,所以才是读取54字节以后的为位图数据。

                                                       调色板个人理解:     类似超市寄存物品,每个格子就是一种颜色,通过你的编号(即位图数据,注

                                                                                           意这里每个像素不是3字节,而是因多少位的图片而异),拿到你想要的颜色。

//		提供方法:
//				1、取得图片信息。
//				2、取得图片数据。



class readBmp
{
public:
	bool			getWidth(long &);					//得到位图的宽
	bool			getHeight(long &);					//得到位图的高
	bool			getBit(int &);						//得到位图位数
	bool			getData(bit_t *&);				//读取文件的颜色信息,即像素部分,即rgb信息

	readBmp(const char *path);
	~readBmp();

private:
	int				bitWidth;				
	int				bitHeight;				
	int				bitBit;					
	bool			bitReadSuccess;			//记录构造函数里bmp文件是否成功读取
	void 			distroy();
	bit_t		   *tmpData;				//从文件读出的数据地址
	bool			isInforExisted(void);	//判断bmp文件是否成功读取
};

/*
在构造函数里读取所需的文件信息,包括像素高度、宽度、和位图数据
自己申请的空间在析构函数释放
*/

readBmp::readBmp(const char *path)
{
	ifstream  bmpFile(path, ios::in | ios::binary);			//创建一个读取文件流对象, 不自动生成不存在文件,二进制方式打开
	bitReadSuccess = bmpFile.good();						//判断文件是否成功打开
	if(true == bitReadSuccess)
	{
		bmpFile.seekg(18, ios::beg);						//bmp文件结构中WIDTH 和 HEIGHT为long类型,在19-26字节
		bmpFile.read((char *)(&bitWidth), 4);				//由于read方法参数类型限制,要将第一个参数如左处理

		//64位系统g++ long 为8字节,不能用sizeof(long)获取字节数,否则文件指针偏移量过大,读取过多

		bmpFile.read((char *)(&bitHeight), 4);		
		bmpFile.seekg(2, ios::cur);
		bmpFile.read((char *)(&bitBit), sizeof (bitBit));
		
		if (bitBit != 24)									//暂时只考虑24位图片的读取,2、4、8位的可以以后扩充
		{
			cout << "非24位图片,请选择合适的图片重试!" << endl;
		}
		else
		{
			long count = 0;
			bmpFile.seekg(22, ios::cur);
			tmpData = new bit_t[bitWidth * bitHeight * 3];
			long	skipWidth = (4 - bitWidth*3%4)%4;			//计算每行读取时要skip的字节数
			for(int i = bitHeight - 1; i >= 0; i--)
			{
				for( int j = 0; j < bitWidth * 3; j++)
					bmpFile.get(tmpData[count+
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值