多媒体指令(图像二值化)

主要用来学习多媒体指令的,要不我也不会这么麻烦的用win32 sdk编程。

果然要只学习图像算法,还是推荐matlab。

这里主要用了pcmpgtb指令

格式 pcmpgtb mm0,mm1; 

解释:当 mm0 中对应字节大于 mm1对应字节时,mm0相应位置置0xff,否则置0x00。

当然,相关还有pcmpgtw等。

详见这里

//本程序算是一个简单的框架了,可以用来处理图像

//主要是用来学习多媒体指令mmx/sse相关的。

#include <windows.h>

#include <gdiplus.h>

#pragma comment(lib, "gdiplus.lib")

using namespace Gdiplus;



typedef union

{

    ARGB Color;

    struct

    {

        BYTE Blue;

        BYTE Green;

        BYTE Red;

        BYTE Alpha;

    };

}Pix;



VOID asmGray2BW(BitmapData *data)

{

    UINT Height=data->Height;

    UINT Width=data->Width;

    Pix* p=(Pix*)data->Scan0;

    UINT n=Height*Width/2;

//非常奇怪,我明明定义的无符号字节,本应该用0x80的,可这里只能用0作为阈值,才相当于cpp版的128

//取0x80808080,无符号单字节是128,可这里显然是有符号的-128,着实奇怪。

//也只能认为mmx寄存器默认为有符号的了。

    Pix cp[]={0x00000000,0x00000000};    

    __asm

    {

        push esi;



        mov ecx,n;

        mov esi,[p];

        movq mm2,[cp];

lp:

        movq    mm1,mm2;

        movq    mm0,[esi];

        pcmpgtb    mm1,mm0;      

        movq    [esi],mm1;

        add esi,8;

        dec    ecx;

        jnz lp;



        pop esi;

        emms;

    }

}



VOID cppGray2BW(BitmapData *data)

{

    Pix* p=(Pix*)data->Scan0;



    for(UINT h = 0; h < data->Height;    ++h)

    {

        for(UINT w = 0; w < data->Width; ++w)

        {

            if (p->Red>128)

            {

                p->Red=0xff;

                p->Blue=0xff;

                p->Green=0xff;    

            }

            else

            {

                p->Red=0;

                p->Blue=0;

                p->Green=0;        

            }        

            ++p;

        }

    }    

}



VOID OnPaint(HDC hdc)

{

    Graphics graphics(hdc);

    

    Bitmap srcbitmap(L"lena.jpg",0);    

    Bitmap *dstbitmap=srcbitmap.Clone(0,0,srcbitmap.GetWidth(),srcbitmap.GetHeight(),srcbitmap.GetPixelFormat());



    BitmapData data;

    Rect rect(0,0,dstbitmap->GetWidth(),dstbitmap->GetHeight());

    

    dstbitmap->LockBits(&rect,ImageLockModeRead | ImageLockModeWrite,PixelFormat32bppARGB,&data);    

    asmGray2BW(&data);

//    cppGray2BW(&data);

    dstbitmap->UnlockBits(&data);

    

    graphics.DrawImage(&srcbitmap,0,0);    

    graphics.DrawImage(dstbitmap,300,0);

    

    delete dstbitmap;

    

}



LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);



INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow)

{

    HWND                hWnd;

    MSG                    msg;

    WNDCLASS            wndClass;

    GdiplusStartupInput gdiplusStartupInput;

    ULONG_PTR            gdiplusToken;



    // Initialize GDI+.

    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);



    wndClass.style          = CS_HREDRAW | CS_VREDRAW;

    wndClass.lpfnWndProc    = WndProc;

    wndClass.cbClsExtra     = 0;

    wndClass.cbWndExtra     = 0;

    wndClass.hInstance      = hInstance;

    wndClass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);

    wndClass.hCursor        = LoadCursor(NULL, IDC_ARROW);

    wndClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);

    wndClass.lpszMenuName   = NULL;

    wndClass.lpszClassName  = TEXT("DIP");



    RegisterClass(&wndClass);



    hWnd = CreateWindow(

        TEXT("DIP"),         // window class name

        TEXT("DIP"),         // window caption

        WS_OVERLAPPEDWINDOW,      // window style

        CW_USEDEFAULT,            // initial x position

        CW_USEDEFAULT,            // initial y position

        600,                    // initial x size

        400,                    // initial y size

        NULL,                     // parent window handle

        NULL,                     // window menu handle

        hInstance,                // program instance handle

        NULL);                    // creation parameters

/*    

    HWND button=CreateWindow("button",

                             "处理",

                             WS_CHILD,

                             200,

                             300,

                             100,

                             30,

                             hWnd,

                             NULL,

                             hInstance,

                             0);

*/

    ShowWindow(hWnd, iCmdShow);

//    ShowWindow(button,iCmdShow);

    UpdateWindow(hWnd);



    while(GetMessage(&msg, NULL, 0, 0))

    {

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }



    GdiplusShutdown(gdiplusToken);

    return msg.wParam;

}  



LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 

    WPARAM wParam, LPARAM lParam)

{

    HDC                hdc;

    PAINTSTRUCT        ps;

    switch(message)

    {

//    case WM_COMMAND:



    case WM_PAINT:

        hdc = BeginPaint(hWnd, &ps);

        OnPaint(hdc);

        EndPaint(hWnd, &ps);

        return 0;

    case WM_DESTROY:

        PostQuitMessage(0);

        return 0;

    default:

        return DefWindowProc(hWnd, message, wParam, lParam);

    }

} 

效果:

多媒体指令(图像二值化)

你可能感兴趣的:(多媒体)