'How to detect and separate vertical and horizontal line and add a circle in the middle of a line from a video opencv
The problem I'm experiencing is that when the horizontal line doesn't form a 180-degree straight line, the hough lines will be fragmented and untidy. Please help so that I can detect a horizontal line using a certain angle or if it has entered a certain angle it will be detected and not cut off in the middle.
This is when the line is straight
This is when the line is not straight
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
// using namespace cv;
int hueminFIELD = 32, huemaxFIELD = 86, satminFIELD= 81, satmaxFIELD = 255, valminFIELD = 0, valmaxFIELD = 255;
int hueminLINE = 0, huemaxLINE = 179, satminLINE= 0, satmaxLINE = 255, valminLINE = 218, valmaxLINE = 255;
cv::Mat hsv, mask;
void getCountours(cv::Mat tebel, cv::Mat gambar){
vector<vector<cv::Point>> kontur;
vector<cv::Vec4i> hierarki;
findContours(tebel,kontur,hierarki,cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
vector<cv::Rect> bataskotak(kontur.size());
vector<vector<cv::Point>> hull(kontur.size());
for (int i = 0; i < kontur.size(); i++)
{
int area = cv::contourArea(kontur[i]);// vector<vector<Point>> konpoli(kontur.size());[i]);
convexHull(cv::Mat(kontur[i]),hull[i]);
drawContours(gambar, hull, i, cv::Scalar(255,0,255),-1);
float batas = cv::arcLength(kontur[i],true);
bataskotak[i]=cv::boundingRect(kontur[i]);
// cv::rectangle(gambar, bataskotak[i].tl(), bataskotak[i].br(), cv::Scalar(255,0,255), -1);
cv::circle(gambar, cv::Point((bataskotak[i].tl()+bataskotak[i].br())/2), 6, cv::Scalar(255,255,255), cv::FILLED);
}
}
int main(){
cv::VideoCapture vid("lapa.mp4");
//trackbar buat nyari warna putih
cv::namedWindow("Trackbar", cv::WINDOW_AUTOSIZE);
cv::createTrackbar("Hue min", "Trackbar", &hueminLINE, 179);
cv::createTrackbar("Hue max", "Trackbar", &huemaxLINE, 179);
cv::createTrackbar("Saturation min", "Trackbar", &satminLINE, 255);
cv::createTrackbar("Saturation Max", "Trackbar", &satmaxLINE, 255);
cv::createTrackbar("Value min", "Trackbar", &valminLINE, 255);
cv::createTrackbar("Value max", "Trackbar", &valmaxLINE, 255);
while(1){
cv::Mat video;
vid.read(video);
cv::resize(video,video,cv::Size(640,480));
//Segmentasi warna lapangan
//cv::GaussianBlur(video,video,cv::Size(3,3),5,2);
cv::cvtColor(video, hsv, cv::COLOR_BGR2HSV);
cv::Scalar lower(hueminFIELD, satminFIELD, valminFIELD);
cv::Scalar upper(huemaxFIELD, satmaxFIELD, valmaxFIELD);
cv::inRange(hsv, lower,upper, mask);
// cv::cvtColor(mask,mask,cv::COLOR_GRAY2BGR);
// cv::Mat hasil; //untuk menyimpan hasil video.
//Bagian kontur
vector<vector<cv::Point>> kontur;
vector<cv::Vec4i> hierarki;
findContours(mask, kontur, hierarki, cv::RETR_TREE,cv::CHAIN_APPROX_NONE);
vector<cv::Point> for_convex;
cv::Mat drawing = cv::Mat::zeros(mask.size(), CV_8UC3);
for (int i = 0; i < kontur.size(); i++)
{
for_convex.insert(for_convex.end(), kontur[i].begin(), kontur[i].end());
}
vector<cv::Point> convexed;
convexHull(for_convex,convexed);
vector<vector<cv::Point>> convexbener;
convexbener.push_back(convexed);
drawContours(drawing,convexbener,0,cv::Scalar(255,255,255),-1);
//Bagian segmentasi garis putih
cv::Mat lapangan;
cv::bitwise_and(video,drawing,lapangan);
// cv::imshow("lapangan",lapangan);
// cv::imshow("drawing",drawing);
cv::Mat lapanganhsv;
cv::cvtColor(lapangan, lapanganhsv, cv::COLOR_BGR2HSV);
cv::Scalar lowerLINE(hueminLINE, satminLINE, valminLINE);
cv::Scalar upperLINE(huemaxLINE, satmaxLINE, valmaxLINE);
cv::Mat maskline;
cv::inRange(lapanganhsv, lowerLINE,upperLINE, maskline);
cv::Mat strukturgaris = cv::getStructuringElement(cv::MORPH_RECT,cv::Size(3,3));
cv::dilate(maskline,maskline,strukturgaris);
//cari kontur garis kemudian convexhull
// vector<vector<cv::Point>> kontur_line;
// vector<cv::Vec4i> hierarki_line;
// findContours(maskline, kontur_line, hierarki_line, cv::RETR_TREE,cv::CHAIN_APPROX_NONE);
// cv::Mat drawing_line = cv::Mat::zeros(maskline.size(), CV_8UC3);
// for (int i = 0; i < kontur_line.size(); i++)
// {
// int area_line = cv::contourArea(kontur_line[i]);
// drawContours(drawing_line,kontur_line,0,cv::Scalar(255,0,255),-1);
// }
// cv::cvtColor(maskline,maskline,cv::COLOR_GRAY2BGR);
cv::imshow("maskline",maskline);
// cv::imshow("kontur",drawing_line);
cv::Mat hasilakhir;
// cv::bitwise_and(video, drawing_line, hasilakhir);
// cv::imshow("hasilconvexline",hasilakhir);
//mulai deteksi garis
//horizontal
// cv::Mat cloning,horizontalStructure;
// cloning = maskline.clone();
// int horizontalSize = maskline.cols/7.5;
// horizontalStructure = cv::getStructuringElement(cv::MORPH_RECT,cv::Size(horizontalSize,1));
// erode(maskline, maskline, horizontalStructure, cv::Point(-1, -1));
// dilate(maskline, maskline, horizontalStructure, cv::Point(-1, -1));
// std::vector<std::vector<cv::Point>> contour_garis;
// std::vector<cv::Point > contour_line_point;
// findContours(maskline,contour_garis,hierarki,cv::RETR_TREE,cv::CHAIN_APPROX_NONE);
// for(size_t i = 0; i < contour_garis.size(); i++){
// // std::cout<<"cv::contourArea(contours_lines[i]) : "<<cv::contourArea(contours_lines[i])<<std::endl;
// if(cv::contourArea(contour_garis[i]) > 150){
// contour_line_point.insert(contour_line_point.end(), contour_garis[i].begin(), contour_garis[i].end());
// }
// cv::cvtColor(horizontal,horizontal,cv::COLOR_GRAY2BGR);
// cv::cvtColor(horizontal,horizontal,cv::COLOR_GRAY2BGR);
// cv::imshow("maskline",lapangan);
// cv::Mat hasilakhir;
//cv::bitwise_and(video,maskline,hasilakhir);
//cv::imshow("videoawaL",hasilakhir);
//SKELETON
cv::Mat skel(maskline.size(), CV_8UC1, cv::Scalar(0));
cv::Mat temp(maskline.size(), CV_8UC1);
cv::Mat element = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(3, 3));
bool done;
do
{
cv::morphologyEx(maskline, temp, cv::MORPH_OPEN, element);
cv::bitwise_not(temp, temp);
cv::bitwise_and(maskline, temp, temp);
cv::bitwise_or(skel, temp, skel);
cv::erode(maskline, maskline, element);
double max;
cv::minMaxLoc(maskline, 0, &max);
done = (max == 0);
} while (!done);
//Hough Line dari skeleton
vector<cv::Vec4i> lines;
HoughLinesP(skel,lines,2, CV_PI/180,80,0,200);
cv::Mat maskbgr;
cvtColor(maskline, maskline, cv::COLOR_GRAY2BGR);
// gambar hough line
for (size_t i = 0; i < lines.size(); i++)
{
cv::Vec4i l = lines[i];
line(maskline, cv::Point(l[0], l[1]), cv::Point(l[2], l[3]), cv::Scalar(255,0,0),1,cv::LINE_AA);
}
//HORIZONTAL
cv::Mat bw;
cv::adaptiveThreshold(skel, bw, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 15, -2);
cv::Mat horizontal = bw.clone();
int horizontal_size = horizontal.cols / 40;
cv::Mat horizontalStructure = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(horizontal_size, 1));
cv::erode(horizontal, horizontal, horizontalStructure);
cv::dilate(horizontal, horizontal, horizontalStructure,cv::Point(-1,-1),10);
// getCountours(horizontal,video);
// // Hough line prob
vector<cv::Vec4i> horiz_lines;
HoughLinesP(horizontal,lines,1, CV_PI/180,80,0,300);
// Mat maskbgr;
cvtColor(horizontal, horizontal, cv::COLOR_GRAY2BGR);
// // gambar hough line
for (size_t i = 0; i < lines.size(); i++)
{
cv::Vec4i l = lines[i];
line(video, cv::Point(l[0], l[1]), cv::Point(l[2], l[3]), cv::Scalar(255,0,0),1,cv::LINE_AA);
}
cv::Mat eroded;
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(5,5));
cv::erode(horizontal,eroded,kernel,cv::Point(-1,-1), 3);
cv::imshow("horizontal", horizontal);
cv::imshow("video", video);
//VERTIKAL
// cv::cvtColor(horizontal,horizontal,cv::COLOR_BGR2GRAY);
// cv::Mat blur_line;
// cv::GaussianBlur(horizontal, blur_line,cv::Size(5,5),0);
// cv::Mat edges;
// cv::Canny(blur_line,edges,50,150);
// cv::imshow("edges",edges);
cv::waitKey(100);
}
return 0;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
