Go to the documentation of this file.00001 #include "motion_detection.h"
00002
00003 MotionDetection::MotionDetection()
00004 {
00005 ros::NodeHandle n;
00006 ros::NodeHandle p_n("~");
00007
00008 img_prev_ptr_.reset();
00009 img_current_ptr_.reset();
00010
00011 image_transport::ImageTransport it(n);
00012 image_transport::ImageTransport image_motion_it(p_n);
00013 image_transport::ImageTransport image_detected_it(p_n);
00014
00015
00016
00017 image_sub_ = it.subscribe("opstation/rgb/image_color", 1 , &MotionDetection::imageCallback, this);
00018
00019 dyn_rec_server_.setCallback(boost::bind(&MotionDetection::dynRecParamCallback, this, _1, _2));
00020
00021 image_percept_pub_ = n.advertise<hector_worldmodel_msgs::ImagePercept>("image_percept", 20);
00022 image_motion_pub_ = image_motion_it.advertiseCamera("image_motion", 10);
00023 image_detected_pub_ = image_detected_it.advertiseCamera("image_detected", 10);
00024 }
00025
00026 MotionDetection::~MotionDetection() {}
00027
00028 void MotionDetection::imageCallback(const sensor_msgs::ImageConstPtr& img)
00029 {
00030
00031 cv_bridge::CvImageConstPtr img_next_ptr(cv_bridge::toCvShare(img, sensor_msgs::image_encodings::MONO8));
00032
00033 if (img_prev_ptr_)
00034 {
00035
00036
00037 cv::Mat diff1;
00038 cv::Mat diff2;
00039 cv::Mat img_motion;
00040 cv::absdiff(img_prev_ptr_->image, img_next_ptr->image, diff1);
00041 cv::absdiff(img_current_ptr_->image, img_next_ptr->image, diff2);
00042 cv::bitwise_and(diff1, diff2, img_motion);
00043 cv::threshold(img_motion, img_motion, motion_detect_threshold_, 255, CV_THRESH_BINARY);
00044 cv::Mat kernel_ero = getStructuringElement(cv::MORPH_RECT, cv::Size(5,5));
00045 cv::erode(img_motion, img_motion, kernel_ero);
00046
00047 unsigned int number_of_changes = 0;
00048 int min_x = img_motion.cols, max_x = 0;
00049 int min_y = img_motion.rows, max_y = 0;
00050
00051 for(int j = 0; j < img_motion.rows; j++) {
00052 for(int i = 0; i < img_motion.cols; i++) {
00053
00054
00055
00056 if(static_cast<int>(img_motion.at<uchar>(j,i)) == 255) {
00057 number_of_changes++;
00058 if (min_x > i) min_x = i;
00059 if (max_x < i) max_x = i;
00060 if (min_y > j) min_y = j;
00061 if (max_y < j) max_y = j;
00062 }
00063 }
00064 }
00065
00066 cv::Mat img_detected;
00067 img_current_col_ptr_->image.copyTo(img_detected);
00068
00069 double percept_size = std::max(std::abs(max_x-min_x), std::abs(max_y-min_y));
00070 double area = std::abs(max_x-min_x) * std::abs(max_y-min_y);
00071 double density = area > 0.0 ? number_of_changes/area : 0.0;
00072
00073 if (number_of_changes && max_percept_size > percept_size && percept_size > min_percept_size && density > min_density)
00074 {
00075 cv::rectangle(img_detected, cv::Rect(cv::Point(min_x, min_y), cv::Point(max_x, max_y)), CV_RGB(255,0,0), 5);
00076 }
00077
00078
00079 sensor_msgs::CameraInfo::Ptr info;
00080 info.reset(new sensor_msgs::CameraInfo());
00081 info->header = img->header;
00082
00083 if(image_motion_pub_.getNumSubscribers() > 0)
00084 {
00085 cv_bridge::CvImage cvImg;
00086 img_motion.copyTo(cvImg.image);
00087 cvImg.header = img->header;
00088 cvImg.encoding = sensor_msgs::image_encodings::MONO8;
00089 image_motion_pub_.publish(cvImg.toImageMsg(), info);
00090 }
00091
00092 if(image_detected_pub_.getNumSubscribers() > 0)
00093 {
00094 cv_bridge::CvImage cvImg;
00095 img_detected.copyTo(cvImg.image);
00096 cvImg.header = img->header;
00097 cvImg.encoding = sensor_msgs::image_encodings::BGR8;
00098 image_detected_pub_.publish(cvImg.toImageMsg(), info);
00099 }
00100 }
00101
00102
00103 img_prev_ptr_= img_current_ptr_;
00104 img_current_ptr_ = img_next_ptr;
00105
00106 img_current_col_ptr_ = cv_bridge::toCvShare(img, sensor_msgs::image_encodings::BGR8);
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161 void MotionDetection::dynRecParamCallback(MotionDetectionConfig &config, uint32_t level)
00162 {
00163 motion_detect_threshold_ = config.motion_detect_threshold;
00164 min_percept_size = config.motion_detect_min_percept_size;
00165 max_percept_size = config.motion_detect_max_percept_size;
00166 min_density = config.motion_detect_min_density;
00167 percept_class_id_ = config.percept_class_id;
00168 }
00169
00170 int main(int argc, char **argv)
00171 {
00172
00173
00174
00175 ros::init(argc, argv, "motion_detection");
00176 MotionDetection md;
00177 ros::spin();
00178
00179
00180
00181 return 0;
00182 }
00183