这个filter是用来平滑图像用的,简单来说是对一幅(width * height)大小的图像按下述方法进行平滑化,以达到除去图像中噪声的目的。
首先把输入图像中每个像素点和该像素点四周的8个像素点作为一组来看,将这9个像素点的灰度进行排序后取最中间的那个灰度值作为这个像素点平滑化后的灰度值。
参数corrupted用来指向一幅有噪声的图像空间,参数smooth用来指向平滑化处理后的图像空间,width和height分别为图像的宽和高。
那么做main函数就应该知道怎么写了才对。
如果你能读入一幅图像并把图像里的各像素点保存到一个unsigned char数组里是最好的,不能的话可以自己虚构一幅图像来尝试滤波。
比如我们有下述5*5大小的图像(灰度范围0-255):
static unsigned char image[] = {
50, 50, 50, 50, 50,
50, 52, 48, 50, 50,
50, 50, 50, 0, 50,
50, 48, 53, 50, 50,
50, 50, 50, 50, 50,
}
本来这幅图像应该是全灰度为50的图像,但是现在某些像素点混入了噪声(非50的像素点即为噪声)
把它送入medianFilter后即可得到平滑化后的全灰度为50的图像。
参考代码:
#include <memory.h>#include <stdio.h>
static unsigned char image[] = {
50, 50, 50, 50, 50,
50, 52, 48, 50, 50,
50, 50, 50, 0, 50,
50, 48, 53, 50, 50,
50, 50, 50, 50, 50,
}
#define WIDTH 5
#define HEIGHT 5
void medianFilter (unsigned char* corrupted, unsigned char* smooth, int width, int height)
{
memcpy ( smooth, corrupted, width*height*sizeof(unsigned char) )
for (int j=1j<height-1j++)
{
for (int i=1i<width-1i++)
{
int k = 0
unsigned char window[9]
for (int jj = j - 1 jj < j + 2 ++jj)
for (int ii = i - 1 ii < i + 2 ++ii)
window[k++] = corrupted[jj * width + ii]
// Order elements (only half of them)
for (int m = 0 m < 5 ++m)
{
int min = m
for (int n = m + 1 n < 9 ++n)
if (window[n] < window[min])
min = n
// Put found minimum element in its place
unsigned char temp = window[m]
window[m] = window[min]
window[min] = temp
}
smooth[ j*width+i ] = window[4]
}
}
}
int main()
{
unsigned char output[WIDTH * HEIGHT]
int i, j
medianFilter(image, output, WIDTH, HEIGHT)
for(i=0 i<HEIGHT i++)
{
for(j=0 j<WIDTH j++)
{
printf("%d\t", output[i*WIDTH+j])
}
printf("\n")
}
return 0
}
MID:MOV A, R0
CLR C
SUBB A, R1
JNC NEXT1
MOV A, R0
XCH A, R1
MOV R0, A
NEXT1:
MOV A, R1
CLR C
SUBB A, R2
JNC NEXT2
MOV A, R1
XCH A, R2
MOV R1, A
NEXT2:
MOV A, R0
CLR C
SUBB A, R1
JNC NEXT3
MOV A, R0
XCH A, R1
MOV R0, A
NEXT3:
RET
END
执行一遍上述程序,R1 内容,即为中值。
unsigned char WINAPI GetMedianNum(unsigned char * bArray, int iFilterH,int iFilterW){
/* unsigned char m = mid(
mid(bArray[0],bArray[1],bArray[2]),
mid(bArray[3],bArray[4],bArray[5]),
mid(bArray[6],bArray[7],bArray[8]))
return m*/
// 循环变量
int i
int j
int k
// 中间变量
unsigned char bTemp
int iFilterLen=iFilterH*iFilterW
float average=0//用于均值加速
//求均值
for (i=0i<iFilterLeni++)
{
average+=bArray[i]
}
average=average/iFilterLen
unsigned char pixel_mid
pixel_mid=bArray[(iFilterH-1)/2*iFilterW+(iFilterW-1)/2]//滤波窗口中心的取中值前的像素值
if (abs(average-pixel_mid)>10) //均值加速,其中“10”为原中值和均值之差,根据你的实际情况自行设置大小
//if(1) //不用均值加速时选此
{
//超快速中值法(本质就是伪中值法)
//行排列
if (0)
{
for (k = 0k < iFilterHk ++)
{
for (j = 0j < iFilterH-1j ++)
{
for (i = 0i < iFilterW-1-ji++)
{
number++
if (bArray[i+iFilterH*k] >bArray[i+iFilterH*k+1])
{ // 互换
bTemp = bArray[i+iFilterH*k]
bArray[i+iFilterH*k] = bArray[i+iFilterH*k+1]
bArray[i+iFilterH*k+1] = bTemp
}
}
还有什么疑问,把邮箱发给我。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)