ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Ros not responding to keypress to WaitKey..

asked 2015-03-25 08:59:04 -0500

215 gravatar image

updated 2015-04-01 05:37:29 -0500

Hi guys..

I am using openCV to run some video processing, in which i switch 2 algorithm, and the switch is performed by the user, from a key press.. The only problem is though i am not able it make react on key press.

It seems like it keep looping around the same code, even though i press a key..

How do i make it change??

Here is the code..

Main.cpp

#include "class.cpp"


int main( int argc, char** argv )
{
   ros::init(argc, argv, "image_converter");
   ImageConverter ic;
   ros::spin();
   return 0;
}

class.h

#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "sensor_msgs/JointState.h"
#include "facedetect.h"
#include <cmath>



using namespace cv;
using namespace std;

static const std::string OPENCV_WINDOW = "Image window";


class ImageConverter
{
  ros::NodeHandle nh_;
  image_transport::ImageTransport it_;
  image_transport::Subscriber image_sub_;
  image_transport::Publisher image_pub_;
  std::vector<double> pos;
  std::vector<double> vel;
  double position_prev_p;
  double position_prev_t;
  pair<double,double> displacement;
  ros::Subscriber sub;
  ros::Publisher facedetect_pub;
  Rect face;
  bool state;


public:
      void chatterCallback(const sensor_msgs::JointState::ConstPtr& msg);
      ImageConverter();
      ~ImageConverter();
      void imageDetect(const sensor_msgs::ImageConstPtr& msg);


};

class.cpp

#include "class.h"

ImageConverter::ImageConverter()
    : it_(nh_),pos(2),  vel(2) 
  {
    // Subscrive to input video feed and publish output video feed

        image_sub_ = it_.subscribe("/custom/left/image_rect_color", 1, 
        &ImageConverter::imageDetect, this);
        image_pub_ = it_.advertise("/image_converter/output_video", 1);
        state = false;
  }



    ImageConverter::~ImageConverter()
      {
        //cv::destroyAllWindows();
      }

      void ImageConverter::imageDetect(const sensor_msgs::ImageConstPtr& msg)
      {
         facedetect_pub = nh_.advertise<sensor_msgs::JointState>("/custom/cmd", 1);
         sub = nh_.subscribe("/joint_states",1,&ImageConverter::chatterCallback,this); 
         cv_bridge::CvImagePtr cv_ptr;
         sensor_msgs::JointState ms;
        try
        {
          cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
        }
        catch (cv_bridge::Exception& e)
        {
          ROS_ERROR("cv_bridge exception: %s", e.what());
          return;
        }

        if (!state) {
            cout <<"Can i see you ?" << endl;

            if(waitKey(10) != 'y')
            {
                face = detectAndDisplay(cv_ptr->image);
            }else{
                state = true;
            }
        }else{
            cout <<"Face detected" << endl; 
            displacement = track(face,cv_ptr->image);
            if(abs(pos[0]-position_prev_p) < 0.50 )
            {
                pos[0] = ceil(sin(displacement.first*0.000727220522)*1000)/1000 + position_prev_p;
            }
            if(abs(pos[1]-position_prev_t) < 0.50)
            {
                cout << "tilt change" << endl;
                pos[1] = -ceil(sin(displacement.second*0.000727220522)*1000)/1000 + position_prev_t;
            }

                ms.position = pos;
                vel[0] =0;
                vel[1] = 0;
                ms.velocity = vel;
                ROS_INFO_STREAM("pan: "<<pos[0]);
                ROS_INFO_STREAM("pan_prev: " << position_prev_p);
                ROS_INFO_STREAM("Subtracted: " <<abs(pos[0]-position_prev_p));
                ROS_INFO_STREAM("tilt: "<<pos[1]);
                ROS_INFO_STREAM("tilt_prev: " << position_prev_t);
                ROS_INFO_STREAM("Subtracted: " <<abs(pos[1]-position_prev_t));
                facedetect_pub.publish(ms);
                ROS_WARN_STREAM("OUT of if");

        }

    }

    void ImageConverter::chatterCallback(const sensor_msgs::JointState::ConstPtr& msg)
       {    
         position_prev_p = (msg->position[0]);
         position_prev_t = (msg->position[1]);
       }

