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
图像大小: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);
}