j'ai fait un petit billet concernant OpenCV & SFML disponible ici :
http://grom.hd.free.fr/index.php/opencv-capture-de-balles/il se peu que le lien soit hors-ligne de temps en temps, il est hébergé sur mon PI2 au fesses de ma box ( en cas de reboot , ma box vire toute les redirections... )
L'utilisation de la SFML n'est pas obligé , mais je l'utilise tout le temps ^^
le point clé , pour récupérer n'importe quel flux en temps réel est ici :
...
// on récupère la webcam
//
cv::Mat webcam_frame;
webcam >> webcam_frame;
// on convertit le flux BGR ( format OPENCV) en RGBA ( format SFML )
//
cv::Mat sfml_rgba_frame;
cv::cvtColor(webcam_frame, sfml_rgba_frame, CV_BGR2RGBA);
// on créer la texture a partir des informations de l'objet cv::Mat sfml_rgba_frame;
//
sf::Texture texture;
texture.create(sfml_rgba_frame.cols,sfml_rgba_frame.rows);
texture.update(reinterpret_cast<sf::Uint8*>(sfml_rgba_frame.ptr()));
...
je met le code au cas ou (c++11) :
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
int iLowH = 8;
int iHighH = 13;
int iLowS = 87;
int iHighS = 115;
int iLowV = 192;
int iHighV = 255;
int main()
{
cv::VideoCapture webcam;
if(!webcam.open(0)){
return 0;
}
CvSize capture_size = cvSize(webcam.get(CV_CAP_PROP_FRAME_WIDTH),webcam.get(CV_CAP_PROP_FRAME_HEIGHT));
sf::RenderWindow window(sf::VideoMode::getDesktopMode(), "balltraking");
sf::View view(sf::FloatRect(0,
0,
capture_size.width,
capture_size.height));
cv::namedWindow("controls", CV_WINDOW_AUTOSIZE);
cv::createTrackbar( "LowH", "controls", &iLowH , 179);
cv::createTrackbar( "HighH", "controls", &iHighH , 179);
cv::createTrackbar( "LowS", "controls", &iLowS , 255);
cv::createTrackbar( "HighS", "controls", &iHighS , 255);
cv::createTrackbar( "LowV", "controls", &iLowV , 255);
cv::createTrackbar( "HighV", "controls", &iHighV , 255);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
// push webcam frame to cv::Mat
//
cv::Mat webcam_frame;
webcam >> webcam_frame;
// detect a color
//
cv::Mat hsv_frame;
cv::Mat threshold_frame;
cv::cvtColor(webcam_frame, hsv_frame, CV_BGR2HSV);
cv::Scalar hsv_min(iLowH, iLowS, iLowV, 0);
cv::Scalar hsv_max(iHighH, iHighS, iHighV, 0);
cv::inRange(hsv_frame, hsv_min, hsv_max, threshold_frame);
cv::blur(threshold_frame,threshold_frame,cv::Size(9,9));
// detect circle with HoughCircles algorithm
//
std::vector<cv::Vec3f> circles;
cv::HoughCircles(threshold_frame, circles, CV_HOUGH_GRADIENT,2, threshold_frame.rows/4, 100, 50, 10, 400);
// convert webcam frame (bgr) to sfml format texture (rgba)
//
cv::Mat sfml_rgba_frame;
cv::cvtColor(webcam_frame, sfml_rgba_frame, CV_BGR2RGBA);
cv::Mat sfml_bgr_thresholded_frame;
cv::Mat sfml_rgba_thresholded_frame;
cv::cvtColor(threshold_frame, sfml_bgr_thresholded_frame, CV_GRAY2BGR);
cv::cvtColor(sfml_bgr_thresholded_frame, sfml_rgba_thresholded_frame, CV_BGR2RGBA);
// create sfml texture from sfml_rgba_frame
//
sf::Texture texture;
texture.create(sfml_rgba_frame.cols,sfml_rgba_frame.rows);
texture.update(reinterpret_cast<sf::Uint8*>(sfml_rgba_frame.ptr()));
sf::Texture thresholded_texture;
thresholded_texture.create(sfml_rgba_thresholded_frame.cols,sfml_rgba_thresholded_frame.rows);
thresholded_texture.update(reinterpret_cast<sf::Uint8*>(sfml_rgba_thresholded_frame.ptr()));
// sfml draw
//
window.setView(view);
window.clear(sf::Color::Blue);
sf::Sprite webcam_sprite;
webcam_sprite.setTexture(texture);
window.draw(webcam_sprite);
for(auto & c : circles){
sf::CircleShape shape;
shape.setPosition(sf::Vector2f(c[0]-c[2],c[1]-c[2]));
shape.setRadius(float(c[2]));
shape.setFillColor(sf::Color::Transparent);
shape.setOutlineColor(sf::Color::Green);
shape.setOutlineThickness(2);
window.draw(shape);
}
sf::Sprite thresholded_sprite;
thresholded_sprite.setTexture(thresholded_texture);
thresholded_sprite.setScale(0.25,0.25);
window.draw(thresholded_sprite);
window.display();
}
return 0;
}