Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <ucl_drone/computer_vision/computer_vision.h>
00014
00015 int ProcessedImage::last_number_of_keypoints = 0;
00016
00017
00018 ProcessedImage::ProcessedImage()
00019 {
00020 ucl_drone::ProcessedImageMsg::Ptr msg(new ucl_drone::ProcessedImageMsg());
00021 }
00022
00023
00024
00025
00026
00027
00028 ProcessedImage::ProcessedImage(const sensor_msgs::Image msg, const ucl_drone::Pose3D pose_,
00029 ProcessedImage& prev, bool use_OpticalFlowPyrLK)
00030 {
00031 ROS_DEBUG("ProcessedImage::init");
00032 this->pose = pose_;
00033
00034
00035 try
00036 {
00037 this->cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
00038
00039
00040 }
00041 catch (cv_bridge::Exception& e)
00042 {
00043 ROS_ERROR("ucl_drone::imgproc::cv_bridge exception: %s", e.what());
00044 return;
00045 }
00046
00047
00048 cv::Size size(Read::img_width(), Read::img_height());
00049 cv::resize(this->cv_ptr->image, this->cv_ptr->image, size);
00050
00051
00052 this->cv_ptr->toImageMsg(this->image);
00053
00054
00055 if (use_OpticalFlowPyrLK && prev.cv_ptr && prev.keypoints.size() > 0 &&
00056 ProcessedImage::last_number_of_keypoints != 0)
00057
00058
00059 {
00060 ROS_DEBUG("use_OpticalFlowPyrLK");
00061 TIC(optical_flow);
00062 bool OF_success = false;
00063
00064
00065 cv::Mat prevgray, gray;
00066 if (this->cv_ptr->image.channels() == 3)
00067 {
00068 cv::cvtColor(this->cv_ptr->image, gray, CV_RGB2GRAY);
00069 cv::cvtColor(prev.cv_ptr->image, prevgray, CV_RGB2GRAY);
00070 }
00071 else
00072 {
00073 prevgray = prev.cv_ptr->image;
00074 gray = this->cv_ptr->image;
00075 }
00076
00077
00078 std::vector< uchar > vstatus(prev.keypoints.size());
00079 std::vector< float > verror(prev.keypoints.size());
00080
00081 std::vector< cv::Point2f > found;
00082 std::vector< cv::Point2f > to_find = Points(prev.keypoints);
00083
00084
00085 cv::calcOpticalFlowPyrLK(prevgray, gray, to_find, found, vstatus, verror);
00086
00087
00088 double thres = 12.0;
00089
00090 for (int i = 0; i < prev.keypoints.size(); i++)
00091 {
00092 if (vstatus[i] && verror[i] < thres)
00093 {
00094 cv::KeyPoint newKeyPoint = prev.keypoints[i];
00095 newKeyPoint.pt.x = found[i].x;
00096 newKeyPoint.pt.y = found[i].y;
00097 this->keypoints.push_back(newKeyPoint);
00098 }
00099 }
00100
00101
00102 OF_success = this->keypoints.size() > ProcessedImage::last_number_of_keypoints * 0.75 &&
00103 this->keypoints.size() > 80;
00104 TOC(optical_flow, "optical flow tracking");
00105
00106 if (OF_success)
00107 {
00108 this->descriptors = cv::Mat::zeros(this->keypoints.size(), DESCRIPTOR_SIZE, CV_32F);
00109 for (int i = 0, j = 0; i < prev.keypoints.size(); i++)
00110 {
00111 if (vstatus[i] && verror[i] < thres)
00112 {
00113 for (unsigned k = 0; k < DESCRIPTOR_SIZE; k++)
00114 {
00115 this->descriptors.at< float >(j, k) = prev.descriptors.at< float >(i, k);
00116 }
00117 j++;
00118 }
00119 }
00120
00121 return;
00122 }
00123 else
00124 {
00125 this->keypoints.clear();
00126 }
00127 }
00128
00129 ROS_DEBUG("=== OPTICAL FLOW NOT SUCCESS ===");
00130
00131
00132 TIC(detect);
00133 detector.detect(this->cv_ptr->image, this->keypoints);
00134 TOC(detect, "detect keypoints");
00135 ROS_DEBUG("ProcessedImage::init this->keypoints.size()=%d", this->keypoints.size());
00136 ProcessedImage::last_number_of_keypoints = this->keypoints.size();
00137 if (this->keypoints.size() == 0)
00138 {
00139 return;
00140 }
00141 TIC(extract);
00142
00143 extractor.compute(this->cv_ptr->image, this->keypoints, this->descriptors);
00144 TOC(extract, "descriptor extrator");
00145 ROS_DEBUG("end ProcessedImage::init");
00146 }
00147
00148 ProcessedImage::~ProcessedImage()
00149 {
00150 }
00151
00152
00153
00154
00155 void ProcessedImage::convertToMsg(ucl_drone::ProcessedImageMsg::Ptr& msg, Target target)
00156 {
00157 msg->pose = this->pose;
00158 msg->image = this->image;
00159
00160 if (this->keypoints.size() == 0)
00161 {
00162 return;
00163 }
00164
00165 TIC(target);
00166
00167 std::vector< cv::DMatch > good_matches;
00168 std::vector< int > idxs_to_remove;
00169 std::vector< cv::Point2f > target_coord;
00170
00171 bool target_is_detected =
00172 target.detect(this->descriptors, this->keypoints, good_matches, idxs_to_remove, target_coord
00173 #ifdef DEBUG_PROJECTION
00174 ,
00175 this->pose
00176 #endif
00177 #ifdef DEBUG_TARGET
00178 ,
00179 this->cv_ptr->image
00180 #endif
00181 );
00182
00183 if (target_is_detected)
00184 {
00185 ROS_DEBUG("TARGET IS DETECTED");
00186 msg->target_detected = true;
00187
00188 msg->target_points.resize(5);
00189 for (int i = 0; i < 5; i++)
00190 {
00191 msg->target_points[i].x = target_coord[i].x;
00192 msg->target_points[i].y = target_coord[i].y;
00193 msg->target_points[i].z = 0;
00194 }
00195 }
00196 else
00197 {
00198 msg->target_detected = false;
00199 }
00200
00201 if (this->keypoints.size() - idxs_to_remove.size() <= 0)
00202 {
00203
00204 return;
00205 }
00206
00207
00208 msg->keypoints.resize(this->keypoints.size() - idxs_to_remove.size());
00209 ROS_DEBUG("ProcessedImage::init msg->keypoints.size()=%d", msg->keypoints.size());
00210 int count = 0;
00211 int j = 0;
00212 for (unsigned i = 0; i < this->keypoints.size() && j < msg->keypoints.size() &&
00213 (count < idxs_to_remove.size() || idxs_to_remove.size() == 0);
00214 i++)
00215 {
00216
00217 if (idxs_to_remove.size() == 0 || i != idxs_to_remove[count])
00218 {
00219
00220 ucl_drone::KeyPoint keypoint;
00221 geometry_msgs::Point point;
00222 point.x = (double)this->keypoints[i].pt.x;
00223 point.y = (double)this->keypoints[i].pt.y;
00224
00225 keypoint.point = point;
00226
00227
00228 std::vector< float > descriptor;
00229 descriptor.resize(DESCRIPTOR_SIZE);
00230 for (unsigned k = 0; k < DESCRIPTOR_SIZE; k++)
00231 {
00232 descriptor[k] = this->descriptors.at< float >(i, k);
00233 }
00234 keypoint.descriptor = descriptor;
00235
00236 msg->keypoints[j] = keypoint;
00237 j++;
00238 }
00239 if (idxs_to_remove.size() != 0 && i == idxs_to_remove[count])
00240 {
00241
00242 if (count < idxs_to_remove.size() - 1)
00243 {
00244 count++;
00245 }
00246 }
00247 }
00248 TOC(target, "detect and remove target");
00249 ROS_DEBUG("=========== POINT (%f;%f)", msg->keypoints[msg->keypoints.size() - 1].point.x,
00250 msg->keypoints[msg->keypoints.size() - 1].point.y);
00251 }