2013-12-20 2 views
3

Я пытаюсь обнаружить пересечение между двумя линиями в подаче веб-камеры. Вот скриншот того, что у меня уже есть enter image description hereОтслеживание пересечения между 2-мя линиями в веб-камере feed opencv

Я пытаюсь найти пересечение между моей красной и зеленой линией.

А вот код того, что я уже

#include "stdafx.h" 

#include <cv.h> 
#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <highgui.h> 

IplImage* imgTracking; 
int lastX = -1; 
int lastY = -1; 

//This function threshold the HSV image and create a binary image 
IplImage* GetThresholdedImage(IplImage* imgHSV){  
    IplImage* imgThresh=cvCreateImage(cvGetSize(imgHSV),IPL_DEPTH_8U, 1); 
    cvInRangeS(imgHSV, cvScalar(170,160,60), cvScalar(180,2556,256), imgThresh); 
    return imgThresh; 
} 

void trackObject(IplImage* imgThresh){ 
    // Calculate the moments of 'imgThresh' 
    CvMoments *moments = (CvMoments*)malloc(sizeof(CvMoments)); 
    cvMoments(imgThresh, moments, 1); 
    double moment10 = cvGetSpatialMoment(moments, 1, 0); 
    double moment01 = cvGetSpatialMoment(moments, 0, 1); 
    double area = cvGetCentralMoment(moments, 0, 0); 

    // if the area<1000, I consider that the there are no object in the image and it's because of the noise, the area is not zero 
    if(area>1000){ 
     // calculate the position of the ball 
     int posX = moment10/area; 
     int posY = moment01/area;   

     if(lastX>=0 && lastY>=0 && posX>=0 && posY>=0) 
     { 
      // Draw a yellow line from the previous point to the current point 
      cvLine(imgTracking, cvPoint(posX, posY), cvPoint(lastX, lastY), cvScalar(0,0,255), 4); 
     } 

     lastX = posX; 
     lastY = posY; 
    } 
    cvLine(imgTracking,cv::Point(100,300) , cv::Point(600,300),cv::Scalar(0,200,0),2,8); 
    free(moments); 
} 

bool intersection(cv::Point lastX, cv::Point lastY, cv::Point , cv::Point()) 
{ 
} 

/* 
void imaginaryline() 
{ 
    cv::Mat img = cv::Mat::zeros(500, 500, CV_8UC3); 
    cv::line(img, cv::Point(100,200) , cv::Point(400,100),cv::Scalar(0,200,0),2,8); 
}*/ 

int main(){ 

     CvCapture* capture =0;  
     capture = cvCaptureFromCAM(0); 
     if(!capture){ 
     printf("Capture failure\n"); 
     return -1; 
     } 

     IplImage* frame=0; 
     frame = cvQueryFrame(capture);   
     if(!frame) return -1; 

    //create a blank image and assigned to 'imgTracking' which has the same size of original video 
    imgTracking=cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U, 3); 
    cvZero(imgTracking); //covert the image, 'imgTracking' to black 

    cvNamedWindow("Video");  
    cvNamedWindow("Ball"); 

     //iterate through each frames of the video  
     while(true){ 

      frame = cvQueryFrame(capture);   
      if(!frame) break; 
      frame=cvCloneImage(frame); 

      cvSmooth(frame, frame, CV_GAUSSIAN,3,3); //smooth the original image using Gaussian kernel 

      IplImage* imgHSV = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3); 
      cvCvtColor(frame, imgHSV, CV_BGR2HSV); //Change the color format from BGR to HSV 
      IplImage* imgThresh = GetThresholdedImage(imgHSV); 

      cvSmooth(imgThresh, imgThresh, CV_GAUSSIAN,3,3); //smooth the binary image using Gaussian kernel 

      //track the possition of the ball 
      trackObject(imgThresh); 
      printf("Pos X = %d", lastX); 
      printf("Pos Y = %d", lastY); 

      // Add the tracking image and the frame 
      cvAdd(frame, imgTracking, frame); 

      cvShowImage("Ball", imgThresh);   
      cvShowImage("Video", frame); 

      //Clean up used images 
      cvReleaseImage(&imgHSV); 
      cvReleaseImage(&imgThresh);    
      cvReleaseImage(&frame); 

      //Wait 10mS 
      int c = cvWaitKey(10); 
      //If 'ESC' is pressed, break the loop 
      if((char)c==27) break;  
     } 

     cvDestroyAllWindows() ; 
     cvReleaseImage(&imgTracking); 
     cvReleaseCapture(&capture);  

     return 0; 
} 

