samedi 26 juillet 2014

Detetcting intersection entre 2 lignes en webcam nourrir opencv - Stack Overflow


i'm trying to detect the intersection between two line in webcam feed. Here's the screenshot of what i already have enter image description here


I try to find the intersection between my red and green line.


And here's the code of what i already have


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

Thank you for your attention guys, i waited for any of your response


UPDATE : Thanks to Sebastian Schmitz, i sollved it. Here's my code


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

i put the call for checkintersection function inside trackobject function so i dont have to change variable posY into global which lead to many error.


Thank you all for your response




If the line is always perfectly horiontal, it will be enough to test if the y coordinate of your last point is on one side of the line and your current Point on the other:


//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
}
}


i'm trying to detect the intersection between two line in webcam feed. Here's the screenshot of what i already have enter image description here


I try to find the intersection between my red and green line.


And here's the code of what i already have


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

Thank you for your attention guys, i waited for any of your response


UPDATE : Thanks to Sebastian Schmitz, i sollved it. Here's my code


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

i put the call for checkintersection function inside trackobject function so i dont have to change variable posY into global which lead to many error.


Thank you all for your response



If the line is always perfectly horiontal, it will be enough to test if the y coordinate of your last point is on one side of the line and your current Point on the other:


//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 commentaires:

Enregistrer un commentaire