利用OpenCV和C++查找轮廓点的坐标 我是新手使用OpenCV和C++,我已经处理了一张图片并提取了图片中的轮廓。然后我在一个新的黑色框架上绘制轮廓。具体来说,我用红色绘制轮廓。我想得到黑框中每个和所有红色像素的坐标,并将其存储在一个数组中。我需要这方面的帮助,代码是首选。提前谢谢

利用OpenCV和C++查找轮廓点的坐标 我是新手使用OpenCV和C++,我已经处理了一张图片并提取了图片中的轮廓。然后我在一个新的黑色框架上绘制轮廓。具体来说,我用红色绘制轮廓。我想得到黑框中每个和所有红色像素的坐标,并将其存储在一个数组中。我需要这方面的帮助,代码是首选。提前谢谢,c++,opencv,contour,C++,Opencv,Contour,这是我的密码: #include <iostream> #include <Windows.h> #include <sstream> #include <opencv2/opencv.hpp> #include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\imgproc.hpp>

这是我的密码:

#include <iostream>
#include <Windows.h>
#include <sstream>

#include <opencv2/opencv.hpp>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>

using namespace cv;
using namespace std;

void on_trackbar(int, void*);
void createTrackbars();
void toggle(int);

const int MAX_NUM_OBJECTS = 500;

const int FRAME_WIDTH = 900;
const int FRAME_HEIGHT = 600;

const int MIN_OBJECT_AREA = 20 * 20;
const int MAX_OBJECT_AREA = FRAME_HEIGHT*FRAME_WIDTH / 1.5;

Point middle;

int l_MIN = 30;
int l_MAX = 165;
int a_MIN = 139;
int a_MAX = 165;
int b_MIN = 136;
int b_MAX = 172;

int kerode = 2;
int kdilate = 8;

bool showchangedframe = true;

int main(int argc, char** argv)
{
    createTrackbars();
    on_trackbar(0, 0);

    int x, y;
    Mat frame, labframe, rangeframe;
    Mat newframe, newrf;
    int key;

    while ((key = waitKey(30)) != 27)
    {
        toggle(key);
        frame = imread(argv[1], 1);
        newframe = imread(argv[1], 1);
        dframe = imread(argv[1], 1);
        newframe = Scalar(0, 0, 0);
        dframe = Scalar(0, 0, 0);
        cvtColor(frame, labframe, COLOR_BGR2Lab);
        inRange(labframe, Scalar(l_MIN, a_MIN, b_MIN), Scalar(l_MAX, a_MAX, b_MAX), rangeframe);

        erode(rangeframe, rangeframe, getStructuringElement(MORPH_RECT, Size(kerode, kerode)));
        dilate(rangeframe, rangeframe, getStructuringElement(MORPH_RECT, Size(kdilate, kdilate)));

        newrf = rangeframe.clone();

        int largest_area = 0;
        int largest_contour_index = 0;
        vector<vector<Point> > contours;

        findContours(newrf, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);

        vector<Moments> mu(contours.size()); //get moments
        for (int i = 0; i < contours.size(); i++)
        {
            mu[i] = moments(contours[i], false);
        }

        vector<Point2f> mc(contours.size()); //get centers
        for (int i = 0; i < contours.size(); i++)
        {
            mc[i] = Point2f(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00);
        }

        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
            }
        }

        drawContours(newframe, contours, largest_contour_index, CV_RGB(255, 0, 0), 4);
        circle(newframe, mc[largest_contour_index], 5, CV_RGB(255, 255, 0), -1, 8, 0);

        imshow("Detected", newframe);

        if (showchangedframe)
            imshow("Camera", frame);
        else
            imshow("Camera", rangeframe);
    }
}

void on_trackbar(int, void*)
{
    if (kerode == 0)
        kerode = 1;
    if (kdilate == 0)
        kdilate = 1;
}

void createTrackbars()
{
    String trackbarWindowName = "TrackBars";
    namedWindow(trackbarWindowName, WINDOW_NORMAL);
    createTrackbar("l_MIN", trackbarWindowName, &l_MIN, l_MAX, on_trackbar);
    createTrackbar("l_MAX", trackbarWindowName, &l_MAX, l_MAX, on_trackbar);
    createTrackbar("a_MIN", trackbarWindowName, &a_MIN, a_MAX, on_trackbar);
    createTrackbar("a_MAX", trackbarWindowName, &a_MAX, a_MAX, on_trackbar);
    createTrackbar("b_MIN", trackbarWindowName, &b_MIN, b_MAX, on_trackbar);
    createTrackbar("b_MAX", trackbarWindowName, &b_MAX, b_MAX, on_trackbar);
    createTrackbar("Erosion", trackbarWindowName, &kerode, 31, on_trackbar);
    createTrackbar("Dilation", trackbarWindowName, &kdilate, 31, on_trackbar);
}

void toggle(int key)
{
    if (key == 'r')
        showchangedframe = !showchangedframe;
}
以下是输出:


将CV_CHAIN_APPROX_SIMPLE替换为CV_CHAIN_APPROX_NONE请参见文档,以获取findContours结果中的每个轮廓点

apörox_simple通过用起点和终点替换直线零件来减少轮廓点的数量。近似值“无”根本不会减少轮廓点的数量

这些要点是你的重点

vector<vector<Point> > contours
您可以通过以下方式访问它们:

for (size_t cC = 0; cC < contours.size(); ++cC)
    for(size_t cP =0; cP < contours[cC].size(); cP++)
    {
         Point currentContourPixel = contours[cC][cP];
         // do whatever you want
    }

将CV_CHAIN_APPROX_SIMPLE替换为CV_CHAIN_APPROX_NONE请参见文档,以获取findContours结果中的每个轮廓点

apörox_simple通过用起点和终点替换直线零件来减少轮廓点的数量。近似值“无”根本不会减少轮廓点的数量

这些要点是你的重点

vector<vector<Point> > contours
您可以通过以下方式访问它们:

for (size_t cC = 0; cC < contours.size(); ++cC)
    for(size_t cP =0; cP < contours[cC].size(); cP++)
    {
         Point currentContourPixel = contours[cC][cP];
         // do whatever you want
    }

向量等高线不是已经存储了坐标吗?@Zindarod:是的,但是只有简化版本,因为他使用了CV_CHAIN_APPROX_简单的参数哦,好的。由于他已经能够绘制轮廓,我认为存储的坐标就足够了。@Mika tq Mika,我已将其更改为CV_CHAIN_About_NONE,我可以知道访问坐标的代码吗?参见迭代所有轮廓并访问内环中单个轮廓的所有点的updared代码向量轮廓不已经存储坐标了吗?@Zindarod:是的,但只有简化版本,因为他使用了CV_CHAIN_APPROX_简单参数哦,好的。由于他已经能够绘制等高线,我认为存储的坐标就足够了。@Mika tq Mika,我已将其更改为CV_CHAIN_About_NONE,我可以知道访问坐标的代码吗?请参阅updared代码,该代码迭代所有等高线并访问内部循环中单个等高线的所有点