Fast filtering of image processing

Fast median filter

In median filtering, it is necessary to calculate the median value of each small histogram. If a new histogram is calculated every time, it will be very troublesome, but every time the pixel is shifted by one unit to the right, the histogram actually only changes the most. In the left column and the rightmost column, the rest of the data can continue to be used, and the median value will not change too much. This method avoids repeated visits and repeated operations.
code show as below:

int calMidValue(int hist[], int midLocation)
{
    
    
	int sum = 0;
	for (int i = 0; i < 256; ++i)
	{
    
    
		sum += hist[i];
		if (sum >= midLocation)
			return i;
	}
	return 255;
}
void midFilt(BYTE *pImg, int width, int height,int windowLength)
{
    
    
	BYTE *pSrc=pImg;
	int hist[256];
	int edge = (windowLength - 1) >> 1;//未处理边界大小
	int windowSize = windowLength * windowLength;//矩形窗大小
	int midLocation = (windowSize >> 1) + 1;//中值的位置
	int realWidth = width - edge, realHeight = height - edge;//实际处理的宽高

	for (int i = edge; i < realWidth; i++)
		for (int j = edge; j < realHeight; j++) 
		{
    
    
			if (j == edge)
			{
    
    
				memset(hist, 0, 256 * sizeof(int));
				for(int h=i-edge;h<=i+edge;h++)
					for (int w = j - edge; w <= j + edge; w++) {
    
    
						BYTE value = pSrc[h*width + w];
						hist[value]++;
					}
			}
			else
			{
    
    
				int left = j - edge - 1, right = j + edge;
				for (int y = i - edge; y <= i + edge; y++)
				{
    
    
					int l = y * width + left, r = y * width + right;
					hist[pSrc[l]]--;
					hist[pSrc[r]]++;
				}
			}
			pSrc[i*width + j] = calMidValue(hist, midLocation);
		}
	return;
}

3*3 template filtering result:
Insert picture description hereInsert picture description here

Fast mean filter

Fast mean filtering can use a method similar to fast median filtering. When moving the boundary, only focus on the changed area, reducing the data access
code as follows:

int calAverValue(int hist[],int windowSize)
{
    
    
	int sum = 0;
	for (int i = 0; i < 256; ++i)
	{
    
    
		sum += hist[i] * i;
	}
	return (sum / windowSize);
}
void averFilt1(BYTE *pImg, int width, int height, int windowLength)
{
    
    
	BYTE *pSrc = pImg;
	int hist[256];
	int edge = (windowLength - 1) >> 1;//未处理边界大小
	int windowSize = windowLength * windowLength;//矩形窗大小
	int realWidth = width - edge, realHeight = height - edge;//实际处理的宽高

	for (int i = edge; i < realWidth; i++)
		for (int j = edge; j < realHeight; j++)
		{
    
    
			if (j == edge)
			{
    
    
				memset(hist, 0, 256 * sizeof(int));
				for (int h = i - edge; h <= i + edge; h++)
					for (int w = j - edge; w <= j + edge; w++) {
    
    
						BYTE value = pSrc[h*width + w];
						hist[value]++;
					}
			}
			else
			{
    
    
				int left = j - edge - 1, right = j + edge;
				for (int y = i - edge; y <= i + edge; y++)
				{
    
    
					int l = y * width + left, r = y * width + right;
					hist[pSrc[l]]--;
					hist[pSrc[r]]++;
				}
			}
			pSrc[i*width + j] = calAverValue(hist, windowSize);
		}
}


Fast integral graph filtering

`
Another method is based on the integral graph algorithm. The image integral graph refers to the value of the point on the integral graph = the sum of all the point and the pixel value at the upper left of the point, that is, s(x,y)=g( x,y)+s(x-1,y)+s(x,y-1)-s(x-1,y-1) This method can quickly calculate the sum of pixel values ​​in a certain area, that is, sum= s(x,y)-s(xm,y)-s(x,yn)+s(xm,yn) and then divided by the window size, it is the mean value.
code show as below:

void averFilt2(BYTE *pImg, int width, int height, int windowLength,BYTE *pDst)
{
    
    
	int windowSize = windowLength * windowLength;
	int edge = (windowLength - 1) >> 2;
	int realWidth = width - edge, realHeight = height - edge;//实际处理的宽高
	for (int i = 0; i < width*height; i++)
	{
    
    
		pDst[i] = pImg[i];
	}
		for (int i = 0; i < height; i++)
			for (int j = 0; j < height; j++)
		
		{
    
    
				pDst[i*width + j] = pDst[i*width + j - 1] + pDst[(i - 1)*width + j] - pDst[(i - 1)*width + j - 1] + pImg[i*width + j];
		}
	
		for (int i = 0; i < realWidth; i++)
			for (int j = 0; j < realHeight; j++)
			{
    
    
				pDst[i*width + j] = (pDst[(i + edge)*width + j + edge] - pDst[(i - edge)*width + j + edge] - pDst[(i + edge)*width + j - edge] + pDst[(i - edge)*width + j - edge]) / windowSize;
			}
	return;
}

Filtering result:

Insert picture description hereInsert picture description here

Guess you like

Origin blog.csdn.net/qq_36587495/article/details/108164741