double dist = sqrt ( pow((x1-x2), 2) + pow((y1-y2), 2) );//两点距离公式
std::vector<cv::Point2f> corners;//所有坐标值得集合
首先谢谢高手的回答。比如:
vector<cv::Point2f> vec;
vec.push_back(cv::Point2f(0,0)); //1
vec.push_back(cv::Point2f(1,0)); //2
vec.push_back(cv::Point2f(0,0)); //3
vec.push_back(cv::Point2f(98,99)); //4
vec.push_back(cv::Point2f(100,100));//5
找出来任何两个点的距离小于50的点,然后取这个些点的中心坐标,比如上面所有点中1,2,3任意两个之间的距离小于50就取中间坐标为(0.33,0)。4,5小于50取中间坐标为(99,99.5)
最终我想得到的集合是两个点:(0.33,0) (99,99.5).
(0.0),(1.0),(0.0)三个点的中心坐标怎么求不用写了吧?
麻烦看下这个代码可以吗?
void erase(vector<cv::Point2f> &v) { std::vector<cv::Point2f> result,filter,tempOut=v; for(int i=0;i<tempOut.size();i++) { for(int j=i+1;j<tempOut.size();j++) { cv::Point2f vo=tempOut[i],vi=tempOut[j]; double x1=(vo).x,x2=(vi).x,y1=(vo).y,y2=(vi).y; double dist = sqrt ( pow((x1-x2), 2) + pow((y1-y2), 2) ); if (dist <= 50) { filter.push_back(vi); tempOut.erase(tempOut.begin()+j); j--; } } // filter.push_back(tempOut[i]); int count=filter.size(); double argX=0,avgY=0; for(int i=0;i<count;i++) { argX+=filter[i].x; avgY+=filter[i].y; } result.push_back(cv::Point2f(argX/count,avgY/count)); filter.clear(); }
汗~,没看懂需求
哪里不清楚呢?
@KissFu: 需求算是看懂了,很简单的一个需求,但对你说的这个结构std::vector<cv::Point2f>不熟悉,你上面的方法中循环可能存在问题,即i和j的循环次数我看好像不对吧? 如果求中间点,这样求(伪代码),写得也比较凌乱,看不懂就算了,我这里没有vc环境:
public class point
{
public point(double x,double y)
{
X=x;Y=y;
}
double X,
double Y
}
point[]={new point(0,0),new point(1,0),new point(0,0),...};
for(int i = 0 ;i<sizeof(point)/sizeof(point[0]);i++)
{
for(int j = 0 ;j<sizeof(point)/sizeof(point[0]);j++)
{
//自己不能和自己比较
if(i==j)
continue;
//两个坐标重复
if(point[i].X==point[j].X && point[i].Y==point[j].Y))
{
//将此坐标加入一个新集合,正在遍历的集合是不能删除的。
continue;
}
if((sqrt(pow((point[i].X-point[j].X), 2) + pow((point[i].Y-point[j].Y), 2) )<50)
{
int x= (point[i].X+point[j].X)/2;
int y= (point[i].Y-point[j].Y)/2;
point c = new point(x,y);
//这是中间点坐标
}
}
}
foreach(int i =0;i<deleteList.count;i++)
{
//从集合中删除刚才找到的集合
pointList.remove(deleteList[i]);
}
@沧海一杰: 非常感谢您的回答。
主要还是要对c++标准库里面的向量std::vector<cv::Point2f>的理解。
第一:自己不能和自己比较、两个坐标重复这两个条件可以用另外一个嵌套循环解决的。
外层循环到i=0的时候,内层j=i+1=1然后接着循环。
第二:就是删除正在循环的集合的某个元素,vector删除某个元素的时候,当前索引会指向下一个值,size-1。我这里有点投机取巧,因为只是在内层删除,而且还是删除当前索引之后的元素,所以要考虑内层的索引指向的值,删除之后就j--就可以指向下一个值啦。
第三:求中间点坐标,要考虑如果是多个点求中间值!!比如,外层i=0,内层j=i+1=1,j=i+2=2,j=i+3=3。内层三个点和外层一个点都<50,然后删除内层三个点,外层一个点不删除,因为内层循环完后,四个点求中间点坐标,把中间点放入另外一个集合里面。外层继续循环。
我不知这样说您是否能理解?我这样是否存在隐患?再次表示感谢。
好像很简单的样子,除了不熟这个集合是怎么构成的,C++不熟。
我猜集合不是矩阵就是数组形式,那就好办,循环取点坐标(去掉重复的),计算dist,判断<50,再产生新坐标
我c++也不是太熟悉,所以我想要个代码,遍历集合的期间,还有删减其中的重复。麻烦
@KissFu:
std::vector<std::vector<CvPoint>> ptAll; for(int jj = 0;jj<ptAll.size();jj++) { for(int ii =0;ii<ptAll[jj].size();ii++) { ptAll[jj][ii]....; } }
@chous: std::vector<std::vector<CvPoint>>这个是集合套一个集合。我的事一个集合。std::vector<cv::Point2f> corners;
@KissFu: corners[][]这样不能操作吗?