Спасибо за внимание парней, я ждал какой-либо из вашего ответа

UPDATE: Благодаря Sebastian Schmitz, я sollved его. Вот мой код

void checkIntersection(int line, int lastY, int y) 
{ 
    if(lastY << line && y >= line || lastY > line && y <= line) 
    { 
     printf("intersection detected"); 
    } 
} 

void trackObject(IplImage* imgThresh){ 
    // Calculate the moments of 'imgThresh' 
    CvMoments *moments = (CvMoments*)malloc(sizeof(CvMoments)); 
    cvMoments(imgThresh, moments, 1); 
    double moment10 = cvGetSpatialMoment(moments, 1, 0); 
    double moment01 = cvGetSpatialMoment(moments, 0, 1); 
    double area = cvGetCentralMoment(moments, 0, 0); 

    // if the area<1000, I consider that the there are no object in the image and it's because of the noise, the area is not zero 
    if(area>1000){ 
     // calculate the position of the ball 
     int posX = moment10/area; 
     int posY = moment01/area;   

     if(lastX>=0 && lastY>=0 && posX>=0 && posY>=0) 
     { 
      // Draw a yellow line from the previous point to the current point 
      cvLine(imgTracking, cvPoint(posX, posY), cvPoint(lastX, lastY), cvScalar(0,0,255), 4); 
     } 
     checkIntersection(300, lastY, posY); 
     lastX = posX; 
     lastY = posY; 
    } 
    cvLine(imgTracking,cv::Point(100,300) , cv::Point(600,300),cv::Scalar(0,200,0),2,8); 
    cvRectangle(imgTracking,cv::Point(400,400), cv::Point(450,450),cv::Scalar(0,200,0),2,8); 
    free(moments); 
} 

я поставил вызов для функции checkintersection внутри trackobject функции, поэтому я не должен изменить переменную Posy в глобальные, которые приводят ко многим ошибок.

Спасибо всем за ответ

+0

Является ли линия всегда совершенно горизонтальной? Или он может быть наклонным? –

+0

Зеленая линия будет всегда идеально горизонтальной @ HannesOvrén –

ответ

3

Если линия всегда идеально horiontal, это будет достаточно, чтобы проверить, если у координаты последней точки на одной стороне линии и текущей точки на другую :

//Pseudocode: 
int line = 20; //horizontal line on y-coordinate "20" 
while(tracking == true){ 
    int lastY = posY; 
    int y = getCoordinate().getY(); //call the y-coordinate of your current point 
    checkIntersection(line, lastY, y) 
} 

checkIntersection(int line, int lastY, int y){ 
    if(lastY < line && y >= line || 
     lastY > line && y <= line){ 
     print("intersection detected") 
     //optional additional check if point is between endpoint of line if you have to 
    } 
} 
+0

привет @Sebastian Schmitz, я реализую ваш код, но я все еще смущен. Я не нашел никакой функции для получения координат в opencv. И у меня есть вопрос. Где я должен помещать этот код в основной или вставку класса trackobject? спасибо –

+1

Я предполагаю, что ваш цикл while должен сказать 'while (tracking == true)', даже если это псевдокод, я думаю, что мы должны, вероятно, сохранить разделение и равенство отдельно. –

+0

err, что такое функция getcoordinate в opencv? Я не нашел его –

 Смежные вопросы

  • Нет связанных вопросов^_^