画像処理に用いるボリューム関数

13955 ワード

画像処理をするには、最も時間のかかる演算がボリューム演算のステップであるはずです.今後,c++で画像処理を行う機会があれば,このボリューム部分は最適化される.Matlabは検証アルゴリズムなので、実は最適化する必要はありません.だから私はボリュームのこの部分を単独で関数をリストして、アセンブリで実現しました.私は電子工学出身なので、編集はもちろん話にならない.
関数はアセンブリで書かれており、c++内蔵asmアセンブリで、同じ機能のc++コードも実現していますが、注釈を外しても同じ結果が得られます.
画像の読み取りと表示にはopencv関数ライブラリが使われていますが、前のプロジェクトが終わった後はあまりこのライブラリを使ったことがないようです.結局、ライブラリの関数を呼び出すだけでは原理が本当に理解できません.
#include <iostream>
#include "cv.h"
#include "highgui.h"
using namespace std;

//*img     ,i_h     ,i_w     
//*m     ,m_h     ,m_w     
//x,y    (x,y)     
//      
int conv(int *img,int i_h,int i_w,int *m,int m_h,int m_w,int y,int x)
{
    int re;
    int sum1;
    int sum2;
    int half_m_w;
    int half_m_h;
    int i;
    int j;
    int ii;
    int jj;
    __asm
    {
        mov        re,0;
        mov        sum1,0;
        mov        sum2,0;

        mov        eax,m_w;        //half_m_w=(m_w-1)/2;
        dec        eax;
        mov        bl,2;
        div        bl;
        mov        ah,0;
        mov        half_m_w,eax;

        mov        eax,m_h;        //half_m_h=(m_h-1)/2;
        dec        eax;
        mov        bl,2;
        div        bl;
        mov        ah,0;
        mov        half_m_h,eax;

        mov        ecx,m_w;        //m_w*h_h
        imul      ecx,m_h;
        mov        eax,0;

label1:
        mov        ebx,m;            //        for (i=0;i<m_w*m_h;i++)                                                                                                                    
        add        eax,[ebx];        //        {
        add        ebx,4;            //            sum2+=m[i];
        dec        ecx;            //        }
        jnz        label1;
        mov        sum2,eax;

        mov        i,0;
        mov        ii,0;
        mov        eax,y;            //i=y-half_m_h;
        sub        eax,half_m_h;
        mov        i,eax;

label2:
        mov        j,0;
        mov        jj,0;
        mov        eax,x;            //j=x-half_m_w;
        sub        eax,half_m_w;
        mov        j,eax;

label3:        
        mov        ebx,img;        //        img  
        mov        edx,m;            //      m  

        mov        eax,i;            //i*i_w+j
        imul    eax,4;
        imul    eax,i_w;
        mov        ecx,j;
        imul    ecx,4;
        add        eax,ecx;
        add        ebx,eax;

        mov        eax,ii;            //ii*m_w+jj
        imul      eax,4;
        imul      eax,m_w;
        mov        ecx,jj;
        imul      ecx,4;
        add        eax,ecx;
        add        edx,eax;

        mov        eax,[ebx];        //sum1+=img[i*i_w+j]*m[ii*m_w+jj];
        imul      eax,[edx];
        add        eax,sum1;
        mov        sum1,eax;

        mov        eax,jj;            //jj++
        inc        eax;
        mov        jj,eax;

        mov        eax,x;            //j?<x+half_m_w
        add        eax,half_m_w;
        mov        ecx,eax;
        sub        ecx,j;
        mov        eax,j;            //j++
        inc        eax;
        mov        j,eax;

        test      ecx,ecx;
        jnz        label3;
         
        mov        eax,ii;            //ii++
        inc        eax;
        mov        ii,eax;

        mov        eax,y;            //i?<y+half_m_h
        add        eax,half_m_h;
        mov        ecx,eax;
        sub        ecx,i;
        mov        eax,i;            //i++
        inc        eax;
        mov        i,eax;

        test      ecx,ecx;
        jnz        label2;

        mov        eax,sum1;        //sum1/sum2
        mov        ebx,sum2;
        div        bl;
        mov        ah,0;
        mov        re,eax;

    }    
    /*
    half_m_h=(m_h-1)/2;
    half_m_w=(m_w-1)/2;
    sum1=0;
    sum2=0;
    for (i=0;i<m_w*m_h;i++)
    {
        sum2+=m[i];
    }

    for (i=y-half_m_h,ii=0;i<=y+half_m_h;i++,ii++)
    {
        for (j=x-half_m_w,jj=0;j<=x+half_m_w;j++,jj++)
        {
            sum1+=img[i*i_w+j]*m[ii*m_w+jj];
        }
    }
    re=int(sum1/sum2);
    */
    return re;
}

int main()
{
    IplImage *image;
    CvScalar s;
    image=cvLoadImage("C:/Users/tc/Documents/Visual Studio 2010/Projects/vm/Debug/lena.jpg",0);

    int *img;
    img=new int[image->height*image->width];

    for (int i=0;i<image->height;i++)
    {
        for (int j=0;j<image->width;j++)
        {
            s=cvGet2D(image,i,j);
            img[i*image->width+j]=(int)s.val[0];
        }
    }

    int *m;
    m=new int[9];
    for (int i=0;i<9;i++)
    {
        m[i]=1;
    }

    for (int i=1;i<image->height-1;i++)
    {
        for (int j=1;j<image->width-1;j++)
        {
            s=cvGet2D(image,i,j);
            s.val[0]=conv(img,image->height,image->width,m,3,3,i,j);
            cvSet2D(image,i,j,s);
        }
    }

    cvNamedWindow("lena",1);
    cvShowImage("lena",image);

    cvWaitKey(0);
    cvReleaseImage(&image);
    cvDestroyAllWindows();
    delete[] img;
    delete[] m;
    return 0;
}

: mmx,sse , 。