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.
Alright, since I get actually this outout 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!