Я пытаюсь обнаружить пересечение двух линий в веб-камере. Вот скриншот того, что у меня уже есть введите описание изображения здесь

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

А вот код того, что у меня уже есть

#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;
}

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

ОБНОВЛЕНИЕ: Благодаря Себастьяну Шмитцу я решил это. Вот мой код

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 на глобальную, что приводит ко многим ошибкам.

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

3
Kevin phytagoras 20 Дек 2013 в 12:05
Линия всегда идеально горизонтальна? Или он может быть наклонным?
 – 
Hannes Ovrén
20 Дек 2013 в 12:34
Зеленая линия всегда будет идеально горизонтальной @ HannesOvrén
 – 
Kevin phytagoras
20 Дек 2013 в 13:13

1 ответ

Лучший ответ

Если линия всегда идеально горизонтальна, этого будет достаточно, чтобы проверить, находится ли координата y вашей последней точки с одной стороны линии, а ваша текущая точка - с другой:

//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
    }
}
3
Sebastian Schmitz 28 Дек 2013 в 21:34
Привет @Sebastian Schmitz, я реализую ваш код, но все еще запутался. Я не нашел никакой функции для получения координаты в opencv. И у меня вопрос. Где мне разместить этот код, в главном классе или в классе вставки trackobject? Спасибо
 – 
Kevin phytagoras
23 Дек 2013 в 10:18
1
Я предполагаю, что в вашем цикле while должно быть указано while(tracking == true), даже если это псевдокод, я думаю, нам, вероятно, следует разделять присваивание и равенство.
 – 
Hannes Ovrén
23 Дек 2013 в 15:39
Эээ, что такое функция getcoordinate в opencv? я не нашел это
 – 
Kevin phytagoras
23 Дек 2013 в 17:02
После настройки здесь и этого, я решаю это сверху псевдокода. Спасибо, @Sebastian Schmitz. Вот мой код
 – 
Kevin phytagoras
24 Дек 2013 в 02:07