Merge HoughLines

Viewed 1890

I stuck at one point in my code. Firstly a short clarification what I'm doing: As an input there's a image of a floor. With the Canny and HoughLinesP algorithm I want to segment the whole wall in many "small" parts, as you could see here, which is at the same time the ideal output (here without canny), I would like to get - a segment is between two red lines.

enter image description here

Alright, since I get actually this outout here

enter image description here

I wonder how to merge lines, which are too cloose to each other. For example the lines 2,4,3,5,6 should be one line and also count as one. Than line 7 till 15 should be also one, which will be the second line.

Of course, I did some research and tried this:

#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <experimental/filesystem>

using namespace cv;
using namespace std;

Mat srcReal = //here's this image http://imgur.com/a/Kcjp6
Mat src, dst, cdst;
vector<Vec4i> lines;

void wallMapping(Mat src) {

  Scalar mu, sigma;
  meanStdDev(src, mu, sigma);

  Canny(src, dst, mu.val[0] - sigma.val[0], mu.val[0] + sigma.val[0], 3, false);

  cvtColor(dst, cdst, CV_GRAY2BGR);
  HoughLinesP(dst, lines, 1, CV_PI / 2, 50, 50, 200);

  sort(lines.begin(), lines.end(), vec4iSortByX());                                 ///sort all lines by number

  for (size_t i = 1; i < lines.size(); i++) {                                   
        Vec4i current = lines[i];                                                   ///set current lines
        Point pt1 = Point(current[0], current[1]);
        Point pt2 = Point(current[2], current[3]);

        Vec4i previous = lines[i - 1];                                              ///set previous lines
        Point ppt1 = Point(previous[0], previous[1]);
        Point ppt2 = Point(previous[2], previous[3]);

        int gradient1, gradient2;
        if (pt1.x - pt2.x != 0) {
            gradient1 = (pt1.y - pt2.y) / (pt1.x - pt2.x);
            gradient2 = (ppt1.y - ppt2.y) / (ppt1.x - ppt2.x);
        }
        Point avrgpt1, avrgpt2;

        if (gradient1 == gradient2) {

            avrgpt1.x = (pt1.x + ppt1.x) / 2;
            avrgpt2.x = (pt2.x + ppt2.x) / 2;

            avrgpt1.y = (pt1.y + ppt1.y) / 2;
            avrgpt2.y = (pt2.y + ppt2.y) / 2;
        }

        double angle = atan2(ppt2.y - ppt1.y, ppt2.x - ppt1.x) * 180.0 / CV_PI;     ///draw only vertical lines (90 degree)
        if (angle) {
            std::vector<int> lineLabel;
            int numLines = cv::partition(lines, lineLabel, isEqual);
            line(cdst, avrgpt1, avrgpt2, Scalar(0, 0, 255), 2, CV_AA);
        }

        cv::putText(cdst, to_string(i+1), pt2 + Point(0, 10), 4, 1, Scalar(0, 255, 0), 1, 8, false);

        //some other stuff
 }

//main
int main(int argc, char *argv[]) {
       wallMapping(srcReal);

       waitKey(0);
       return 0;
}

But as you look at the picture above, you could see that my merging idea in the code doesn't work. So I'd be glad about idea, approaches or corrections of my code! Thanks!

1 Answers
Related