24位位图转化为灰度图
2007-06-18 16:30
239 查看
前两天刚刚开始做图像处理的东西,好不容易弄清了位图的基本格式,并尝试着编了一个二十四位位图转化为灰度图的API函数:
HDIB WINAPI DIBToGray(LPSTR lpDIB)
{
// 获取位图的信息头
LPBITMAPINFOHEADER lpDIBHdr; // 指向BITMAPINFOHEADER的指针
lpDIBHdr=(LPBITMAPINFOHEADER)lpDIB;
LPSTR lpGray;
// 计算位图图的信息头、调色板和图形数据的大小, 并给灰度图分配内存
int dwInfo=lpDIBHdr->biSize;
int dwPal=::DIBNumColors((LPSTR)lpDIBHdr)*sizeof(RGBQUAD);
int dwData=lpDIBHdr->biSizeImage;
int dwGrayPal=dwPal;
if(dwPal==0)
{
dwGrayPal=256*sizeof(RGBQUAD);
dwData=lpDIBHdr->biHeight*lpDIBHdr->biWidth;
}
int sizeTotal=dwInfo+dwGrayPal+dwData;
HGLOBAL hGray=(HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeTotal);
if (hGray==0)
{
return NULL; //内存分配失败则返回NULL
}
lpGray = (LPSTR) ::GlobalLock(hGray);
// 创建灰度图的颜色表 计算每个像素点的灰度值,即求平均即可
LPLOGPALETTE lpGrayPal=(LPLOGPALETTE)(lpGray+40);
char * lpBits=FindDIBBits(lpDIB);
int rowLen=WIDTHBYTES(8*lpDIBHdr->biWidth);
BYTE* lpGrayBits=(BYTE*)(lpGrayPal)+dwGrayPal;
int aver=0;
int i,j,k;
if(24==lpDIBHdr->biBitCount)
{
lpGrayPal->palNumEntries=256;
lpGrayPal->palVersion=PALVERSION;
for(i=0;i<256;i++)
{
lpGrayPal->palPalEntry[i].peBlue=i;
lpGrayPal->palPalEntry[i].peGreen=i;
lpGrayPal->palPalEntry[i].peRed=i;
lpGrayPal->palPalEntry[i].peFlags=0;
}
for (i=0;i<lpDIBHdr->biHeight;i++)
{
for (j=0; j<rowLen; j++)
{
k=i*3*rowLen+3*j;
lpGrayBits[i*rowLen+j]=(lpBits[k]+lpBits[k+1]+lpBits[k+2])/3;
}
}
}
// 创建灰度图的信息头
LPBITMAPINFOHEADER lpGrayHdr=(LPBITMAPINFOHEADER)lpGray;
memcpy(lpGrayHdr, lpDIBHdr, dwInfo);
if(dwPal==0)
{
lpGrayHdr->biSizeImage=sizeTotal;
lpGrayHdr->biBitCount=8;
lpGrayHdr->biClrUsed=256;
}
::GlobalUnlock(hGray);
return (HDIB)hGray;
}
在 (BYTE*)(lpGrayPal)+dwGrayPal; 中,最初由于写成了(BYTE*)(lpGrayPal+dwGrayPal);造成了分配的内存不够,一开始是尝试着多分配了一些内存,但是读出来的图像发生了错位,后来发现,dwGrayPal事实上已经是代表了dwGrayPal*sizeof(LOGPALETTE)的大小了,故而发生了错位。由此可以发现,指针增量的类型是十分重要的!
本来以为前面的代码已经算是做完了,但是今天上午换了张图片时,发现得到的灰度图发生了严重的倾斜,并且在第二次灰度化(第二次调用这个函数的时候,发现就是一张纯黑色的图片)。分析原因如下:
纯黑色是因为第二次进入这个函数的时候,只是重新复制了信息头,而调色板和图片数据都没有进行任何操作。而图片倾斜,则是因为位图在存储的时候,如果每一行的像素值所占的字节数为4的倍数时,则正常存储;否则要在后端补零。昨天试验的图片因为其行数恰好是4的倍数,所以没有出现异常,而今天试验的图片不是4的倍数,所以发生了倾斜。
下面给出校正后的代码:
HDIB WINAPI DIBToGray(LPSTR lpDIB)
{
// 获取位图的信息头
LPBITMAPINFOHEADER lpDIBHdr; // 指向BITMAPINFOHEADER的指针
lpDIBHdr=(LPBITMAPINFOHEADER)lpDIB;
LPSTR lpGray;
// 计算位图图的信息头、调色板和图形数据的大小, 并给灰度图分配内存
int dwInfo=lpDIBHdr->biSize;
int dwPal=::DIBNumColors((LPSTR)lpDIBHdr)*sizeof(RGBQUAD);
int dwData=lpDIBHdr->biSizeImage;
int dwGrayPal=dwPal;
int rowLenDes=WIDTHBYTES(8*lpDIBHdr->biWidth);
if(dwPal==0)
{
dwGrayPal=256*sizeof(RGBQUAD);
dwData=lpDIBHdr->biHeight*rowLenDes;
}
int sizeTotal=dwInfo+dwGrayPal+dwData;
HGLOBAL hGray=(HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeTotal);
if (hGray==0)
{
return NULL; //内存分配失败则返回NULL
}
lpGray = (LPSTR) ::GlobalLock(hGray);
// 创建灰度图的颜色表 计算每个像素点的灰度值,即求平均即可
LPLOGPALETTE lpGrayPal=(LPLOGPALETTE)(lpGray+40);
char * lpBits=FindDIBBits(lpDIB);
int rowLenSr=0;
BYTE* lpGrayBits=(BYTE*)(lpGrayPal)+dwGrayPal;
int i,j,k;
if(24==lpDIBHdr->biBitCount)
{
lpGrayPal->palNumEntries=256;
lpGrayPal->palVersion=PALVERSION;
for(i=0;i<256;i++)
{
lpGrayPal->palPalEntry[i].peBlue=i;
lpGrayPal->palPalEntry[i].peGreen=i;
lpGrayPal->palPalEntry[i].peRed=i;
lpGrayPal->palPalEntry[i].peFlags=0;
}
rowLenSr=WIDTHBYTES(24*lpDIBHdr->biWidth);
for (i=0;i<lpDIBHdr->biHeight;i++)
{
for (j=0; j<lpDIBHdr->biWidth; j++)
{
k=i*rowLenSr+3*j;
lpGrayBits[i*rowLenDes+j]=(lpBits[k]+lpBits[k+1]+lpBits[k+2])/3;
}
for (j=lpDIBHdr->biWidth;j<rowLenDes;j++)
{
lpGrayBits[i*rowLenDes+j]=0;
}
}
}
else
{
memcpy((LPSTR)lpGrayPal,(LPSTR)lpDIBHdr+40,dwGrayPal+dwData);
}
// 创建灰度图的信息头
LPBITMAPINFOHEADER lpGrayHdr=(LPBITMAPINFOHEADER)lpGray;
memcpy(lpGrayHdr, lpDIBHdr, dwInfo);
if(dwPal==0)
{
lpGrayHdr->biSizeImage=dwData;
lpGrayHdr->biBitCount=8;
lpGrayHdr->biClrUsed=256;
}
::GlobalUnlock(hGray);
return (HDIB)hGray;
}
对于真彩色图则直接对数据进行处理,而对于其他类型的位图,则只要把调色板中的RGB分量全部用Y来替代就可以了,并给出更新后的代码:
HDIB WINAPI DIBToGray(LPSTR lpDIB)
{
// 获取位图的信息头
LPBITMAPINFOHEADER lpDIBHdr; // 指向BITMAPINFOHEADER的指针
lpDIBHdr=(LPBITMAPINFOHEADER)lpDIB;
LPSTR lpGray;
// 计算位图图的信息头、调色板和图形数据的大小, 并给灰度图分配内存
int dwInfo=lpDIBHdr->biSize;
int dwPal=::DIBNumColors((LPSTR)lpDIBHdr)*sizeof(RGBQUAD);
int dwData=lpDIBHdr->biSizeImage;
int dwGrayPal=dwPal;
int rowLenDes=WIDTHBYTES(8*lpDIBHdr->biWidth);
if(dwPal==0)
{
dwGrayPal=256*sizeof(RGBQUAD);
dwData=lpDIBHdr->biHeight*rowLenDes;
}
int sizeTotal=dwInfo+dwGrayPal+dwData;
HGLOBAL hGray=(HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeTotal);
if (hGray==0)
{
return NULL; //内存分配失败则返回NULL
}
lpGray = (LPSTR) ::GlobalLock(hGray);
// 创建灰度图的颜色表 计算每个像素点的灰度值,即求平均即可
LPLOGPALETTE lpGrayPal=(LPLOGPALETTE)(lpGray+40);
unsigned char * lpBits=(unsigned char *)FindDIBBits(lpDIB);
int rowLenSr=0;
BYTE* lpGrayBits=(BYTE*)(lpGrayPal)+dwGrayPal;
int i,j,k;
if(24==lpDIBHdr->biBitCount)
{
lpGrayPal->palNumEntries=256;
lpGrayPal->palVersion=PALVERSION;
for(i=0;i<256;i++)
{
lpGrayPal->palPalEntry[i].peBlue=i;
lpGrayPal->palPalEntry[i].peGreen=i;
lpGrayPal->palPalEntry[i].peRed=i;
lpGrayPal->palPalEntry[i].peFlags=0;
}
rowLenSr=WIDTHBYTES(24*lpDIBHdr->biWidth);
for (i=0;i<lpDIBHdr->biHeight;i++)
{
for (j=0; j<lpDIBHdr->biWidth; j++)
{
k=i*rowLenSr+3*j;
lpGrayBits[i*rowLenDes+j]=(BYTE)(0.114*lpBits[k]+0.587*lpBits[k+1]+0.299*lpBits[k+2]);
}
for (j=lpDIBHdr->biWidth;j<rowLenDes;j++)
{
lpGrayBits[i*rowLenDes+j]=0;
}
}
}
else
{
LPLOGPALETTE lpPal=(LPLOGPALETTE)((LPSTR)lpDIBHdr+40);
lpGrayPal->palNumEntries=DIBNumColors((LPSTR)lpDIBHdr);
lpGrayPal->palVersion=PALVERSION;
unsigned char r,g,b,aver;
for(i=0;i<lpGrayPal->palNumEntries;i++)
{
b=(unsigned char)lpPal->palPalEntry[i].peBlue;
g=(unsigned char)lpPal->palPalEntry[i].peGreen;
r=(unsigned char)lpPal->palPalEntry[i].peRed;
aver=(unsigned char)(0.114*b+0.587*g+0.299*r);
lpGrayPal->palPalEntry[i].peBlue=aver;
lpGrayPal->palPalEntry[i].peGreen=aver;
lpGrayPal->palPalEntry[i].peRed=aver;
lpGrayPal->palPalEntry[i].peFlags=0;
}
memcpy((LPSTR)lpGrayBits,(LPSTR)lpBits,dwData);
}
// 创建灰度图的信息头
LPBITMAPINFOHEADER lpGrayHdr=(LPBITMAPINFOHEADER)lpGray;
memcpy(lpGrayHdr, lpDIBHdr, dwInfo);
if(dwPal==0)
{
lpGrayHdr->biSizeImage=dwData;
lpGrayHdr->biBitCount=8;
lpGrayHdr->biClrUsed=256;
}
::GlobalUnlock(hGray);
return (HDIB)hGray;
}
当然,若是得到灰度图可以覆盖原来的24位位图,则可以直接在已有的图片存储区操作,不用开辟新的存储区,此时函数的传入参数可以改为引用类型或输出参数改为指针类型。
HDIB WINAPI DIBToGray(LPSTR lpDIB)
{
// 获取位图的信息头
LPBITMAPINFOHEADER lpDIBHdr; // 指向BITMAPINFOHEADER的指针
lpDIBHdr=(LPBITMAPINFOHEADER)lpDIB;
LPSTR lpGray;
// 计算位图图的信息头、调色板和图形数据的大小, 并给灰度图分配内存
int dwInfo=lpDIBHdr->biSize;
int dwPal=::DIBNumColors((LPSTR)lpDIBHdr)*sizeof(RGBQUAD);
int dwData=lpDIBHdr->biSizeImage;
int dwGrayPal=dwPal;
if(dwPal==0)
{
dwGrayPal=256*sizeof(RGBQUAD);
dwData=lpDIBHdr->biHeight*lpDIBHdr->biWidth;
}
int sizeTotal=dwInfo+dwGrayPal+dwData;
HGLOBAL hGray=(HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeTotal);
if (hGray==0)
{
return NULL; //内存分配失败则返回NULL
}
lpGray = (LPSTR) ::GlobalLock(hGray);
// 创建灰度图的颜色表 计算每个像素点的灰度值,即求平均即可
LPLOGPALETTE lpGrayPal=(LPLOGPALETTE)(lpGray+40);
char * lpBits=FindDIBBits(lpDIB);
int rowLen=WIDTHBYTES(8*lpDIBHdr->biWidth);
BYTE* lpGrayBits=(BYTE*)(lpGrayPal)+dwGrayPal;
int aver=0;
int i,j,k;
if(24==lpDIBHdr->biBitCount)
{
lpGrayPal->palNumEntries=256;
lpGrayPal->palVersion=PALVERSION;
for(i=0;i<256;i++)
{
lpGrayPal->palPalEntry[i].peBlue=i;
lpGrayPal->palPalEntry[i].peGreen=i;
lpGrayPal->palPalEntry[i].peRed=i;
lpGrayPal->palPalEntry[i].peFlags=0;
}
for (i=0;i<lpDIBHdr->biHeight;i++)
{
for (j=0; j<rowLen; j++)
{
k=i*3*rowLen+3*j;
lpGrayBits[i*rowLen+j]=(lpBits[k]+lpBits[k+1]+lpBits[k+2])/3;
}
}
}
// 创建灰度图的信息头
LPBITMAPINFOHEADER lpGrayHdr=(LPBITMAPINFOHEADER)lpGray;
memcpy(lpGrayHdr, lpDIBHdr, dwInfo);
if(dwPal==0)
{
lpGrayHdr->biSizeImage=sizeTotal;
lpGrayHdr->biBitCount=8;
lpGrayHdr->biClrUsed=256;
}
::GlobalUnlock(hGray);
return (HDIB)hGray;
}
在 (BYTE*)(lpGrayPal)+dwGrayPal; 中,最初由于写成了(BYTE*)(lpGrayPal+dwGrayPal);造成了分配的内存不够,一开始是尝试着多分配了一些内存,但是读出来的图像发生了错位,后来发现,dwGrayPal事实上已经是代表了dwGrayPal*sizeof(LOGPALETTE)的大小了,故而发生了错位。由此可以发现,指针增量的类型是十分重要的!
本来以为前面的代码已经算是做完了,但是今天上午换了张图片时,发现得到的灰度图发生了严重的倾斜,并且在第二次灰度化(第二次调用这个函数的时候,发现就是一张纯黑色的图片)。分析原因如下:
纯黑色是因为第二次进入这个函数的时候,只是重新复制了信息头,而调色板和图片数据都没有进行任何操作。而图片倾斜,则是因为位图在存储的时候,如果每一行的像素值所占的字节数为4的倍数时,则正常存储;否则要在后端补零。昨天试验的图片因为其行数恰好是4的倍数,所以没有出现异常,而今天试验的图片不是4的倍数,所以发生了倾斜。
下面给出校正后的代码:
HDIB WINAPI DIBToGray(LPSTR lpDIB)
{
// 获取位图的信息头
LPBITMAPINFOHEADER lpDIBHdr; // 指向BITMAPINFOHEADER的指针
lpDIBHdr=(LPBITMAPINFOHEADER)lpDIB;
LPSTR lpGray;
// 计算位图图的信息头、调色板和图形数据的大小, 并给灰度图分配内存
int dwInfo=lpDIBHdr->biSize;
int dwPal=::DIBNumColors((LPSTR)lpDIBHdr)*sizeof(RGBQUAD);
int dwData=lpDIBHdr->biSizeImage;
int dwGrayPal=dwPal;
int rowLenDes=WIDTHBYTES(8*lpDIBHdr->biWidth);
if(dwPal==0)
{
dwGrayPal=256*sizeof(RGBQUAD);
dwData=lpDIBHdr->biHeight*rowLenDes;
}
int sizeTotal=dwInfo+dwGrayPal+dwData;
HGLOBAL hGray=(HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeTotal);
if (hGray==0)
{
return NULL; //内存分配失败则返回NULL
}
lpGray = (LPSTR) ::GlobalLock(hGray);
// 创建灰度图的颜色表 计算每个像素点的灰度值,即求平均即可
LPLOGPALETTE lpGrayPal=(LPLOGPALETTE)(lpGray+40);
char * lpBits=FindDIBBits(lpDIB);
int rowLenSr=0;
BYTE* lpGrayBits=(BYTE*)(lpGrayPal)+dwGrayPal;
int i,j,k;
if(24==lpDIBHdr->biBitCount)
{
lpGrayPal->palNumEntries=256;
lpGrayPal->palVersion=PALVERSION;
for(i=0;i<256;i++)
{
lpGrayPal->palPalEntry[i].peBlue=i;
lpGrayPal->palPalEntry[i].peGreen=i;
lpGrayPal->palPalEntry[i].peRed=i;
lpGrayPal->palPalEntry[i].peFlags=0;
}
rowLenSr=WIDTHBYTES(24*lpDIBHdr->biWidth);
for (i=0;i<lpDIBHdr->biHeight;i++)
{
for (j=0; j<lpDIBHdr->biWidth; j++)
{
k=i*rowLenSr+3*j;
lpGrayBits[i*rowLenDes+j]=(lpBits[k]+lpBits[k+1]+lpBits[k+2])/3;
}
for (j=lpDIBHdr->biWidth;j<rowLenDes;j++)
{
lpGrayBits[i*rowLenDes+j]=0;
}
}
}
else
{
memcpy((LPSTR)lpGrayPal,(LPSTR)lpDIBHdr+40,dwGrayPal+dwData);
}
// 创建灰度图的信息头
LPBITMAPINFOHEADER lpGrayHdr=(LPBITMAPINFOHEADER)lpGray;
memcpy(lpGrayHdr, lpDIBHdr, dwInfo);
if(dwPal==0)
{
lpGrayHdr->biSizeImage=dwData;
lpGrayHdr->biBitCount=8;
lpGrayHdr->biClrUsed=256;
}
::GlobalUnlock(hGray);
return (HDIB)hGray;
}
后来发现前面所给的代码得到的灰度图并不理想,查看相关书籍后才发现灰度图转化并不是简单地将RGB三个分量的值求平均,具体说明如下:除了RGB颜色表示方法外,还有一种称作YUV的表示方法,其中的Y分量是表示亮度,也就是灰度图中的值,而UV表示色差信号。RGB和YUV二者间的转化关系为:
Y=0.299*R+0.587*G+0.114*B对于真彩色图则直接对数据进行处理,而对于其他类型的位图,则只要把调色板中的RGB分量全部用Y来替代就可以了,并给出更新后的代码:
HDIB WINAPI DIBToGray(LPSTR lpDIB)
{
// 获取位图的信息头
LPBITMAPINFOHEADER lpDIBHdr; // 指向BITMAPINFOHEADER的指针
lpDIBHdr=(LPBITMAPINFOHEADER)lpDIB;
LPSTR lpGray;
// 计算位图图的信息头、调色板和图形数据的大小, 并给灰度图分配内存
int dwInfo=lpDIBHdr->biSize;
int dwPal=::DIBNumColors((LPSTR)lpDIBHdr)*sizeof(RGBQUAD);
int dwData=lpDIBHdr->biSizeImage;
int dwGrayPal=dwPal;
int rowLenDes=WIDTHBYTES(8*lpDIBHdr->biWidth);
if(dwPal==0)
{
dwGrayPal=256*sizeof(RGBQUAD);
dwData=lpDIBHdr->biHeight*rowLenDes;
}
int sizeTotal=dwInfo+dwGrayPal+dwData;
HGLOBAL hGray=(HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeTotal);
if (hGray==0)
{
return NULL; //内存分配失败则返回NULL
}
lpGray = (LPSTR) ::GlobalLock(hGray);
// 创建灰度图的颜色表 计算每个像素点的灰度值,即求平均即可
LPLOGPALETTE lpGrayPal=(LPLOGPALETTE)(lpGray+40);
unsigned char * lpBits=(unsigned char *)FindDIBBits(lpDIB);
int rowLenSr=0;
BYTE* lpGrayBits=(BYTE*)(lpGrayPal)+dwGrayPal;
int i,j,k;
if(24==lpDIBHdr->biBitCount)
{
lpGrayPal->palNumEntries=256;
lpGrayPal->palVersion=PALVERSION;
for(i=0;i<256;i++)
{
lpGrayPal->palPalEntry[i].peBlue=i;
lpGrayPal->palPalEntry[i].peGreen=i;
lpGrayPal->palPalEntry[i].peRed=i;
lpGrayPal->palPalEntry[i].peFlags=0;
}
rowLenSr=WIDTHBYTES(24*lpDIBHdr->biWidth);
for (i=0;i<lpDIBHdr->biHeight;i++)
{
for (j=0; j<lpDIBHdr->biWidth; j++)
{
k=i*rowLenSr+3*j;
lpGrayBits[i*rowLenDes+j]=(BYTE)(0.114*lpBits[k]+0.587*lpBits[k+1]+0.299*lpBits[k+2]);
}
for (j=lpDIBHdr->biWidth;j<rowLenDes;j++)
{
lpGrayBits[i*rowLenDes+j]=0;
}
}
}
else
{
LPLOGPALETTE lpPal=(LPLOGPALETTE)((LPSTR)lpDIBHdr+40);
lpGrayPal->palNumEntries=DIBNumColors((LPSTR)lpDIBHdr);
lpGrayPal->palVersion=PALVERSION;
unsigned char r,g,b,aver;
for(i=0;i<lpGrayPal->palNumEntries;i++)
{
b=(unsigned char)lpPal->palPalEntry[i].peBlue;
g=(unsigned char)lpPal->palPalEntry[i].peGreen;
r=(unsigned char)lpPal->palPalEntry[i].peRed;
aver=(unsigned char)(0.114*b+0.587*g+0.299*r);
lpGrayPal->palPalEntry[i].peBlue=aver;
lpGrayPal->palPalEntry[i].peGreen=aver;
lpGrayPal->palPalEntry[i].peRed=aver;
lpGrayPal->palPalEntry[i].peFlags=0;
}
memcpy((LPSTR)lpGrayBits,(LPSTR)lpBits,dwData);
}
// 创建灰度图的信息头
LPBITMAPINFOHEADER lpGrayHdr=(LPBITMAPINFOHEADER)lpGray;
memcpy(lpGrayHdr, lpDIBHdr, dwInfo);
if(dwPal==0)
{
lpGrayHdr->biSizeImage=dwData;
lpGrayHdr->biBitCount=8;
lpGrayHdr->biClrUsed=256;
}
::GlobalUnlock(hGray);
return (HDIB)hGray;
}
当然,若是得到灰度图可以覆盖原来的24位位图,则可以直接在已有的图片存储区操作,不用开辟新的存储区,此时函数的传入参数可以改为引用类型或输出参数改为指针类型。
相关文章推荐
- 24位真色位图转化为8位灰度位图
- DIB(设备无关位图)编程系列(二)——24位真彩图转256阶(8位)灰度图
- DIB(设备无关位图)编程系列(二)―24位真彩图转256阶(8位)灰度图
- bmp位图文件:读取、写入、24位真彩转8位灰度、灰度图的二值化
- 24位真彩位图转4位(16色)灰度图(BMP)
- 24位位图转8位灰度图
- 24位位图转8位灰度图
- 24位位图转化为8位位图 位图头部信息BITMAPFILEHEADER BITMAPINFOHEADER修改代码
- vc++ 位图转化为 灰度图
- 24位真彩位图转4位(16色)灰度图(BMP) .
- 用matlab读取位图并以灰度图的方式显示
- Android中常用的位图操作(View与Bitmap转化、圆角、灰化、提取Alpha、旋转、倒影、剪切……)
- WINCE下点阵转化为位图
- ARGB32位转化为RGB24位的函数
- 实现1位,4位,8位,24位BMP位图的互相转换的方法,32位转24位
- BMP真彩图转化为灰度图处理方法
- OpenCV-将图像两次缩放+转化为灰度图+边缘检测
- C++实现24位位图的灰度化
- 为什么24位位图(真彩色)的biSizeImage不等于(biWidth*biBitCount+31)/32*4*biHeight?
- C++8位和24位bmp位图平滑、锐化和二值处理,24位真彩图的灰度化