我正在尝试检测摄像头提要中两条线之间的交点。这是我已经拥有的屏幕截图

我尝试找到红线和绿线之间的交点。

这是我已经拥有的代码

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

谢谢您的关注,我等待您的任何回复

更新:
多亏塞巴斯蒂安·施密茨(Sebastian Schmitz),我才解决了。这是我的代码
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更改为global,这会导致很多错误。

谢谢大家的回应

最佳答案

如果直线始终完美水平,则足以测试最后一点的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
    }
}

10-08 17:40