博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何优化图像卷积
阅读量:4539 次
发布时间:2019-06-08

本文共 10582 字,大约阅读时间需要 35 分钟。

一、图像卷积:

二、DFT---离散傅里叶变换(Discrete Fourier Transform)

      1、傅里叶级数(DFS):表示一个周期信号可以用一族正交完备的正弦波通过线性组合得到。

                                                建立时频关系。

                                 

      2、离散傅里叶变换(DFT)

           1)为何使用Dirac(\delta)函数:

      3、快速傅里叶变换(FFT):加速多项式乘法         

/************FFT***********/  #include   
#include
#include
#define N 1000 typedef struct { double real; double img; }complex; void fft(); /*快速傅里叶变换*/ void ifft(); /*快速傅里叶逆变换*/ void initW(); void change(); void add(complex ,complex ,complex *); /*复数加法*/ void mul(complex ,complex ,complex *); /*复数乘法*/ void sub(complex ,complex ,complex *); /*复数减法*/ void divi(complex ,complex ,complex *);/*复数除法*/ void output(); /*输出结果*/ complex x[N], *W;/*输出序列的值*/ int size_x=0;/*输入序列的长度,只限2的N次方*/ double PI; int main() { int i,method; system("cls"); PI=atan(1)*4; printf("Please input the size of x:\n"); /*输入序列的长度*/ scanf("%d",&size_x); printf("Please input the data in x[N]:(such as:5 6)\n"); /*输入序列对应的值*/ for(i=0;i
0 ) { j=j<<1; j|=(k & 1); k=k>>1; } if(j>i) { temp=x[i]; x[i]=x[j]; x[j]=temp; } } } void output() /*输出结果*/ { int i; printf("The result are as follows\n"); for(i=0;i
=0.0001) printf("+%.4fj\n",x[i].img); else if(fabs(x[i].img)<0.0001) printf("\n"); else printf("%.4fj\n",x[i].img); } } void add(complex a,complex b,complex *c) { c->real=a.real+b.real; c->img=a.img+b.img; } void mul(complex a,complex b,complex *c) { c->real=a.real*b.real - a.img*b.img; c->img=a.real*b.img + a.img*b.real; } void sub(complex a,complex b,complex *c) { c->real=a.real-b.real; c->img=a.img-b.img; } void divi(complex a,complex b,complex *c) { c->real=( a.real*b.real+a.img*b.img )/( b.real*b.real+b.img*b.img); c->img=( a.img*b.real-a.real*b.img)/(b.real*b.real+b.img*b.img); }
View Code

      4、2d加速图像卷积

           将2d核拆分成行向量与列向量乘积的形式 