facedetect.h - detectAndDisplay

Rect detectAndDisplay( Mat frame )
{
        vector<Rect> faces(1);
        Point center_of_frame(frame.size().width/2,frame.size().height/2);
        pair<Point, Point> corners;
        pair<double,double> displacement;
        double displacement_pixel_x;
        double displacement_pixel_y;
        bool foundFace = false;
        pair<Rect, bool> response;
                if (frame.type()!= 8) {
                        cvtColor(frame, frame, CV_8U);
                }

        //-- 1. Load the cascades
                if( !face_cascade.load( face_cascade_XML ) ){
                        cout << "Cascade Error" << endl;
                };

                circle(frame, center_of_frame, 1, CV_RGB(0,255,255),8,8,0);

        //-- Detect faces
                face_cascade.detectMultiScale( frame, faces, 1.1 ...
(more)
edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
0

answered 2015-04-01 10:18:21 -0500

215 gravatar image

I choose to remove the waitKey(1) != 'y' solution and use this one instead

http://answers.ros.org/question/63491/keyboard-key-pressed/

edit flag offensive delete link more
1

answered 2015-03-25 17:18:16 -0500

lucasw gravatar image

The waitKey only detects keypresses from an opencv highgui window in focus. Add an imshow of nothing at all or some interesting visualization, click on it and then you should be able to type.

http://docs.opencv.org/modules/highgu...

The function only works if there is at least one HighGUI window created and the window is active. If there are several HighGUI windows, any of them can be active.

edit flag offensive delete link more

Comments

detectAndDisplay() does open a imshow window.. i could try to open a empty outside of the function, if thats what you are referring to?

215 gravatar image 215  ( 2015-03-25 18:16:25 -0500 )edit
1

answered 2015-03-26 04:08:49 -0500

Malefitz gravatar image

updated 2015-03-26 04:11:47 -0500

You just wait for 10 miliseconds for a key input on every image.

if(waitKey(10) != 'y')
{
      face = detectAndDisplay(cv_ptr->image);
}

I don't think that's enough time for you to press the key in the right moment ;)

Wait some more to be able to press the right key, if that's not an option you may want to think about a design change (maybe put the image display in an extra thread).

Hope that helps.

edit flag offensive delete link more

Comments

We'll if i Increase the time, will make the image flow slower..

215 gravatar image 215  ( 2015-03-26 04:25:35 -0500 )edit

Well if that's the case as I said you probably have to put the code for showing the image and recognizing the key input into an extra thread.

Malefitz gravatar image Malefitz  ( 2015-03-26 04:28:13 -0500 )edit

How would you make multiple threads in ROS.. If my main keeps spinning my constructor.. ?

215 gravatar image 215  ( 2015-03-26 07:56:55 -0500 )edit

If you use a boost thread just for showing the image and listening to the key input it shouldn't interfer with ros. Something similar to this should work:

//ownThreadLoop()
while(1)
{
imshow(imgPtr)
if(waitkey(10) == 'y')
state = true
}

You may need a mutex for the image.

Malefitz gravatar image Malefitz  ( 2015-03-26 14:55:17 -0500 )edit

What about using a an extra node, which signals the first node?.. too much ?

215 gravatar image 215  ( 2015-03-31 21:04:50 -0500 )edit

That's a bit overkill. Did you try it the way I suggested and it didn't work? With boost threads?

Malefitz gravatar image Malefitz  ( 2015-04-01 02:08:54 -0500 )edit

Well.. it was more avoid using multiple threads and so on..

I am bit unsure on where you want it running, The image pointer is only accessible from within the class itself, so the only way i can do as you suggest is within the class, but as far as i Know multithreading within a class..

215 gravatar image 215  ( 2015-04-01 05:05:28 -0500 )edit

Added detectAndDisplay(Mat) function from the h. file facedetect.h.

To help you guys to understand the situation.. All support is appreciated :)

215 gravatar image 215  ( 2015-04-01 05:38:44 -0500 )edit

Question Tools

Stats

Asked: 2015-03-25 08:59:04 -0500

Seen: 3,413 times

Last updated: Apr 01 '15