C++图像识别转灰度


  1 #include <stdafx.h>
  2 #include <stdio.h>
  3 #include <string.h>
  4 #include <math.h>
  5 #include <windows.h>
  6 using namespace std;
  7 
  8 
  9 //将位图转换为256色灰度图
 10 void ToGray(const string& srcFile,const string& desFile)
 11 {
 12     BITMAPFILEHEADER bmfHeader;
 13     BITMAPINFOHEADER bmiHeader;
 14     
 15     FILE *pFile;
 16     if ((pFile = fopen(srcFile.c_str(),"rb")) == NULL)
 17     {
 18         printf("open bmp file error.");
 19         exit(-1);
 20     }
 21     //读取文件和Bitmap头信息
 22     fseek(pFile,0,SEEK_SET);
 23     fread(&bmfHeader,sizeof(BITMAPFILEHEADER),1,pFile);
 24     fread(&bmiHeader,sizeof(BITMAPINFOHEADER),1,pFile);
 25     //先不支持16位位图
 26     int bitCount = bmiHeader.biBitCount;
 27     if (bitCount == 16)
 28     {
 29         exit(-1);
 30     }
 31     double byteCount = (double)bitCount / 8;
 32     int nClr = 0;
 33     if (bitCount < 16)
 34     {        
 35         nClr = bmiHeader.biClrUsed ? bmiHeader.biClrUsed : 1 << bitCount;
 36         if (nClr > 256)
 37             nClr = 0;        
 38     }
 39     //读取调色板
 40     RGBQUAD *quad = NULL;
 41     if (nClr > 0)
 42     {
 43         quad = new RGBQUAD[nClr];
 44         fread(quad,sizeof(RGBQUAD) * nClr,1,pFile);
 45     }
 46     
 47     int srcW = bmiHeader.biWidth;
 48     int srcH = bmiHeader.biHeight;
 49     //原图像每一行去除偏移量的字节数
 50     int lineSize = bitCount * srcW >> 3;
 51     //偏移量,windows系统要求每个扫描行按四字节对齐
 52     int alignBytes = (((bmiHeader.biWidth * bitCount + 31) & ~31) >> 3)
 53         - ((bmiHeader.biWidth * bitCount) >> 3);
 54     //原图像缓存    
 55     int srcBufSize = lineSize * srcH;
 56     BYTE* srcBuf = new BYTE[srcBufSize];
 57     int i,j;
 58     //读取文件中数据
 59     for (i = 0; i < srcH; i++)
 60     {        
 61         fread(&srcBuf[lineSize * i],lineSize,1,pFile);
 62         fseek(pFile,alignBytes,SEEK_CUR);
 63     }
 64     //256色位图调色板
 65     RGBQUAD *quadDes = NULL;
 66     quadDes = new RGBQUAD[256];
 67     for (i = 0; i < 256; i++)
 68     {
 69         //灰度图的RGB值相等
 70         quadDes[i].rgbBlue = quadDes[i].rgbGreen = quadDes[i].rgbRed = i;
 71     }
 72     //灰度图每个像素采用8位表示
 73     int desBufSize = (((srcW * 8 + 31) & ~31) >> 3) * srcH;
 74     BYTE *desBuf = new BYTE[desBufSize];
 75     //每个扫描行占用字节数
 76     int desLineSize = ((srcW * 8 + 31) >> 5) * 4;
 77 
 78     for (i = 0; i < srcH; i++)
 79     {
 80         for (j = 0; j < srcW; j++)
 81         {
 82             //从调色板中读取RGB值
 83             if (nClr > 0)
 84             {
 85                 unsigned int pos = srcBuf[i * lineSize + int(j * byteCount)];
 86                 desBuf[i * desLineSize + j] = 0.3 * quad[pos].rgbRed
 87                     + 0.59 * quad[pos].rgbGreen
 88                     + 0.11 * quad[pos].rgbBlue;
 89             }
 90             else
 91                 desBuf[i * desLineSize + j] = 0.3 * srcBuf[i * lineSize + int(j * byteCount)] 
 92                 + 0.59 * srcBuf[i * lineSize + int(j * byteCount) + 1
 93                 +  0.11 * srcBuf[i * lineSize + int(j * byteCount) + 2];
 94         }
 95     }
 96 
 97     //创建目标文件
 98     HFILE hfile = _lcreat(desFile.c_str(),0);    
 99     //文件头信息
100     BITMAPFILEHEADER nbmfHeader;    
101     nbmfHeader.bfType = 0x4D42;
102     nbmfHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
103         + 256 * sizeof(RGBQUAD) + srcW * srcH;
104     nbmfHeader.bfReserved1 = 0;
105     nbmfHeader.bfReserved2 = 0;
106     nbmfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
107     //Bitmap头信息
108     BITMAPINFOHEADER   bmi; 
109     bmi.biSize=sizeof(BITMAPINFOHEADER); 
110     bmi.biWidth=srcW; 
111     bmi.biHeight=srcH; 
112     bmi.biPlanes=1
113     bmi.biBitCount=8
114     bmi.biCompression=BI_RGB; 
115     bmi.biSizeImage=0
116     bmi.biXPelsPerMeter=0
117     bmi.biYPelsPerMeter=0
118     bmi.biClrUsed= 256
119     bmi.biClrImportant=0
120     
121     //写入文件头信息
122     _lwrite(hfile,(LPCSTR)&nbmfHeader,sizeof(BITMAPFILEHEADER));
123     //写入Bitmap头信息
124     _lwrite(hfile,(LPCSTR)&bmi,sizeof(BITMAPINFOHEADER));
125     if (quadDes)
126     {
127         _lwrite(hfile,(LPCSTR)quadDes,sizeof(RGBQUAD) * 256);
128     }
129     //写入图像数据
130     _lwrite(hfile,(LPCSTR)desBuf,desBufSize);
131     _lclose(hfile);
132     if (quad)
133     {
134         delete[] quad;
135         quad = NULL;
136     }
137     if (quadDes)
138     {
139         delete[] quadDes;
140         quadDes = NULL;
141     }
142 }
143 
144 int main(int argc, char* argv[])
145 {
146     string srcFile("e://t.bmp");
147     string desFile("e://gray.bmp");
148     ToGray(srcFile,desFile);
149     system("pause");

150     return 0;
151 }




转载于:https://my.oschina.net/RobinChinaSoft/blog/425544

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值