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


    主要用来学习多媒体指令的,要不我也不会这么麻烦的用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);
        }
    } 

    效果:

  • 相关阅读:
    人与人之间的本质
    如何让百度搜索不到
    js.prototype最深刻的理解
    调用函数不能用&
    浏览器的缓存就是关闭了浏览器任然存在
    Spring switch的使用
    thymeleaf如何遍历数据 each循环的使用
    spring 机制 扫描包
    Spring分层次建包
    如何使用thymeleaf显示控制传递过来的数据
  • 原文地址:https://www.cnblogs.com/tiandsp/p/2960437.html
Copyright © 2020-2023  润新知