# Revision history [back]

### how can merge two lines to form a ROI

I already solve part of the problem, but i need to close the lines vertically, how can i solve this situation?

#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
using namespace cv;
using namespace std;
int main(int argc, char** argv){
// convert to HSV color space
Mat hsvImage;
cvtColor(input, hsvImage, CV_BGR2HSV);

// split the channels
std::vector<cv::Mat> hsvChannels;
split(hsvImage, hsvChannels);

// hue channels tells you the color tone, if saturation and value aren't too low.

// red color is a special case, because the hue space is circular and red is exactly at the beginning/end of the circle.
// in literature, hue space goes from 0 to 360 degrees, but OpenCV rescales the range to 0 up to 180, because 360 does not fit in a single byte. Alternatively there is another mode where 0..360 is rescaled to 0..255 but this isn't as common.
int hueValue = 65; // red color
int hueRange =  1; // how much difference from the desired color we want to include to the result If you increase this value, for example a red color would detect some orange values, too.

int minSaturation = 20; // I'm not sure which value is good here...
int minValue = 0; // not sure whether 50 is a good min value here...

Mat hueImage = hsvChannels[0]; // [hue, saturation, value]

// is the color within the lower hue range?
inRange(hueImage, hueValue - hueRange, hueValue + hueRange, hueMask);

// if the desired color is near the border of the hue space, check the other side too:
// TODO: this won't work if "hueValue + hueRange > 180" - maybe use two different if-cases instead... with int lowerHueValue = hueValue - 180
if (hueValue - hueRange < 0 || hueValue + hueRange > 180)
{
int upperHueValue = hueValue + 180; // in reality this would be + 360 instead
inRange(hueImage, upperHueValue - hueRange, upperHueValue + hueRange, hueMaskUpper);

}

// now we have to filter out all the pixels where saturation and value do not fit the limits:
Mat saturationMask = hsvChannels[1] > minSaturation;
Mat valueMask = hsvChannels[2] > minValue;

// now perform the line detection
std::vector<cv::Vec4i> lines;
HoughLinesP(hueMask, lines, 1, CV_PI / 360, 50, 50, 10);

// draw the result as big green lines:
for (unsigned int i = 0; i < lines.size(); ++i)
{
line(input, cv::Point(lines[i][0], lines[i][1]), cv::Point(lines[i][2], lines[i][3]), cv::Scalar(255, 255, 0), 2);
cout << Point(lines[i][0], lines[i][1]) << "END" << Point(lines[i][2], lines[i][3]) <<endl;
}

imwrite("detection.png", input);
imshow("input", input);
waitKey(0);
return 0;
}


This is my original image, now I need to merge the points to form a ROI.

### how can merge two lines to form a ROI

I already solve part of the problem, but i need to close the lines vertically, how can i solve this situation?

