代码说明:
在当前点的搜索半径为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;
}
}