二维图像坐标排序

二维坐标点位排序

背景:
对vector中乱序的坐标进行排序
目的:
对坐标进行排序,先横向,再纵向,

编译器:
VS2012 + Win32
步骤:
使用vector来装数据,个人习惯
1、首先导入vector

#include <vector>
using namespace std;

2、创建排序函数

//对y方向上的点位进行排序
bool SetSortRule(const Point p1,const Point p2)
{
	if(p1.x < p2.x)
		return true;
	else
		return false;
}
//对x方向上的点位进行排序
bool SetSortRule1(const vector<Point> p1,const vector<Point> p2)
{
	if(p1.at(0).y < p2.at(0).y)
		return true;
	else
		return false;
}

3、逻辑部分

vector<Point> posP;
posP.push_back(Point(4,2));
posP.push_back(Point(3,2));
posP.push_back(Point(2,2));
posP.push_back(Point(1,2));
posP.push_back(Point(4,1));
posP.push_back(Point(3,1));
posP.push_back(Point(2,1));
posP.push_back(Point(1,1));
posP.push_back(Point(2,4));
posP.push_back(Point(1,4));
posP.push_back(Point(3,3));
posP.push_back(Point(1,3));
posP.push_back(Point(4,3));
posP.push_back(Point(4,4));
posP.push_back(Point(3,4));
posP.push_back(Point(2,3));
我这边是手动push数据,也可以用for循环push
vector<vector<Point>> point_all;
vector<Point> point_row;
point_all.clear();
point_row.clear();
int IErr = 0; //同一行y坐标允许的误差值
for(unsigned int i = 0; i < posP.size();i++)
{
	for(unsigned int j =i+1;j<posP.size();j++)
	{
		if(abs( posP.at(i).y - posP.at(j).y)<= IErr )
		{
			point_row.push_back(posP.at(j));
			posP.erase(posP.begin()+j);
			j--;
		}
	}
	point_row.push_back(posP.at(i));//最后将比较的点放入Vector
	cout << "size:" << point_row.size() << endl;
	sort(point_row.begin(),point_row.end(),SetSortRule);//对同一行的点位进行排序
	for(unsigned int k=0; k < point_row.size();k++)
		cout << point_row.at(k)<< endl;
	//将同一行的点位放入vector
	point_all.push_back(point_row);
	point_row.clear();	//清空,准备下一次排序
}
		由于图像中同一行 实际的像素坐标在Y方向上存在一些误差,所以在误差范围内都认为是同一行。
	即满足 abs(posP.at(i).y - posP.at(j).y) <=iErr 这个条件的坐标,都认为是同一行。
		每次找到对应的坐标,都将坐标丢进 point_row,并将次坐标从posP中剔除,直到第二个for循环遍历完成,
	然后将被比较的坐标丢进point_row,这样代表这一行Y方向相近的坐标,都被获取。
		接下来对point_row这一行的坐标进行排序。
		然后将排序后点vector丢进point_all中,将point_row清空准备下一次排序

对point_all进行排序

cout << "before:" << endl;
for(unsigned int i=0; i < point_all.size();i++)
{
	for(unsigned int j=0; j < point_all.at(i).size();j++)
	{
		cout << point_all.at(i).at(j)<<endl;
	}
}
cout << "after:" << endl;
sort(point_all.begin(),point_all.end(),SetSortRule1);

for(unsigned int i=0; i < point_all.size();i++)
{
	for(unsigned int j=0; j < point_all.at(i).size();j++)
	{
		cout << point_all.at(i).at(j)<<endl;
	}
}
system("pause");
return 0;
}

4、结果
在这里插入图片描述
posP 中初始坐标顺序

在这里插入图片描述
对每一行的坐标进行X方向上的排序
在这里插入图片描述
对每一行的坐标进行Y方向上的排序。
如有问题,请指示出来,我会及时改正,谢谢。
附:Mat图实际测试效果:
在这里插入图片描述
排序之前:
在这里插入图片描述
排序之后:
在这里插入图片描述
Code:

