opencv将坐标点按逆时针顺序存放
在做项目的时候有时需要对轮廓点按照顺时针或者逆时针存储,假设坐标点保存的数据类型是vector<Point>
,现在将其按照逆时针的顺序存放,废话不多说,直接上函数。
#include<iostream>
#include <opencv2\>
using namespace cv;
using namespace std;
//若点a大于点b,即点a在点b顺时针方向,返回false,否则返回true
bool PointCmp(Point a, Point b, Point center)
{
if (a.x >= 0 && b.x < 0)
return false;
if (a.x == 0 && b.x == 0)
return a.y < b.y;
int det = ((a.x - center.x) * (b.y - center.y) - (b.x - center.x) * (a.y - center.y));
if (det < 0)
return false;
if (det > 0)
return true;
double d1 = (a.x - center.x) * (a.x - center.x) + (a.y - center.y) * (a.y - center.y);
double d2 = (b.x - center.x) * (b.x - center.y) + (b.y - center.y) * (b.y - center.y);
return d1 < d2;
}
void ClockwiseSortPoints(vector<Point> &vPoints)
{
//计算重心
Point center;
double X = 0, Y = 0;
for (int i = 0; i < vPoints.size(); i++)
{
X += vPoints[i].x;
Y += vPoints[i].y;
}
center.x = (int)X / vPoints.size();
center.y = (int)Y / vPoints.size();
//冒泡排序
for (int i = 0; i < vPoints.size() - 1; i++)
{
for (int j = 0; j < vPoints.size() - i - 1; j++)
{
if (PointCmp(vPoints[j], vPoints[j + 1], center))
{
Point tmp = vPoints[j];
vPoints[j] = vPoints[j + 1];
vPoints[j + 1] = tmp;
}
}
}
}
vector<Point> findBiggestContour(Mat binary_image)
{
vector<vector<cv::Point>> contours;
vector<Vec4i> hierarchy;
int largest_area = 0;
int largest_contour_index = 0;
findContours(binary_image, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
for (int i = 0; i < contours.size(); i++) // iterate through each contour.
{
double a = contourArea(contours[i], false); // Find the area of contour
if (a > largest_area) {
largest_area = a;
largest_contour_index = i; //Store the index of largest contour
}
}
return contours[largest_contour_index];
}
int main()
{
Mat img = imread("", 0);
threshold(img, img, 127, 255, CV_THRESH_BINARY);
vector<Point> bigestContour;
bigestContour = findBiggestContour(img);//提取最大轮廓
ClockwiseSortPoints(bigestContour);
for(int i = 0; i < bigestContour.size(); i++)
{
cout<<"第"<<i<<"个轮廓点坐标:"<<bigestContour[i].x,bigestContour[i].y<<endl;
}
return 0;
}
这里说明一下,其实轮廓本身已经是逆时针方向了,因为使用了宏CV_CHAIN_APPROX_NONE,但如果不使用这个宏,就有必要对轮廓排序了,除了对轮廓点可以采用此方法排序外,还可以对凸多边形点进行排序,这样在项目中可以有效的处理我们的数据,平时写博客少,有问题可以沟通,qq385105501。