@@ -23,66 +23,20 @@ void Processing::processImage(Mat& inputPicture, int thresholdValue, int gaussKe | |||
// One (this) to do all kinds of stuff to the picture (grayscale conversion, threshold, gauss etc etc) | |||
// And one (the other one) to segment the lines. | |||
// No return value here as the input is passed by reference -> directly modified. | |||
vector<Vec4i> lines; | |||
cvtColor(inputPicture, inputPicture, COLOR_BGR2GRAY); | |||
threshold(inputPicture, inputPicture, thresholdValue, 255, THRESH_BINARY); | |||
GaussianBlur(inputPicture, inputPicture, Size(gaussKernelSize, gaussKernelSize), 0); | |||
Canny(inputPicture, inputPicture, 50, 200, 3); | |||
HoughLinesP(inputPicture, lines, 1, CV_PI/180, 150, 0, 0); | |||
//Draw lines | |||
for( size_t i = 0; i < lines.size(); i++ ) | |||
{ | |||
line( inputPicture, Point(lines[i][0], lines[i][1]), | |||
Point( lines[i][2], lines[i][3]), Scalar(0,0,255), 3, 8 ); | |||
} | |||
vector<VectorOfLines> vectors; | |||
Point point11; | |||
Point point12; | |||
Point point21; | |||
Point point22; | |||
for( size_t i = 0; i < lines.size(); i++ ) | |||
{ | |||
point11 = Point(lines[i][0], lines[i][1]); | |||
point12 = Point( lines[i][2], lines[i][3]); | |||
float gradient1 = VectorOfLines::calcGradient(point11, point12); | |||
for( size_t j = 0; j < lines.size(); j++ ) | |||
{ | |||
if(j != i){ | |||
point21 = Point(lines[j][0], lines[j][1]); | |||
point22 = Point(lines[j][2], lines[j][3]); | |||
float gradient2 = VectorOfLines::calcGradient(point21, point22); | |||
float gradient12 = VectorOfLines::calcGradient(point12, point21); | |||
if((norm(gradient1 - gradient2) < 0.05) & (norm(gradient1 - gradient12) < 0.05)) | |||
{ | |||
//To Do: add line between 2 lines | |||
} | |||
} | |||
} | |||
} | |||
imshow("Result", inputPicture); | |||
waitKey(0); | |||
destroyWindow("Result"); | |||
for( size_t i = 0; i < lines.size(); i++ ) | |||
{ | |||
line( inputPicture, Point(lines[i][0], lines[i][1]), | |||
Point( lines[i][2], lines[i][3]), Scalar(0,0,255), 3, 8 ); | |||
} | |||
GaussianBlur(inputPicture, inputPicture, Size(gaussKernelSize, gaussKernelSize), 0); | |||
Canny(inputPicture, inputPicture, 50, 100, 3); | |||
} | |||
std::vector<LFRLine> Processing::calculateLineSegments(const Mat& inputPicture) | |||
std::vector<Vec4i> Processing::calculateLineSegments(const Mat& inputPicture) | |||
{ | |||
//See following link | |||
//https://stackoverflow.com/questions/45322630/how-to-detect-lines-in-opencv | |||
return std::vector<LFRLine>(); | |||
vector<Vec4i> lines; | |||
VectorOfLines linesInVectors; | |||
HoughLinesP(inputPicture, lines, 1, CV_PI/360, 150, 0, 250); | |||
//lines = linesInVectors.findMiddleLine(lines); | |||
return lines; | |||
} |
@@ -21,5 +21,5 @@ public: | |||
void processImage(Mat& inputPicture, int thresholdValue, int gaussKernelSize); | |||
std::vector<LFRLine> calculateLineSegments(const Mat& inputPicture); | |||
std::vector<Vec4i> calculateLineSegments(const Mat& inputPicture); | |||
}; |
@@ -50,12 +50,53 @@ VectorOfLines::VectorOfLines() | |||
{ | |||
} | |||
float VectorOfLines::calcGradient(Point p0, Point p1) | |||
VectorOfLines::~VectorOfLines() | |||
{ | |||
return (p1.y - p0.y)/(p1.x - p0.x); | |||
} | |||
double VectorOfLines::calcGradient(Point p0, Point p1) | |||
{ | |||
double gradient = (p1.y - p0.y)/(p1.x - p0.x + 1e-10); | |||
return p1.x > p0.x ? gradient : - gradient; | |||
} | |||
float VectorOfLines::calcZeroPoint(cv::Point x, float m) | |||
{ | |||
return 0.0; | |||
} | |||
double VectorOfLines::calcDistance(Point p0, Point p1) | |||
{ | |||
return sqrt(pow(p1.y - p0.y, 2) + pow(p1.x - p0.x, 2)); | |||
} | |||
vector<Vec4i> VectorOfLines::findMiddleLine(vector<Vec4i> &lines){ | |||
Point point11; | |||
Point point12; | |||
Point point21; | |||
Point point22; | |||
vector<Vec4i> middleLines; | |||
for( size_t i = 0; i < (lines.size() - 1); i++ ) | |||
{ | |||
point11 = Point(lines[i][0], lines[i][1]); | |||
point12 = Point( lines[i][2], lines[i][3]); | |||
double gradient1 = VectorOfLines::calcGradient(point11, point12); | |||
//Compare every Line with the other | |||
for( size_t j = 0; j < (lines.size()); j++ ) | |||
{ | |||
if(j != i) | |||
{ | |||
point21 = Point(lines[j][0], lines[j][1]); | |||
point22 = Point(lines[j][2], lines[j][3]); | |||
double gradient2 = VectorOfLines::calcGradient(point21, point22); | |||
if(norm(gradient1 - gradient2) < 0.15) | |||
{ | |||
middleLines.push_back(Vec4i((point11.x+point21.x)/2, (point11.y+point21.y)/2, (point12.x+point22.x)/2, (point12.y+point22.y)/2)); | |||
} | |||
} | |||
} | |||
} | |||
return middleLines; | |||
} |
@@ -55,8 +55,9 @@ class VectorOfLines{ | |||
float zeroPoint; | |||
VectorOfLines(); | |||
~VectorOfLines(); | |||
static float calcGradient(Point x, Point y); | |||
static double calcGradient(Point x, Point y); | |||
float calcZeroPoint(cv::Point x, float m); | |||
static double calcDistance(Point p0, Point p1); | |||
vector<Vec4i> findMiddleLine(vector<Vec4i> &lines); | |||
}; |
@@ -9,7 +9,7 @@ int main(void) | |||
const int thresholdBinary = 140; | |||
const int videoHeight = 240; | |||
const int videoWidth = 320; | |||
const int gaussKernelSize = 11; | |||
const int gaussKernelSize = 21; | |||
LFR lfr(videoHeight, videoWidth, thresholdBinary, gaussKernelSize); | |||
lfr.startLoop(); |
@@ -23,8 +23,14 @@ void LFR::loop() | |||
while(iAmLooping) | |||
{ | |||
Mat image = input.readFile("C:\\Line-Following-Robot\\Test_data"); | |||
processing.processImage(image, this->thresholdBinary, this->gaussKernelSize); | |||
std::vector<LFRLine> lines = processing.calculateLineSegments(image); | |||
Mat processedImage = image; | |||
processing.processImage(processedImage, this->thresholdBinary, this->gaussKernelSize); | |||
std::vector<Vec4i> lines = processing.calculateLineSegments(processedImage); | |||
for( size_t i = 0; i < lines.size(); i++ ) | |||
{ | |||
line( image, Point(lines[i][0], lines[i][1]), | |||
Point( lines[i][2], lines[i][3]), (0,0,255), 1, 8 ); | |||
} | |||
imshow("Display window", image); | |||
char c = (char)waitKey(1); | |||
} |