bool convolve2DFast(unsigned char* in, unsigned char* out, int dataSizeX, int dataSizeY,                    float* kernel, int kernelSizeX, int kernelSizeY){    int i, j, m, n, x, y, t;    unsigned char **inPtr, *outPtr, *ptr;    int kCenterX, kCenterY;    int rowEnd, colEnd;                             // ending indice for section divider    float sum;                                      // temp accumulation buffer    int k, kSize;    // check validity of params    if(!in || !out || !kernel) return false;    if(dataSizeX <= 0 || kernelSizeX <= 0) return false;    // find center position of kernel (half of kernel size)    kCenterX = kernelSizeX >> 1;    kCenterY = kernelSizeY >> 1;    kSize = kernelSizeX * kernelSizeY;              // total kernel size    // allocate memeory for multi-cursor    inPtr = new unsigned char*[kSize];    if(!inPtr) return false;                        // allocation error    // set initial position of multi-cursor, NOTE: it is swapped instead of kernel    ptr = in + (dataSizeX * kCenterY + kCenterX); // the first cursor is shifted (kCenterX, kCenterY)    for(m=0, t=0; m < kernelSizeY; ++m)    {        for(n=0; n < kernelSizeX; ++n, ++t)        {            inPtr[t] = ptr - n;        }        ptr -= dataSizeX;    }    // init working  pointers    outPtr = out;    rowEnd = dataSizeY - kCenterY;                  // bottom row partition divider    colEnd = dataSizeX - kCenterX;                  // right column partition divider    // convolve rows from index=0 to index=kCenterY-1    y = kCenterY;    for(i=0; i < kCenterY; ++i)    {        // partition #1 ***********************************        x = kCenterX;        for(j=0; j < kCenterX; ++j)                 // column from index=0 to index=kCenterX-1        {            sum = 0;            t = 0;            for(m=0; m <= y; ++m)            {                for(n=0; n <= x; ++n)                {                    sum += *inPtr[t] * kernel[t];                    ++t;                }                t += (kernelSizeX - x - 1);         // jump to next row            }            // store output            *outPtr = (unsigned char)((float)fabs(sum) + 0.5f);            ++outPtr;            ++x;            for(k=0; k < kSize; ++k) ++inPtr[k];    // move all cursors to next        }        // partition #2 ***********************************        for(j=kCenterX; j < colEnd; ++j)            // column from index=kCenterX to index=(dataSizeX-kCenterX-1)        {            sum = 0;            t = 0;            for(m=0; m <= y; ++m)            {                for(n=0; n < kernelSizeX; ++n)                {                    sum += *inPtr[t] * kernel[t];                    ++t;                }            }            // store output            *outPtr = (unsigned char)((float)fabs(sum) + 0.5f);            ++outPtr;            ++x;            for(k=0; k < kSize; ++k) ++inPtr[k];    // move all cursors to next        }        // partition #3 ***********************************        x = 1;        for(j=colEnd; j < dataSizeX; ++j)           // column from index=(dataSizeX-kCenter) to index=(dataSizeX-1)        {            sum = 0;            t = x;            for(m=0; m <= y; ++m)            {                for(n=x; n < kernelSizeX; ++n)                {                    sum += *inPtr[t] * kernel[t];                    ++t;                }                t += x;                             // jump to next row            }            // store output            *outPtr = (unsigned char)((float)fabs(sum) + 0.5f);            ++outPtr;            ++x;            for(k=0; k < kSize; ++k) ++inPtr[k];    // move all cursors to next        }        ++y;                                        // add one more row to convolve for next run    }    // convolve rows from index=kCenterY to index=(dataSizeY-kCenterY-1)    for(i= kCenterY; i < rowEnd; ++i)               // number of rows    {        // partition #4 ***********************************        x = kCenterX;        for(j=0; j < kCenterX; ++j)                 // column from index=0 to index=kCenterX-1        {            sum = 0;            t = 0;            for(m=0; m < kernelSizeY; ++m)            {                for(n=0; n <= x; ++n)                {                    sum += *inPtr[t] * kernel[t];                    ++t;                }                t += (kernelSizeX - x - 1);            }            // store output            *outPtr = (unsigned char)((float)fabs(sum) + 0.5f);            ++outPtr;            ++x;            for(k=0; k < kSize; ++k) ++inPtr[k];    // move all cursors to next        }        // partition #5 ***********************************        for(j = kCenterX; j < colEnd; ++j)          // column from index=kCenterX to index=(dataSizeX-kCenterX-1)        {            sum = 0;            t = 0;            for(m=0; m < kernelSizeY; ++m)            {                for(n=0; n < kernelSizeX; ++n)                {                    sum += *inPtr[t] * kernel[t];                    ++inPtr[t]; // in this partition, all cursors are used to convolve. moving cursors to next is safe here                    ++t;                }            }            // store output            *outPtr = (unsigned char)((float)fabs(sum) + 0.5f);            ++outPtr;            ++x;        }        // partition #6 ***********************************        x = 1;        for(j=colEnd; j < dataSizeX; ++j)           // column from index=(dataSizeX-kCenter) to index=(dataSizeX-1)        {            sum = 0;            t = x;            for(m=0; m < kernelSizeY; ++m)            {                for(n=x; n < kernelSizeX; ++n)                {                    sum += *inPtr[t] * kernel[t];                    ++t;                }                t += x;            }            // store output            *outPtr = (unsigned char)((float)fabs(sum) + 0.5f);            ++outPtr;            ++x;            for(k=0; k < kSize; ++k) ++inPtr[k];    // move all cursors to next        }    }    // convolve rows from index=(dataSizeY-kCenterY) to index=(dataSizeY-1)    y = 1;    for(i= rowEnd; i < dataSizeY; ++i)               // number of rows    {        // partition #7 ***********************************        x = kCenterX;        for(j=0; j < kCenterX; ++j)                 // column from index=0 to index=kCenterX-1        {            sum = 0;            t = kernelSizeX * y;            for(m=y; m < kernelSizeY; ++m)            {                for(n=0; n <= x; ++n)                {                    sum += *inPtr[t] * kernel[t];                    ++t;                }                t += (kernelSizeX - x - 1);            }            // store output            *outPtr = (unsigned char)((float)fabs(sum) + 0.5f);            ++outPtr;            ++x;            for(k=0; k < kSize; ++k) ++inPtr[k];    // move all cursors to next        }        // partition #8 ***********************************        for(j=kCenterX; j < colEnd; ++j)            // column from index=kCenterX to index=(dataSizeX-kCenterX-1)        {            sum = 0;            t = kernelSizeX * y;            for(m=y; m < kernelSizeY; ++m)            {                for(n=0; n < kernelSizeX; ++n)                {                    sum += *inPtr[t] * kernel[t];                    ++t;                }            }            // store output            *outPtr = (unsigned char)((float)fabs(sum) + 0.5f);            ++outPtr;            ++x;            for(k=0; k < kSize; ++k) ++inPtr[k];        }        // partition #9 ***********************************        x = 1;        for(j=colEnd; j < dataSizeX; ++j)           // column from index=(dataSizeX-kCenter) to index=(dataSizeX-1)        {            sum = 0;            t = kernelSizeX * y + x;            for(m=y; m < kernelSizeY; ++m)            {                for(n=x; n < kernelSizeX; ++n)                {                    sum += *inPtr[t] * kernel[t];                    ++t;                }                t += x;            }            // store output            *outPtr = (unsigned char)((float)fabs(sum) + 0.5f);            ++outPtr;            ++x;            for(k=0; k < kSize; ++k) ++inPtr[k];    // move all cursors to next        }        ++y;                                        // the starting row index is increased    }    return true;}
View Code

转载于:https://www.cnblogs.com/cjh1122/p/11119344.html

你可能感兴趣的文章
python random
查看>>
input输入框只允许输入数字/ 数字+小数点/ 文字+字母/ 等解决方法
查看>>
【翻译】西川善司「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,前篇(2)...
查看>>
mysql 5.6 参数详解
查看>>
求旋转数组的最小元素
查看>>
Gson解析Json数组
查看>>
Lintcode: Fast Power
查看>>
Pocket Gem OA: Log Parser
查看>>
枚举也能直接转换为对应的数值输出
查看>>
angularjs1-7,供应商
查看>>
BitSet
查看>>
Spring常用注解,自动扫描装配Bean
查看>>
(转载)深入理解WeakHashmap
查看>>
[SCOI2010]生成字符串
查看>>
JLOI2015 城池攻占
查看>>
搭建ntp时间服务器 ntp - (Network Time Protocol)
查看>>
Python中的open和codecs.open
查看>>
asp.net mvc 伪静态添加
查看>>
EA类图与代码同步
查看>>
Android Studio 智能感知无效
查看>>