MinFilter算法的快速实现,提供一篇论文供有需要的朋友学 习:http://files.cnblogs.com/Imageshop/O%281%29%E6%9C%80%E5%A4%A7%E5%80%BC %E6%9C%80%E5%B0%8F%E5%80%BC%E7%AE%97%E6%B3%95.pdf
这篇论文写了 12页这么长,没用的太多。实现该算法确实提升了最小值滤波的速度。不过论文中给的代码好扯淡呀,用队列完成,进站出站就耗掉好长时间了。
图像大小:width=500,height=376 块大小31 运行快了好多,仅仅用了7个毫秒。如果程序写的更灵巧,可能速度还会提高不少,希望大家批评指导,谢谢。
图片
数组实现(论文提到的):
void getMin(unsigned char* data,unsigned char* output,int size,int r)
{
    int minIndex=0;
    int block=(r<<1)+1;
    int min=*data;
    for(int i=1;i<block;i++)
    {
        if(min>=*(data+i))
        {
            min=*(data+i);
            minIndex=i;
        }
    }
    output[r]=data[minIndex];
    for (int j=r+1;j<size-r;j++)
    {
       
        if (minIndex>=j-r)
        {
            int temp=(r<<1)+j-r;
            if(data[minIndex]>=data[temp])
                minIndex=temp;
        }
        else
        {
            minIndex=j-r;
            int min=data[j-r];
            for (int i=j-r+1;i<block+j-r;i++)
            {
                if(min>=data[i])
                {
                    min=data[i];
                    minIndex=i;
                }
            }
        }
        output[j]=data[minIndex];
    }
}

对于矩阵的实现:
void minFilter2(unsigned char* minData,unsigned char* outputData,int width,int height,int r)
{
    int block=(r<<1)+1;
    unsigned char* tempData=(unsigned char*)calloc(height,sizeof(unsigned char));
    unsigned char* tempData2=(unsigned char*)calloc(height,sizeof(unsigned char));
    int minIndex=0;
    int min=0;
    //求行的最小值
    for (int i=0;i<height;i++)
    {
        unsigned char* data_ptr=minData+i*width;
        unsigned char* output_ptr=outputData+i*width;
        getMin(data_ptr,output_ptr,width,r);
        //在边缘复制minData值
        for (int j=0;j<r;j++)
        {
            output_ptr[j]=data_ptr[j];
            output_ptr[width-j-1]=data_ptr[width-j-1];
        }
    }
    //求列最小值
    //for (int j=0;j<width;j++)
    //{
    //    for (int i=0;i<height;i++)
    //    {
    //        *(tempData+i)=*(outputData+i*width+j);
    //    }
    //    getMin(tempData,tempData2,height,r);
    //    for (int i=r;i<height-r;i++)
    //    {
    //        *(outputData+i*width+j)=*(tempData2+i);
    //    }
    //}
    //free(tempData2);
    //求列最小值
    for (int j=0;j<width;j++)
    {
        min=outputData[j];
        minIndex=0;
        for (int i=1;i<block;i++)
        {
            unsigned char* output_ptr=outputData+i*width;
            if(min>=output_ptr[j])
            {
                min=output_ptr[j];
                minIndex=i;
            }
        }
        *(tempData+r)=min;
        for (int i=r+1;i<height-r;i++)
        {
            if(minIndex>=i-r)
            {
                unsigned char* output_ptr2=outputData+(i+r)*width;
                if(min>=output_ptr2[j])
                {
                    min=output_ptr2[j];
                    minIndex=i+r;
                }
            }
            else
            {
                unsigned char* output_ptr1=outputData+(i-r)*width;
                minIndex=i-r;
                min=output_ptr1[j];
                for (int k=i-r+1;k<block+i-r;k++)
                {
                    unsigned char* output_ptr3=outputData+k*width;
                    if(min>=output_ptr3[j])
                    {
                        min=output_ptr3[j];
                        minIndex=k;
                    }
                }
            }
            *(tempData+i)=min;
        }
        for (int i=r;i<height-r;i++)
        {
            *(outputData+i*width+j)=*(tempData+i);
        }
    }
    free(tempData);
}