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

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

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

这里主要用了pcmpgtb指令

格式 pcmpgtb mm0,mm1; 

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

当然,相关还有pcmpgtw等。

详见这里

//本程序算是一个简单的框架了,可以用来处理图像
//主要是用来学习多媒体指令mmx/sse相关的。
#include 
#include 
#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);
    }
} 

效果:

多媒体指令(图像二值化)_第1张图片

转载于:https://www.cnblogs.com/tiandsp/archive/2013/03/14/2960437.html

你可能感兴趣的:(多媒体指令(图像二值化))