#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <math.h>
#include <Windows.h>
#include <opencv2\opencv.hpp>
#include <highgui.hpp>
#include <imgproc.hpp>
#include <iostream>

#include <vector>
using namespace std;
using namespace cv;

//对y方向上的点位进行排序
bool SetSortRule(const Point p1,const Point p2)
{
	if(p1.x < p2.x)
		return true;
	else
		return false;
}
//对x方向上的点位进行排序
bool SetSortRule1(const vector<Point> p1,const vector<Point> p2)
{
	if(p1.at(0).y < p2.at(0).y)
		return true;
	else
		return false;
}
int _tmain(int argc, _TCHAR* argv[])
{
	Mat mSrc,mGray,mThresh,mDst,mDst2;
	mSrc= imread("Test.jpg",-1);
	if(mSrc.channels() ==3)
		cvtColor(mSrc,mGray,CV_BGR2GRAY);
	else
		mGray = mSrc.clone();
	mDst = mSrc.clone();
	if(mDst.channels() ==1)
		cvtColor(mDst,mDst,CV_GRAY2BGR);
	mDst2 = mDst.clone();
	threshold(mGray,mThresh,50,255,THRESH_BINARY);
	vector<Point> posP;
	vector<vector<Point> > contours;
	findContours(mThresh.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
	cout << contours.size() << endl;
	for(unsigned int i =0;i< contours.size();i++)
	{
		Rect R =boundingRect(contours[i]);
		if(R.width * R.height > 50)
		{
			Point p;
			p.x = R.x;
			p.y = R.y;
			posP.push_back(p);
			char text[20];
			sprintf_s(text,"%d",i);
			putText(mDst,text,p,cv::FONT_HERSHEY_SIMPLEX,1,cv::Scalar(0, 0, 255), 2, 8, 0);
		}
	}
	imwrite("mDst1.jpg",mDst);
	cout<< posP.size() << endl;
	//输出
	for(unsigned int i=0; i< posP.size();i++)
	{
		cout <<"posP:" <<posP.at(i) << endl;
	}

	vector<vector<Point>> point_all;
	vector<Point> point_row;
	point_all.clear();
	point_row.clear();
	int IErr = 50; //同一行y坐标允许的误差值
	for(unsigned int i = 0; i < posP.size();i++)
	{
		for(unsigned int j =i+1;j<posP.size();j++)
		{
			if(abs( posP.at(i).y - posP.at(j).y)<= IErr )
			{
				point_row.push_back(posP.at(j));
				posP.erase(posP.begin()+j);
				j--;
			}
		}
		point_row.push_back(posP.at(i));//最后将比较的点放入Vector
		cout << "size:" << point_row.size() << endl;
		sort(point_row.begin(),point_row.end(),SetSortRule);//对同一行的点位进行排序
		for(unsigned int k=0; k < point_row.size();k++)
			cout << point_row.at(k)<< endl;
		//将同一行的点位放入vector
		point_all.push_back(point_row);
		point_row.clear();	//清空,准备下一次排序
	}
	cout << "before:" << endl;
	for(unsigned int i=0; i < point_all.size();i++)
	{
		for(unsigned int j=0; j < point_all.at(i).size();j++)
		{
			cout << point_all.at(i).at(j)<<endl;
		}
	}
	cout << "after:" << endl;
	sort(point_all.begin(),point_all.end(),SetSortRule1);
	for(unsigned int i=0; i < point_all.size();i++)
	{
		for(unsigned int j=0; j < point_all.at(i).size();j++)
		{
			cout << point_all.at(i).at(j)<<endl;

			char text[20];
			sprintf_s(text,"%d",(i*(point_all.at(i).size())+j));
			putText(mDst2,text,point_all.at(i).at(j),cv::FONT_HERSHEY_SIMPLEX,1,cv::Scalar(0, 0, 255), 2, 8, 0);
		}
	}
	imwrite("Dst2.jpg",mDst2);

	waitKey();
	system("pause");
	return 0;
}
  • 8
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值