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