#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp> // for hough line
#include <iostream>
#define FRAMERATE 20
#define CANNY_THRESHOLD1 125
#define CANNY_THRESHOLD2 300
#define PI 3.1415926
using namespace cv;
using namespace std;
class LineFinder{
private:
Mat img; // 원본영상
vector<Vec4i> lines; // 선을 감지하기 위한 마지막 점을 포함
double deltaRho;
double deltaTheta; // 누산기 해상도 파라미터
int minVote; // 선을 고려하기 전에 받아야하는 최소 투표 개수
double minLength; // 선에 대한 최소 길이
double maxGap; // 선에 대한 최대 허용 간격
public:
LineFinder() : deltaRho(1), deltaTheta(PI / 180), minVote(10), minLength(0.), maxGap(0.){}
//기본 누적 해상도는 1각도 1화소
//간격이 없고 최소 길이도 없음
//해당 세터
//누적기에 해상도설정
void setAccResolution(double dRho, double dTheta){
deltaRho = dRho;
deltaTheta = dTheta;
}
//최소 투표 개수 설정
void setMinVote(int minv){
minVote = minv;
}
//선 길이와 간격 설정
void setLineLengthAndGap(double length, double gap){
minLength = length;
maxGap = gap;
}
// 허프 선 세그먼트 감지를 수행하는 메소드
// 확률적 허프 변환 사용
vector<Vec4i> findLines(Mat &binary){
lines.clear();
HoughLinesP(binary, lines, deltaRho, deltaTheta, minVote, minLength, maxGap);
return lines;
} // Vec4i 벡터를 변환하고, 감지된 세그먼트의 시작과 마지막 점 좌표를 포함
// 위 메소드에서 감지한 선을 다음 메소드를 사용해서 그림
// 영상에서 감지된 선을 그리기
void drawDetectedLines(Mat &image, Scalar color = Scalar(0,0,255)){
vector<Vec4i>::const_iterator it2 = lines.begin();
while (it2 != lines.end()){
Point pt1((*it2)[0], (*it2)[1]);
Point pt2((*it2)[2], (*it2)[3]);
line(image, pt1, pt2, color);
++it2;
}
}
};
int main(int argc, char** argv)
{
VideoCapture vedioFrame("REC_2015_03_17_08_43_20_D.avi");
if (!vedioFrame.isOpened()){
cout << "동영상 불러오기 실패";
}
Mat img;
while (1){
vedioFrame >> img;
if (img.empty()) break; //동영상 끝났을 때
if (waitKey(FRAMERATE) == 27) break; // 27은 esc의 아스키코드
//캐니 알고리즘
Mat contours;
Canny(img, contours, CANNY_THRESHOLD1, CANNY_THRESHOLD2);
LineFinder Id; //인스턴스 생성
//확률적 허프변환 파라미터 설정하기
Id.setLineLengthAndGap(100, 30);
Id.setMinVote(50);
//선을 감지하고 그리기
vector<Vec4i> li = Id.findLines(contours);
Id.drawDetectedLines(img);
//창 사이즈 줄이기
Mat img_dst;
Mat contours_dst;
resize(img, img_dst, Size(),0.5,0.5);
resize(contours, contours_dst, Size(), 0.5, 0.5);
//창 띄우기
imshow("detected line video", img_dst);
imshow("contours line video", contours_dst);
}
destroyAllWindows();
}