#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
using namespace cv;
using namespace std;
int main(int argc, char** argv){
// convert to HSV color space
Mat hsvImage;
cvtColor(input, hsvImage, CV_BGR2HSV);

// split the channels
std::vector<cv::Mat> hsvChannels;
split(hsvImage, hsvChannels);

// hue channels tells you the color tone, if saturation and value aren't too low.

// red color is a special case, because the hue space is circular and red is exactly at the beginning/end of the circle.
// in literature, hue space goes from 0 to 360 degrees, but OpenCV rescales the range to 0 up to 180, because 360 does not fit in a single byte. Alternatively there is another mode where 0..360 is rescaled to 0..255 but this isn't as common.
int hueValue = 65; // red color
int hueRange =  1; // how much difference from the desired color we want to include to the result If you increase this value, for example a red color would detect some orange values, too.

int minSaturation = 20; // I'm not sure which value is good here...
int minValue = 0; // not sure whether 50 is a good min value here...

Mat hueImage = hsvChannels[0]; // [hue, saturation, value]

// is the color within the lower hue range?
inRange(hueImage, hueValue - hueRange, hueValue + hueRange, hueMask);

// if the desired color is near the border of the hue space, check the other side too:
// TODO: this won't work if "hueValue + hueRange > 180" - maybe use two different if-cases instead... with int lowerHueValue = hueValue - 180
if (hueValue - hueRange < 0 || hueValue + hueRange > 180)
{
int upperHueValue = hueValue + 180; // in reality this would be + 360 instead
inRange(hueImage, upperHueValue - hueRange, upperHueValue + hueRange, hueMaskUpper);

}

// now we have to filter out all the pixels where saturation and value do not fit the limits:
Mat saturationMask = hsvChannels[1] > minSaturation;
Mat valueMask = hsvChannels[2] > minValue;

// now perform the line detection
std::vector<cv::Vec4i> lines;
HoughLinesP(hueMask, lines, 1, CV_PI / 360, 50, 50, 10);

// draw the result as big green lines:
for (unsigned int i = 0; i < lines.size(); ++i)
{
line(input, cv::Point(lines[i][0], lines[i][1]), cv::Point(lines[i][2], lines[i][3]), cv::Scalar(255, 255, 0), 2);
cout << Point(lines[i][0], lines[i][1]) << "END" << Point(lines[i][2], lines[i][3]) <<endl;
}

imwrite("detection.png", input);
imshow("input", input);
waitKey(0);
return 0;
}


This is my original image, now I need to merge the points to form a ROI.

### how can merge two lines to form create a ROI

I already solve part of the problem, but i need to close the lines vertically, how can i solve this situation?

#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
using namespace cv;
using namespace std;
int main(int argc, char** argv){
// convert to HSV color space
Mat hsvImage;
cvtColor(input, hsvImage, CV_BGR2HSV);

// split the channels
std::vector<cv::Mat> hsvChannels;
split(hsvImage, hsvChannels);

// hue channels tells you the color tone, if saturation and value aren't too low.

// red color is a special case, because the hue space is circular and red is exactly at the beginning/end of the circle.
// in literature, hue space goes from 0 to 360 degrees, but OpenCV rescales the range to 0 up to 180, because 360 does not fit in a single byte. Alternatively there is another mode where 0..360 is rescaled to 0..255 but this isn't as common.
int hueValue = 65; // red color
int hueRange =  1; // how much difference from the desired color we want to include to the result If you increase this value, for example a red color would detect some orange values, too.

int minSaturation = 20; // I'm not sure which value is good here...
int minValue = 0; // not sure whether 50 is a good min value here...

Mat hueImage = hsvChannels[0]; // [hue, saturation, value]

// is the color within the lower hue range?
inRange(hueImage, hueValue - hueRange, hueValue + hueRange, hueMask);

// if the desired color is near the border of the hue space, check the other side too:
// TODO: this won't work if "hueValue + hueRange > 180" - maybe use two different if-cases instead... with int lowerHueValue = hueValue - 180
if (hueValue - hueRange < 0 || hueValue + hueRange > 180)
{
int upperHueValue = hueValue + 180; // in reality this would be + 360 instead
inRange(hueImage, upperHueValue - hueRange, upperHueValue + hueRange, hueMaskUpper);

}

// now we have to filter out all the pixels where saturation and value do not fit the limits:
Mat saturationMask = hsvChannels[1] > minSaturation;
Mat valueMask = hsvChannels[2] > minValue;

// now perform the line detection
std::vector<cv::Vec4i> lines;
HoughLinesP(hueMask, lines, 1, CV_PI / 360, 50, 50, 10);

// draw the result as big green lines:
for (unsigned int i = 0; i < lines.size(); ++i)
{
line(input, cv::Point(lines[i][0], lines[i][1]), cv::Point(lines[i][2], lines[i][3]), cv::Scalar(255, 255, 0), 2);
cout << Point(lines[i][0], lines[i][1]) << "END" << Point(lines[i][2], lines[i][3]) <<endl;
}