`
hmi213tv
  • 浏览: 11427 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

2011-5-9

 
阅读更多

2011-5-9
2011年05月09日
  考虑到现有的数字图像处理都是基于Windows平台,都或多或少使用了Win32 API函数,不能移植到Linux或者嵌入式系统中。为了使程序可移植,采用标准C语言建立了数字图像处理的基本框架,如下图所示:
  
  
  
  程序参考了网上一些博客的内容,并进行了改变,建立了符合自己习惯的数据结构。主要实现了bmp格式图像的打开、保存、创建、图像颜色空间转换等功能,暂时还没有添加具体的处理函数。我想,既然有了程序的框架,添加算法只是编写一个个函数的问题。
  本程序具体实现的功能如下:
  * 打开和保存bmp文件,这里使用自定义数据结构Bitmap,相关函数定义如下:
  bmp.h:
  int CreateBitmap(Bitmap* bmp, int width, int height, int bitCount);
  void ReleaseBitmap(Bitmap* bmp);
  int CheckPath(char *path);
  int ReadBitmap(char* path, Bitmap* bmp);
  int SaveBitmap(char* path, Bitmap* bmp);
  * 图像格式转换
  basicprocess.h:
  int RGB2Gray(Bitmap* src, Bitmap* dst);
  int Gray2RGB(Bitmap* src, Bitmap* dst);
  int Gray2BW(Bitmap* src, Bitmap* dst, int threshold);
  void hsv2rgb(float H, float S, float V, float *R, float *G, float *B);
  void rgb2hsv(float R, float G, float B, float *H, float *S, float* V);
  程序源码如下,
  1
  19#ifndef BMP_H_INCLUDED
  20#define BMP_H_INCLUDED
  21
  22#include
  23#include
  24#include
  25#include
  26#include
  27
  28
  31typedef unsigned short WORD;
  32typedef unsigned long DWORD;
  33typedef long LONG;
  34typedef unsigned char BYTE;
  35
  36
  37typedef struct tagBITMAPFILEHEADER {
  38    WORD bfType;
  39    DWORD bfSize;
  40    WORD bfReserved1;
  41    WORD bfReserved2;
  42    DWORD bfOffBits;
  43} BITMAPFILEHEADER;
  44
  45
  46typedef struct tagBITMAPINFOHEADER {
  47    DWORD biSize; // 结构长度 40B
  48    LONG biWidth;
  49    LONG biHeight;
  50    WORD biPlanes; // 1
  51    WORD biBitCount; // 表示颜色要用到的位数
  52    DWORD biCompression; // 压缩格式
  53    DWORD biSizeImage; // 位图占用字节数=biWidth'(4的整倍数)*biHeight
  54    LONG biXPelsPerMeter; // 水平分辨率
  55    LONG biYPelsPerMeter; // 垂直分辨率
  56    DWORD biClrUsed; // 本图像用到的颜色数
  57    DWORD biClrImportant; // 本图像的重要颜色数
  58} BITMAPINFOHEADER;
  59
  60
  61typedef struct tagRGBQUAD {
  62    BYTE rgbBlue;
  63    BYTE rgbGreen;
  64    BYTE rgbRed;
  65    BYTE rgbReserved;
  66} RGBQUAD;
  67
  68
  69typedef struct tagBITMAPINFO {
  70    BITMAPINFOHEADER bmiHeader;
  71    RGBQUAD bmiColors[1];
  72} BITMAPINFO;
  73
  74
  75typedef struct _Bitmap
  76{
  77    BITMAPFILEHEADER bmfh;
  78    BITMAPINFOHEADER bmih;
  79    int width;
  80    int height;
  81    int bitCount;    // 8 或者24
  82    int imageSize;    // 图像数据大小(imageSize=height*widthStep)字节
  83    BYTE* imageData;//排列的图像数据
  84    int widthStep;    //排列的图像行大小
  85}Bitmap;
  86
  87
  94int CreateBitmap(Bitmap* bmp, int width, int height, int bitCount)
  95{
  96    bmp->width=width;
  97    bmp->height=height;
  98    bmp->bmih.biWidth=width;
  99    bmp->bmih.biHeight=height;
  100
  101    bmp->widthStep=(int)((width*bitCount+31)/32)*4;        //计算排列的宽度
  102    bmp->imageSize=bmp->height*bmp->widthStep*sizeof(BYTE);//计算排列的图像大小
  103
  104    if(bitCount==8)
  105    {
  106        bmp->bitCount=8;
  107        bmp->bmfh.bfType=0x4d42;    //注意是4d42 这个地方折磨我一下午啊
  108        bmp->bmfh.bfReserved1=0;
  109        bmp->bmfh.bfReserved2=0;
  110        bmp->bmih.biBitCount=8;
  111        bmp->bmih.biSize=40;
  112        bmp->bmih.biPlanes=1;
  113        bmp->bmfh.bfSize=54+256*4+height*bmp->widthStep;
  114        bmp->bmfh.bfOffBits=1078;
  115        bmp->bmih.biBitCount=8;
  116        bmp->bmih.biCompression=0;
  117        bmp->bmih.biSizeImage=bmp->imageSize;
  118        bmp->bmih.biClrUsed=0;
  119        bmp->bmih.biClrImportant=0;
  120        bmp->bmih.biXPelsPerMeter=0;
  121        bmp->bmih.biYPelsPerMeter=0;
  122    }
  123    else if (bitCount==24)
  124    {
  125        bmp->bitCount=24;
  126        bmp->bmfh.bfType=0x4d42;
  127        bmp->bmih.biBitCount=24;
  128        bmp->bmfh.bfReserved1=0;
  129        bmp->bmfh.bfReserved2=0;
  130        bmp->bmih.biSize=40;
  131        bmp->bmih.biPlanes=1;
  132        bmp->bmfh.bfSize=54+height*bmp->widthStep;
  133        bmp->bmfh.bfOffBits=54;
  134        bmp->bmih.biBitCount=24;
  135        bmp->bmih.biSizeImage=bmp->imageSize;
  136        bmp->bmih.biClrUsed=0;
  137        bmp->bmih.biCompression=0;
  138        bmp->bmih.biClrImportant=0;
  139        bmp->bmih.biXPelsPerMeter=0;
  140        bmp->bmih.biYPelsPerMeter=0;
  141    }
  142    else
  143    {
  144        printf("Error(CreateBitmap): only supported 8 or 24 bits bitmap.\n");
  145        return -1;
  146    }
  147
  148    bmp->imageData=(BYTE*)malloc(bmp->imageSize);        //分配数据空间
  149    if(!(bmp->imageData))
  150    {
  151        printf("Error(CreateBitmap): can not allocate bitmap memory.\n");
  152        return -1;
  153    }
  154    return 0;
  155}
  156
  157
  163void ReleaseBitmap(Bitmap* bmp)
  164{
  165    free(bmp->imageData);
  166    bmp->imageData=NULL;
  167    free(bmp);
  168    bmp=NULL;
  169}
  170
  171
  178int CheckPath(char *path)
  179{
  180    FILE *fd;
  181    int len = strlen(path) / sizeof(char);
  182    char ext[3];
  183    //check whether the path include the characters "bmp" at end
  184    strncpy(ext, &path[len - 3], 3);
  185    if (!(ext[0] == 'b' && ext[1] == 'm' && ext[2] == 'p')) {
  186        printf("Error(CheckPath): the extension of the file is not bmp.\n");
  187        return -1;
  188    }
  189
  190    //check whether the file can be read or not
  191    fd = fopen(path, "r");
  192    if (!fd)
  193    {
  194        printf("Error(CheckPath): can not open the file.\n");
  195        return -1;
  196    }
  197    fclose(fd);
  198
  199    return 0;
  200}
  201
  202
  210int ReadBitmap(char* path, Bitmap* bmp)
  211{
  212    int ret;
  213    FILE *fd;
  214
  215    //检查路径是否可读
  216    ret=CheckPath(path);
  217    if(ret==-1)
  218    {
  219        printf("Error(ReadBitmap): the path of the image is invalid.\n");
  220        return -1;
  221    }
  222
  223    //打开文件
  224    fd=fopen(path,"rb");
  225    if(fd==0)
  226    {
  227        printf("Error(ReadBitmap): can not open the image.\n");
  228        return -1;
  229    }
  230
  231    //读取文件信息头     14字节
  232    fread(&(bmp->bmfh.bfType),sizeof(WORD),1,fd);
  233    fread(&(bmp->bmfh.bfSize),sizeof(DWORD),1,fd);
  234    fread(&(bmp->bmfh.bfReserved1),sizeof(WORD),1,fd);
  235    fread(&(bmp->bmfh.bfReserved2),sizeof(WORD),1,fd);
  236    fread(&(bmp->bmfh.bfOffBits),sizeof(DWORD),1,fd);
  237
  238    //读取位图信息头    40字节
  239    fread(&(bmp->bmih.biSize),sizeof(DWORD),1,fd);
  240    fread(&(bmp->bmih.biWidth),sizeof(DWORD),1,fd);
  241    fread(&(bmp->bmih.biHeight),sizeof(DWORD),1,fd);
  242    fread(&(bmp->bmih.biPlanes),sizeof(WORD),1,fd);
  243    fread(&(bmp->bmih.biBitCount),sizeof(WORD),1,fd);
  244    fread(&(bmp->bmih.biCompression),sizeof(DWORD),1,fd);
  245    fread(&(bmp->bmih.biSizeImage),sizeof(DWORD),1,fd);
  246    fread(&(bmp->bmih.biXPelsPerMeter),sizeof(DWORD),1,fd);
  247    fread(&(bmp->bmih.biYPelsPerMeter),sizeof(DWORD),1,fd);
  248    fread(&(bmp->bmih.biClrUsed),sizeof(DWORD),1,fd);
  249    fread(&(bmp->bmih.biClrImportant),sizeof(DWORD),1,fd);
  250
  251    //创建位图结构
  252    ret=CreateBitmap(bmp, bmp->bmih.biWidth, bmp->bmih.biHeight, bmp->bmih.biBitCount);
  253    if(ret==-1)
  254    {
  255        printf("Error(CreateBitmap): can not CreateBitmap.\n");
  256        return -1;
  257    }
  258
  259    //读取图像数据
  260    //由于4字节对齐格式
  261    fseek(fd,bmp->bmfh.bfOffBits,SEEK_SET);    //定位到图像数据区
  262    ret=fread(bmp->imageData,bmp->imageSize,1,fd);
  263    if(ret==0)
  264    {
  265        if(feof(fd))    //if the file pointer point to the end of the file
  266        {
  267        }
  268        if(ferror(fd))  //if error happened while read the pixel data
  269        {
  270            printf("Error(ReadBitmap): can not read the pixel data.\n");
  271            fclose(fd);
  272            return -1;
  273        }
  274    }
  275
  276    //关闭文件
  277    fclose(fd);
  278    return 0;
  279}
  280
  281
  289int SaveBitmap(char* path, Bitmap* bmp)
  290{
  291    int ret;
  292    FILE *fd;
  293
  294    //检查路径是否正确
  295    int len = strlen(path) / sizeof(char);
  296    char ext[3];
  297    //check whether the path include the characters "bmp" at end
  298    strncpy(ext, &path[len - 3], 3);
  299    if (!(ext[0] == 'b' && ext[1] == 'm' && ext[2] == 'p'))
  300    {
  301        printf("Error(SaveBitmap): the extension of the file is not bmp.\n");
  302        return -1;
  303    }
  304
  305    //打开文件
  306    fd=fopen(path,"wb");
  307    if(fd==0)
  308    {
  309        printf("Error(SaveBitmap): can not open the image.\n");
  310        return -1;
  311    }
  312
  313    //保存文件信息头     14字节
  314    fwrite(&(bmp->bmfh.bfType),sizeof(WORD),1,fd);
  315    fwrite(&(bmp->bmfh.bfSize),sizeof(DWORD),1,fd);
  316    fwrite(&(bmp->bmfh.bfReserved1),sizeof(WORD),1,fd);
  317    fwrite(&(bmp->bmfh.bfReserved2),sizeof(WORD),1,fd);
  318    fwrite(&(bmp->bmfh.bfOffBits),sizeof(DWORD),1,fd);
  319
  320    //保存位图信息头    40字节
  321    fwrite(&(bmp->bmih.biSize),sizeof(DWORD),1,fd);
  322    fwrite(&(bmp->bmih.biWidth),sizeof(DWORD),1,fd);
  323    fwrite(&(bmp->bmih.biHeight),sizeof(DWORD),1,fd);
  324    fwrite(&(bmp->bmih.biPlanes),sizeof(WORD),1,fd);
  325    fwrite(&(bmp->bmih.biBitCount),sizeof(WORD),1,fd);
  326    fwrite(&(bmp->bmih.biCompression),sizeof(DWORD),1,fd);
  327    fwrite(&(bmp->bmih.biSizeImage),sizeof(DWORD),1,fd);
  328    fwrite(&(bmp->bmih.biXPelsPerMeter),sizeof(DWORD),1,fd);
  329    fwrite(&(bmp->bmih.biYPelsPerMeter),sizeof(DWORD),1,fd);
  330    fwrite(&(bmp->bmih.biClrUsed),sizeof(DWORD),1,fd);
  331    fwrite(&(bmp->bmih.biClrImportant),sizeof(DWORD),1,fd);
  332
  333    //如果为8位,则保存调色板
  334    RGBQUAD pal[256];
  335    int i;
  336    if(bmp->bitCount==8)
  337    {
  338        for(i=0;ibmp->imageData,bmp->imageSize,1,fd);
  355    if(ret!=1)
  356    {
  357        printf("Error(SaveBitmap): can not save the pixel data.\n");
  358        return -1;
  359    }
  360
  361    //关闭文件
  362    fclose(fd);
  363
  364    return 0;
  365}
  366
  367#endif // BMP_H_INCLUDED
  368
  369
  370
  371
  372
  373
  391
  392#ifndef BASICPROCESS_H_
  393#define BASICPROCESS_H_
  394
  395#include "bmp.h"
  396#include
  397
  400int RGB2Gray(Bitmap* src, Bitmap* dst)
  401{
  402    int ret;
  403    int n=0,i,j;
  404    BYTE r,g,b,gray;
  405
  406    //检查图像格式是否合法
  407    if(src->bitCount!=24)
  408    {
  409        printf("Error(RGB2Gray): the source image must be in RGB format.\n");
  410        return -1;
  411    }
  412
  413    //为dst图像分配数据空间
  414    ret=CreateBitmap(dst,src->width,src->height,8);
  415    if(ret==-1)
  416    {
  417        printf("Error(RGB2Gray): can't create target image.\n");
  418        return -1;
  419    }
  420
  421    //计算灰度数据
  422    for(i=0;iheight;i++)
  423    {
  424        n=0;
  425        for(j=0;jwidth*3;j++,n++)
  426        {
  427            b=*(src->imageData+src->widthStep*(src->height-1-i)+j);
  428            j++;
  429            g=*(src->imageData+src->widthStep*(src->height-1-i)+j);
  430            j++;
  431            r=*(src->imageData+src->widthStep*(src->height-1-i)+j);
  432            gray=(r*19595 + g*38469 + b*7472) >> 16;
  433            *(dst->imageData+dst->widthStep*(dst->height-1-i)+n)=gray;
  434        }
  435    }
  436
  437    return 0;
  438}
  439
  440
  449int Gray2RGB(Bitmap* src, Bitmap* dst)
  450{
  451    int ret;
  452    int n=0,i,j;
  453    BYTE r;
  454
  455    //检查图像格式是否合法
  456    if(src->bitCount!=8)
  457    {
  458        printf("Error(Gray2RGB): the source image must be in gray scale.\n");
  459        return -1;
  460    }
  461
  462    //为dst图像分配数据空间
  463    ret=CreateBitmap(dst,src->width,src->height,24);
  464    if(ret==-1)
  465    {
  466        printf("Error(Gray2RGB): can't create target image.\n");
  467        return -1;
  468    }
  469
  470    //计算灰度数据
  471    for(i=0;iheight;i++)
  472    {
  473        n=0;
  474        for(j=0;jwidth;j++,n++)
  475        {
  476            r=*(src->imageData+src->widthStep*(src->height-1-i)+j);
  477            *(dst->imageData+dst->widthStep*(dst->height-1-i)+n)=r;
  478            n++;
  479            *(dst->imageData+dst->widthStep*(dst->height-1-i)+n)=r;
  480            n++;
  481            *(dst->imageData+dst->widthStep*(dst->height-1-i)+n)=r;
  482        }
  483    }
  484
  485    return 0;
  486}
  487
  488
  497int Gray2BW(Bitmap* src, Bitmap* dst, int threshold)
  498{
  499    int ret;
  500    int n=0,i,j;
  501    BYTE r;
  502
  503    //检查图像格式是否合法
  504    if(src->bitCount!=8)
  505    {
  506        printf("Error(Gray2BW): the source image must be in gray scale.\n");
  507        return -1;
  508    }
  509
  510    //为dst图像分配数据空间
  511    ret=CreateBitmap(dst,src->width,src->height,8);
  512    if(ret==-1)
  513    {
  514        printf("Error(Gray2BW): can't create target image.\n");
  515        return -1;
  516    }
  517
  518    //计算灰度数据
  519    for(i=0;iheight;i++)
  520    {
  521        for(j=0;jwidth;j++,n++)
  522        {
  523            r=*(src->imageData+src->widthStep*(src->height-1-i)+j);
  524            if(r>=threshold)
  525            {
  526                n=255;
  527            }
  528            else
  529            {
  530                n=0;
  531            }
  532            *(dst->imageData+dst->widthStep*(dst->height-1-i)+j)=n;
  533        }
  534    }
  535
  536    return 0;
  537}
  538
  539
  547void rgb2hsv(float R, float G, float B, float *H, float *S, float* V)
  548{
  549    float min, max, delta,tmp;
  550    tmp = RG?R:G;
  553    max = tmp>B?tmp:B;
  554    *V = max; // v
  555
  556    delta = max - min;
  557
  558    if( max != 0 )
  559      *S = delta / max; // s
  560    else
  561    {
  562       // r = g = b = 0 // s = 0, v is undefined
  563      *S = 0;
  564      *H = -1;
  565      return;
  566    }
  567    if( R == max )
  568        *H = ( G - B ) / delta; // between yellow & magenta
  569   else if( G == max )
  570        *H = 2 + ( B - R ) / delta; // between cyan & yellow
  571   else
  572       *H = 4 + ( R - G ) / delta; // between magenta & cyan
  573
  574    (*H) *= 60; // degrees
  575    if( *H < 0 )
  576       (*H) += 360;
  577}
  578
  579
  580
  588void hsv2rgb(float H, float S, float V, float *R, float *G, float *B)
  589{
  590     int i;
  591    float f, p, q, t;
  592
  593    if( S == 0 )
  594    {
  595        *R =*G = *B = V;
  596        return;
  597    }
  598
  599    H /= 60; // sector 0 to 5
  600    i = floor( H );
  601    f = H - i; // factorial part of h
  602    p = V * ( 1 - S );
  603    q = V * ( 1 - S * f );
  604    t = V * ( 1 - S * ( 1 - f ) );
  605
  606    switch( i )
  607    {
  608    case 0:
  609        *R = V;
  610        *G = t;
  611        *B = p;
  612       break;
  613    case 1:
  614       *R = q;
  615       *G = V;
  616       *B = p;
  617       break;
  618    case 2:
  619       *R = p;
  620       *G = V;
  621       *B = t;
  622       break;
  623    case 3:
  624       *R = p;
  625       *G = q;
  626       *B = V;
  627       break;
  628    case 4:
  629       *R = t;
  630       *G = p;
  631       *B = V;
  632       break;
  633    default: // case 5:
  634       *R = V;
  635       *G = p;
  636       *B = q;
  637       break;
  638    }
  639}
  640
  641
  645int HistEqualization(Bitmap* dstBmp, Bitmap* srcBmp)
  646{
  647    return 0;
  648}
  649
  650
  653
  654int MedFilt(Bitmap* dstBmp, Bitmap* srcBmp)
  655{
  656    return 0;
  657}
  658
  659#endif
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics