opencv实现自己的中值滤波

在读了中值滤波这节内容时突然想到是否可以自己实现中值滤波,于是用c++写了一下中值滤波,主要看的是中值滤波的思想。
#include<iostream>
#include<opencv2\opencv.hpp>
#include<opencv2\core\core.hpp>

/****************************************
pArray[]-需要提取中值的数组
length-数组长度
功能:排序,获取中值
****************************************/
int GetMedianValue(int pArray[], int length)
{
	int nMedianValue=0;
	//插入排序
	for (auto j = 1; j < length; j++)
	{
		int temp = pArray[j];
		int k;
		for (k = j; k>0 && pArray[k - 1] >temp; k--)
		{
			pArray[k] = pArray[k - 1];
		}
		pArray[k] =temp;
	}
	//计算中值
	//奇数个元素,返回中间元素
	if ((length & 1) > 0)
	{
		nMedianValue = pArray[(length + 1) / 2];
	}
	//偶数个元素,返回中间两个元素的差值
	else
	{
		nMedianValue = (pArray[length / 2] + pArray[length / 2 + 1]) / 2;
	}
	return nMedianValue;
}

/****************************************
srcImg-输入图像(灰度图像)
nTempH-模板的高度
nTempW-模板的宽度
nTempMY与nTempMX-中心的坐标
功能:中值滤波
****************************************/
void medianBlur(const cv::Mat srcImg, cv::Mat& resultImg, int nTempH, int nTempW, int nTempMY, int nTempMX)
{
	if (srcImg.empty())
	{
		return;
	}
	srcImg.copyTo(resultImg);
	//邻域像素数组
	int* pArray = new int[nTempH*nTempW];

	int nValue;
	//扫面图像,进行中值滤波
	for (int i = nTempMY; i < srcImg.rows - (nTempH - nTempMY) + 1; i++)
	{
		for (int j = nTempMX; j < resultImg.cols - (nTempW - nTempMX) + 1; j++)
		{
			for (int k = 0; k < nTempH; k++)
			{
				for (int l = 0; l < nTempW; l++)
				{
					pArray[k*nTempW + l] = srcImg.at<uchar>(i + k - nTempMY, j + l - nTempMX);
				}
			}
			//中值排序获取中值
			nValue = GetMedianValue(pArray, nTempH*nTempW);
			resultImg.at<uchar>(i, j) = nValue;
		}
	}
	delete[]pArray;
}
int main()
{
	cv::Mat testImg = cv::imread("test1.jpg");
	cv::Mat grayImg;
	cv::cvtColor(testImg, grayImg, CV_BGR2GRAY);
	cv::imshow("原始图像", grayImg);
	cv::Mat resultImg;
	medianBlur(grayImg, resultImg, 5, 5, 2, 2);
	cv::imshow("my中值滤波", resultImg);
	cv::waitKey(0);
	return 0;
}

原图:


中值滤波后的图像:


  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值