车牌识别(一)BMP文件读写

车牌识别代码,作者地址:https://blog.csdn.net/liujia2100/article/details/6989712

BMP格式的文件,也就是没有任何压缩的原始位图,占用的磁盘空间也是最大的,但此文件结构简单,运算速度快,很适合初学者学习车牌识别原理,由于目的是为了学习车牌识别,所以下面的代码,只支持24位色的BMP文件,上代码。

#include <stdio.h>
#include <stdlib.h>

typedef unsigned long       DWORD;
typedef int                 BOOL;
typedef unsigned char       BYTE;
typedef unsigned short      WORD;
typedef float               FLOAT;
typedef unsigned char       byte;

//BMP图像结构
struct BMP_img
{
    //{BMP头
    BYTE  bfType[2];//类型,判断是否为‘B’,‘M’
    DWORD size;//文件尺寸
    DWORD reser;//保留,为0
    DWORD header_length;//头部长度,也就是数据起始位置
    //}BMP头长度,14字节

    //{信息头40字节
    DWORD infoheader_length;//信息头长度,40
    DWORD width;//图像宽度
    DWORD height;//图像高度
    WORD  biplanes;//颜色平面数,为1
    WORD  bmp_type;/* 8bit 24bit; */
    DWORD compres;//0表示不压缩
    DWORD datasize;//数据长度,size-54
    DWORD bixpm;//水平分辩率
    DWORD biypm;//垂直分辩率
    DWORD clrused;//为0所有颜色,其它的为索引数
    DWORD relclrused;//0表示都重要
    //}信息头结束

    //其它信息
    BYTE *image;//指向一块内存,保存BMP的内容
    DWORD lineBytes;//一行占多少字节
};

//文件图文件到内存中
int read_img(char const *fn, struct BMP_img *img)
{
    DWORD i,j,l,t;
    FILE *infile;
    if((infile=fopen(fn,"rb"))==NULL)return 0;

    fread(&img->bfType,2,1,infile);//BM
    if(!(img->bfType[0]=='B' && img->bfType[1]=='M'))return 0;
    fread(&img->size,sizeof(DWORD),1,infile);
    printf("\nBMP size             :%d",(int)img->size);
    fread(&img->reser,sizeof(DWORD),1,infile);
    printf("\n保留位:");
    fread(&img->header_length,sizeof(DWORD),1,infile);
    printf("\nheader length    :%d",(int)img->header_length);
    fread(&img->infoheader_length,sizeof(DWORD),1,infile);
    fread(&img->width, sizeof(DWORD), 1, infile);
    fread(&img->height, sizeof(DWORD), 1, infile);
    printf( "\nwidth   :%d\n  height  :%d ", (int)img->width, (int)img->height);
    fread(&img->biplanes, sizeof(WORD), 1, infile);
    fread(&img->bmp_type, sizeof(WORD), 1, infile);
    printf("\nBMP Tpye             :%d ", img->bmp_type);
    fread(&img->compres, sizeof(DWORD), 1, infile);
    if(img->compres==0) {printf("\nbmp图片为非压缩!");}printf(" ");
    fread(&img->datasize, sizeof(DWORD), 1, infile);
    printf("\nBMP Data Size        :%d ",(int)img->datasize);
    fread(&img->bixpm, sizeof(DWORD), 1, infile);
    fread(&img->biypm, sizeof(DWORD), 1, infile);
    fread(&img->clrused, sizeof(DWORD), 1, infile);
    printf("\n实际使用颜色数=%d ",(int)img->clrused);printf(" ");
    fread(&img->relclrused, sizeof(DWORD), 1, infile);

    if(img->bmp_type==24)//24位色,这里只考虑24位色图,其它的不考虑
    {
        img->lineBytes=((img->width*3+3)>>2)<<2;//计算一行需要多少字节,对齐到4字节

        byte *temp=(byte *)malloc(sizeof(byte) * img->height * img->lineBytes);//分配一块内存,用于读文件
        img->image=(byte *)malloc(img->lineBytes*img->height);//分配一块内存,用于保存图像数据
        if(img->image==NULL) fprintf(stderr, "\n Allocation error for temp in read_bmp() \n");
        fseek(infile, img->header_length, SEEK_SET);//跳过头部,也就是跳到图像位置
        fread(temp, sizeof(byte), (img->lineBytes)*img->height, infile);//全部读到内存中

        for(i=0;i<img->height;i++)//循环高度,上下颠倒
        {
            l=(img->height-i-1)*img->lineBytes;//从下往上
            t=i*img->lineBytes;//从上往下
            for(j=0;j<img->width*3;j+=3)
            {
                img->image[l+j+2]=*(temp+t+j+2);
                img->image[l+j+1]=*(temp+t+j+1);
                img->image[l+j]=*(temp+t+j);
            }
        }
        free(temp);
        temp=NULL;
    }
    else return 0;
    fclose(infile);
    return 1;
}

//根据img写BMP文件
void WriteBMP(char const *fn,struct BMP_img *img)
{
    FILE *infile;
    if((infile=fopen(fn,"wb"))==NULL)//保存为当前文件夹下的xx文件
    {
        return;
    }
    fwrite(&img->bfType,2,1,infile);//B M
    fwrite(&img->size,sizeof(DWORD),1,infile);
    fwrite(&img->reser,sizeof(DWORD),1,infile);
    fwrite(&img->header_length,sizeof(DWORD),1,infile);
    fwrite(&img->infoheader_length,sizeof(DWORD),1,infile);
    fwrite(&img->width, sizeof(DWORD), 1, infile);
    fwrite(&img->height, sizeof(DWORD), 1, infile);
    fwrite(&img->biplanes, sizeof(WORD), 1, infile);
    fwrite(&img->bmp_type, sizeof(WORD), 1, infile);
    fwrite(&img->compres, sizeof(DWORD), 1, infile);
    fwrite(&img->datasize, sizeof(DWORD), 1, infile);
    fwrite(&img->bixpm, sizeof(DWORD), 1, infile);
    fwrite(&img->biypm, sizeof(DWORD), 1, infile);
    fwrite(&img->clrused, sizeof(DWORD), 1, infile);
    fwrite(&img->relclrused, sizeof(DWORD), 1, infile);
    fwrite(img->image,img->datasize,1,infile);
    fclose(infile);
}

int main(int argc, char **argv)
{
    struct BMP_img img;//定义结构

    //把当前文件夹下的1.bmp文件内容,读到img结构中,并上下镜像
    if(read_img("1.bmp", &img)==0)
    {
        printf("error");
        return 0;
    }
    
    //写入镜像后的数据到2.bmp中
    WriteBMP("2.bmp",&img);
    
    free(img.image);//释放动态分配的内存
    
    printf("请打开2.bmp进行查看\n");
    system("pause");
    return 0;
}

要使代码正常运行,首先你编译后的当前文件夹下,要有1.bmp文件存在,如下图

程序运行后,会自动生成2.bmp,与上图相比,上下颠倒过来了,效果如下图

到此,BMP读写成功了。。。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值