0

I have converted a python code to segment hough lines using OpenCV k-means. I am trying to find the intersection of hough lines to get the corners of a quadrilateral. If I find intersection directly without segmenting I get clusters of points so I am using Kmeans so that, that cluster problem doesn't occur. While converting it to c++ I am getting some errors(error picture posted below). I have used the map library in c++ in place of defaultdict in python's collections library. Is this the right way to use map, how to append segmented at a particular position and how should convert map to array or vector to return it. I found this Python Code here:

def segment_by_angle_kmeans(lines, k=3, **kwargs):
    default_criteria_type = cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER
    criteria = kwargs.get('criteria', (default_criteria_type, 10, 1.0))
    flags = kwargs.get('flags', cv2.KMEANS_RANDOM_CENTERS)
    attempts = kwargs.get('attempts', 10)

    angles = np.array([line[0][1] for line in lines])
    pts = np.array([[np.cos(2 * angle), np.sin(2 * angle)]
                    for angle in angles], dtype=np.float32)
    labels, centers = cv2.kmeans(pts, k, None, criteria, attempts, flags)[1:]
    labels = labels.reshape(-1)

    segmented = defaultdict(list)
    for i, line in zip(range(len(lines)), lines):
        segmented[labels[i]].append(line)

    segmented = list(segmented.values())
    return segmented

C++ code i have converted:

vector<Vec2f> segment(vector<Vec2f> lines, int k = 3) {
    Mat labels;
    vector<Vec2f> angles;
    vector<Point2f> centers;
    for (int i = 0; i < lines.size(); i++) {
        float angle = lines[i][1];
        angles.push_back(angle);
    }
    Mat points(angles.size, 2, CV_32F);
    for (int j = 0; j < angles.size(); j++) {
        float angle = 2 * angles[j][1];
        float c = cos(angle);
        float s = sin(angle);
        points.at<float>(j, 0) = c;
        points.at<float>(j, 1) = s;
    }
    TermCriteria term(TermCriteria::EPS + TermCriteria::MAX_ITER, 10, 1.0);
    kmeans(points, k, labels, term, 10, KMEANS_RANDOM_CENTERS, centers);
    labels = labels.reshape(-1);
    map<Mat, vector<Vec2f>> segmented;

    for (size_t i = 0; i < lines.size(); ++i)
    {
        segmented[labels[i]].push_back(lines[i]);
    }

    return segmented;}

Errors: Error (active) E0349 no operator "[]" matches these operands

Error (active) E0312 no suitable user-defined conversion from "std::map>, std::less, std::allocator>>>>" to "std::vector>"

errors

Edit:

map<int,vector<Vec2f>>::iterator itr = segmented.begin();
vector<Vec2f> segments;
int i = 0;
while (itr != segmented.end())
{   
    segments.push_back(itr->second);

    itr++;
    i++;
}

I have edited the code and converted the map into vector but one error occured

"Error (active) E0304 no instance of overloaded function "std::vector<_Ty, _Alloc>::push_back [with _Ty=cv::Vec2f, _Alloc=std::allocator]" matches the argument list"

goodboy
  • 41
  • 3
  • 1
    Labels are integers. Generic `Mat` is a bit of an overkill, a simple `std::vector` would do. | I expect `segmented` should map labels to lines. Therefore it ought to be `map>` -- the key being a `Mat` doesn't make sense. | Finally, the functions return type is `vector`, but you're trying to return `segmented`, which is a map... – Dan Mašek Nov 21 '19 at 12:56
  • @DanMašek Thank you I have edited the code accordingly that worked. But unable to convert map into vector array. Please check the edit part. – goodboy Nov 26 '19 at 07:24

0 Answers0