24位真彩色转换为8位灰度图片(完整代码)

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

图像的灰度与二值化

http://www.cnblogs.com/maozefa/archive/2011/12/09/2281656.html

    图像的灰度化与二值化是图像处理中最常见的处理方法,也是很多图像处理方法的基础,如图像灰度统计、图像识别等。

    图像的灰度化与二值化方法较多,处理过程也比较简单。但切不可因其简单而忽视效率。如常用的图像灰度计算公式:gray = red * 0.299 + green * 0.587 + blue * 0.114,如果在程序代码中直接套用了这个公式,因浮点数的缘故导致代码执行效率较低,如改为定点整数运算,可使执行效率大大提高。

    下面是图像的灰度与二值化代码:

// 定义ARGB像素结构
typedef union
{
    ARGB Color;
    struct
    {
        BYTE Blue;
        BYTE Green;
        BYTE Red;
        BYTE Alpha;
    };
}ARGBQuad, *PARGBQuad;
// ---------------------------------------------------------------------------

// 图像数据data灰度化
VOID Gray(BitmapData *data)
{
    PARGBQuad p = (PARGBQuad)data->Scan0;
    INT offset = data->Stride - data->Width * sizeof(ARGBQuad);

    for (UINT y = 0; y < data->Height; y ++, (BYTE*)p += offset)
    {
        for (UINT x = 0; x < data->Width; x ++, p ++)
            p->Blue = p->Green = p->Red =
                (UINT)(p->Blue * 29 + p->Green * 150 + p->Red * 77 + 128) >> 8;

    }
}
// ---------------------------------------------------------------------------

// 图像数据data灰度同时二值化,threshold阀值
VOID GrayAnd2Values(BitmapData *data, BYTE threshold)
{
    PARGBQuad p = (PARGBQuad)data->Scan0;
    INT offset = data->Stride - data->Width * sizeof(ARGBQuad);

    for (UINT y = 0; y < data->Height; y ++, (BYTE*)p += offset)
    {
        for (UINT x = 0; x < data->Width; x ++, p ++)
        {
            if (((p->Blue * 29 + p->Green * 150 + p->Red * 77 + 128) >> 8) < threshold)
                p->Color &= 0xff000000;
            else
                p->Color |= 0x00ffffff;

        }
    }
}
// ---------------------------------------------------------------------------

    因本文使用的是32位图像数据,所以图像的二值化没有采用通常的赋值操作p->Blue = p->Green = p->Red = 0(或者255),而是采用了位运算。

    下面是使用BCB2007和GDI+图像数据实现图像灰度和二值化的例子代码:

// 锁定GDI+位位图扫描线到data
FORCEINLINE
VOID LockBitmap(Gdiplus::Bitmap *bmp, BitmapData *data)
{
    Gdiplus::Rect r( 0, 0, bmp->GetWidth(), bmp->GetHeight());
    bmp->LockBits(&r, ImageLockModeRead | ImageLockModeWrite,
        PixelFormat32bppARGB, data);
}
// ---------------------------------------------------------------------------

// GDI+位图扫描线解锁
FORCEINLINE
VOID UnlockBitmap(Gdiplus::Bitmap *bmp, BitmapData *data)
{
    bmp->UnlockBits(data);
}
// ---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    Gdiplus::Bitmap *bmp =  new Gdiplus::Bitmap(L " d:\\source1.jpg ");
    Gdiplus::Graphics *g = new Gdiplus::Graphics(Canvas->Handle);
    g->DrawImage(bmp, 0, 0);
    BitmapData data;
    LockBitmap(bmp, &data);
//     Gray(&data);
    GrayAnd2Values(&data, 128);

    UnlockBitmap(bmp, &data);
    g->DrawImage(bmp, data.Width, 0);
    delete g;
    delete bmp;
}
// ---------------------------------------------------------------------------

 

 

 

24位真彩色转换为8位灰度图片(完整代码)

 

 

//Code By xets007
//
转载请注明出处
//

#include <windows.h>

BOOL BMP24to8(char *szSourceFile,char *szTargetFile);

 

int main(int argc,char* argv[])
{

//调用这个函数直接把24位真彩色灰度化

BOOL stat=BMP24to8("c://source.bmp","c://target.bmp");

return 0;

}

BOOL BMP24to8(char *szSourceFile,char *szTargetFile)

{

HANDLE hSourceFile=INVALID_HANDLE_VALUE,hTargetFile=INVALID_HANDLE_VALUE;
DWORD dwSourceSize=0,dwTargetSize=0;

PBYTE pSource=NULL,pTarget=NULL;

hSourceFile=CreateFile(szSourceFile,GENERIC_READ,FILE_SHARE_READ,NULL,

OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hSourceFile==INVALID_HANDLE_VALUE)

   return FALSE;

dwSourceSize=GetFileSize(hSourceFile,NULL);
pSource=(PBYTE)VirtualAlloc(NULL,dwSourceSize,MEM_COMMIT,PAGE_READWRITE);

//分配空间失败或者文件太小(BMP文件不可能小于54个字节)

 

if(pSource==NULL||dwSourceSize<=54)

{

   CloseHandle(hSourceFile);

   return FALSE;

}

DWORD dwTemp=0;

ReadFile(hSourceFile,pSource,dwSourceSize,&dwTemp,NULL);

BITMAPFILEHEADER *pSourceFileHeader=(BITMAPFILEHEADER*)pSource;

BITMAPINFOHEADER *pSourceInfoHeader=(BITMAPINFOHEADER*)(pSource+sizeof(BITMAPFILEHEADER));

 //不是BMP文件或者不是24位真彩色

 

if(pSourceFileHeader->bfType!=0x4d42||pSourceInfoHeader->biBitCount!=24)

{

CloseHandle(hSourceFile);

VirtualFree(pSource,NULL,MEM_RELEASE);

return FALSE;

}

CloseHandle(hSourceFile);

LONG nWidth=pSourceInfoHeader->biWidth;

LONG nHeight=pSourceInfoHeader->biHeight;

<
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值