C++实现基于邻域剔除二维数据离群点

代码说明:

在当前点的搜索半径为radius的范围内,如果相邻点个数少于k个,则该点为离群点,进行剔除;

#include <iostream>
#include <opencv2\opencv.hpp>

using namespace std;
using namespace cv;

struct pointLoc
{
	float x;
	float y;

};

//设置在当前点的搜索半径为radius的范围内,如果相邻点个数少于k个,则该点为离群点
void removeOutlier(vector<pointLoc> inData, int radius, int k, vector<pointLoc> &outData)
{
	outData.clear();

	int cnt = 0;
	int n = 0;
	for (int m = 0; m < inData.size(); m++)
	{
		cnt = 0;
		for (n = 0; n < inData.size(); n++)
		{
			if (n == m)
				continue;

			if (sqrt(pow(inData[m].x - inData[n].x,2) + pow(inData[m].y - inData[n].y,2)) <= radius)
			{
				cnt++;
				if (cnt >= k)
				{
					outData.push_back(inData[m]);
					n = 0;
					break;
				}
			}
		}
	}
}

//创建随机数据
void randData(int num, vector<pointLoc> &randomData)
{
	randomData.clear();
	pointLoc p;
	srand((unsigned)time(NULL));
	for (int n = 0; n < num; n++)
	{
		p.x = (int)100 * rand() / (RAND_MAX + 1);
		p.y = (int)100 * rand() / (RAND_MAX + 1);
		randomData.push_back(p);
	}
}

int main()
{
	cv::Mat xx = cv::Mat::zeros(100, 100, CV_8UC3);

	vector<pointLoc> randomData;
	randData(100, randomData);

	for (int m = 0; m < randomData.size(); m++)
	{
		xx.at<Vec3b>(randomData[m].y, randomData[m].x)[0] = 0;
		xx.at<Vec3b>(randomData[m].y, randomData[m].x)[1] = 0;
		xx.at<Vec3b>(randomData[m].y, randomData[m].x)[2] = 255;
	}

	vector<pointLoc> outData;
	removeOutlier(randomData, 10, 3, outData);

	for (int m = 0; m < outData.size(); m++)
	{
		xx.at<Vec3b>(outData[m].y, outData[m].x)[0] = 255;
		xx.at<Vec3b>(outData[m].y, outData[m].x)[1] = 0;
		xx.at<Vec3b>(outData[m].y, outData[m].x)[2] = 0;
	}
}

猜你喜欢

转载自blog.csdn.net/zfjBIT/article/details/93488130
今日推荐