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 }

时间: 2024-10-08 19:47:30

C++图像识别转灰度的相关文章

Opencv图像识别从零到精通(8)-----灰度直方图

其实刚开始的时候,看很多的书和教程讲绘图和彩色图像等,但是我觉得还是先学会灰度直方图,因为灰度的dims是1,如果dims是3的就是彩色,同时知道前面将的彩色图像的像素访问,相信很快就可以迁移过去的.  一.换个角度认识图像(直方图) 第一个就是当我们面对图像的时候,我们面对的是抽象的矩阵,如下图,下面是0-255的灰度图像的表示,密密麻麻的 那么我们做的直方图,其实就是对这些像素值的统计,看下图,其中Bin是条数,数据和范围是对图的解释,一看就懂 二.准备知识 如果想绘制出来直方图,先要知道几

Atitit图像识别的常用特征大总结attilax大总结

1.1. 常用的图像特征有颜色特征.纹理特征.形状特征.空间关系特征. 1 1.2. HOG特征:方向梯度直方图(Histogram of Oriented Gradient, HOG)1 1.3. (二)LBP特征 LBP(Local Binary Pattern,局部二值模式)是一种用来描述图像局部纹理特征的算子4 1.4. :它具有旋转不变性和灰度不变性等显著的优点.它是首先由T. Ojala, M.Pietik?inen, 和D. Harwood 在1994年提出,用于纹理特征提取.而且

Opencv图像识别从零到精通(26)---分水岭

分水岭是区域分割三个方法的最后一个,对于前景背景的分割有不错的效果. 分水岭分割方法,是一种基于拓扑理论的数学形态学的分割方法,其基本思想是把图像看作是测地学上的拓扑地貌,图像中每一点像素的灰度值表示该点的海拔高度,每一个局部极小值及其影响区域称为集水盆,而集水盆的边界则形成分水岭.分水岭的概念和形成可以通过模拟浸入过程来说明.在每一个局部极小值表面,刺穿一个小孔,然后把整个模型慢慢浸入水中,随着浸入的加深,每一个局部极小值的影响域慢慢向外扩展,在两个集水盆汇合处构筑大坝,即形成分水岭. 分水岭

使用 MNIST 图像识别数据集

下载代码示例 机器学习领域中最迷人的主题之一是图像识别 (IR). 使用红外系统的示例包括使用指纹或视网膜识别的计算机登录程序和机场安全系统的扫描乘客脸寻找某种通缉名单上的个人. MNIST 数据集是可用于实验的简单图像集合­沙用红外的算法. 这篇文章并介绍了一个相对简单 C# 程序,向您介绍的 MNIST 数据集,这反过来你接触到红外的概念. 它不太可能你会需要使用红外大多数软件应用程序,但我觉得你可能有用的信息在这篇文章为四个不同的原因. 第一,没有更好的方法,了解的 MNIST 数据集和

[图像识别] 1、如何识别一个指针式的时种的时间?

目录 一.算法基本原理 1.图片预处理 2.找表盘 3.找指针 4.指针映射 5.求时间 二.算法流程图 三.程序关键函数说明 1.Canny 2.HoughCircles 3.HoughLines2 4.MyLine类 5.平面几何相关函数 四.运行结果 五.实验中遇到的主要问题及解决方法: 1.在处理速度方面 2.去除其他圆的影响 3.霍夫找到的直线转换为夹角表示的线段 六.实验中的缺陷和不足 一.算法基本原理 时钟识别,顾名思义:就是根据一张带有钟表的图片识别出钟表上所展示的时间.对于这个

Opencv图像识别从零到精通(24)------漫水填充,种子填充,区域生长、孔洞填充

可以说从这篇文章开始,就结束了图像识别的入门基础,来到了第二阶段的学习.在平时处理二值图像的时候,除了要进行形态学的一些操作,还有有上一节讲到的轮廓连通区域的面积周长标记等,还有一个最常见的就是孔洞的填充,opencv这里成为漫水填充,其实也可以叫种子填充,或者区域生长,基本的原理是一样的,但是应用的时候需要注意一下,种子填充用递归的办法,回溯算法,漫水填充使用堆栈,提高效率,同时还提供了一种方式是扫描行.经常用来填充孔洞,现在来具体看看. 漫水填充:也就是用一定颜色填充联通区域,通过设置可连通

图像识别技术

图像识别算法实现收藏 以往的图像处理函数实现,多是针对图像句柄.算法实现 需要操作复杂的图像文件. 但是,这种方式算法实现和调试的周期比较长.为了加速开外,我在中间插入的矩阵库.因为图像处理算法多是针对矩阵,所以实现和调试比较快. //////////////////////////////////////////////////////////////////// 指纹图像识别算法的基本原理介绍 在有的国家,指纹属于个人隐私,不能象人工处理那样直接处理指纹图像,所以许多生物识别技术并不直接存储

Opencv图像识别从零到精通(27)---grabcut

这是基于图论的分割方法,所以开始就先介绍了 Graph cuts,然后再到Grab cut   一. Graph cuts Graph cuts是一种十分有用和流行的能量优化算法,在计算机视觉领域普遍应用于前背景分割(Image segmentation).立体视觉(stereo vision).抠图(Image matting)等. 此类方法把图像分割问题与图的最小割(min cut)问题相关联.首先用一个无向图G=<V,E>表示要分割的图像,V和E分别是顶点(vertex)和边(edge)

【JAVA】图像识别——HSV肤色提取 【转载】

OSCHINA上看到各种语言的抓妹子图的程序段,拿来跑一跑,都是爬虫的机制,而地址一般都是固定的,格式固定,才能抓到想要的图,这显示不够智能,于是把作者的代码改掉,变成了个下载图片的爬虫.然后问题就来了,大量的图片,不是我想要的,于是想到了图像识别,目前主要的分支有,找相似图,人脸识别,鉴黄等. OSCHINA上看到各种语言的抓妹子图的程序段,拿来跑一跑,都是爬虫的机制,而地址一般都是固定的,格式固定,才能抓到想要的图,这显示不够智能,于是把作者的代码改掉,变成了个下载图片的爬虫.然后问题就来了