opencv将坐标点按逆时针顺序存放

opencv将坐标点按逆时针顺序存放

在做项目的时候有时需要对轮廓点按照顺时针或者逆时针存储,假设坐标点保存的数据类型是vector<Point>,现在将其按照逆时针的顺序存放,废话不多说,直接上函数。

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

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("25.png", 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。

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值