void speedy_convolution( const CvMat *A,//size:M1 * N1 const CvMat *B, //size : M2 * N2 CvMat *C //size:(M1+M2-1) * (N1+N2-1) ) { int dft_M = cvGetOptimalDFTSize(A->rows + B->rows -1); int dft_N = cvGetOptimalDFTSize(A->cols + B->cols -1); CvMat *dft_A = cvCreateMat(dft_M , dft_N , A->type); CvMat *dft_B = cvCreateMat(dft_M, dft_N, B->type); CvMat tmp; //copy A TO dft_A and pad dft_A with zeros cvGetSubRect(dft_A,&tmp , cvRect(0,0,A->cols,A->rows)); cvCopy(A,&tmp); cvGetSubRect(dft_A,&tmp,cvRect(A->cols,0,dft_A->cols - A->cols , A->rows)); cvZero(&tmp); //no need to pad bottom part of dft_A with zeros because of //use nonzero_rows parameter in cvDFT() call below cvDFT(dft_A,dft_A,CV_DXT_FORWARD,A->rows); //repeat the same with the second array cvGetSubRect(dft_B,&tmp,cvRect(0,0,B->cols,B->rows)); cvCopy(B,&tmp); cvGetSubRect(dft_B,&tmp,cvRect(B->cols,0,dft_B->cols - B->cols , B->rows)); cvZero(&tmp); //no need to pad bottom part of dft_B with zeros because of //use nonzero-rows parameter in cvDFT() call below cvDFT(dft_B,dft_B,CV_DXT_FORWARD,B->rows); //or CV_DXT_MUL_CONJ to get correlation rather than convolution cvMulSpectrums(dft_A,dft_B,dft_A,0); //calculate only the top part cvDFT(dft_A,dft_A,CV_DXT_INV_SCALE,C->rows); cvGetSubRect(dft_A,&tmp,cvRect(0,0,C->cols,C->rows)); cvCopy(&tmp,C); cvReleaseMat(dft_A); cvReleaseMat(dft_B); }