5252#include < dynamic_reconfigure/server.h>
5353#include " opencv_apps/MatchTemplateConfig.h"
5454#include " opencv_apps/RectArrayStamped.h"
55+ #include < std_msgs/Float64.h>
5556
5657namespace match_template
5758{
@@ -61,7 +62,8 @@ namespace match_template
6162 image_transport::Publisher matched_img_pub_;
6263 image_transport::Subscriber img_sub_;
6364 image_transport::CameraSubscriber cam_sub_;
64- ros::Publisher msg_pub_;
65+ ros::Publisher matched_val_pub_;
66+ ros::Publisher matched_rect_pub_;
6567
6668 boost::shared_ptr < image_transport::ImageTransport > it_;
6769
@@ -72,16 +74,24 @@ namespace match_template
7274
7375 bool debug_view_;
7476 int match_method_;
77+ #if (CV_MAJOR_VERSION >= 3 && CV_MINOR_VERSION >= 2) // mask is only supported since opencv 3.2 (https://github.com/opencv/opencv/pull/3554)
7578 bool use_mask_;
79+ #endif
7680
7781 ros::Time prev_stamp_;
7882
7983 cv::Mat templ_;
84+ #if (CV_MAJOR_VERSION >= 3 && CV_MINOR_VERSION >= 2)
8085 cv::Mat mask_;
86+ #endif
8187
8288 void reconfigureCallback (Config & new_config, uint32_t level)
8389 {
8490 config_ = new_config;
91+ if ( match_method_ != config_.match_method ) {
92+ match_method_ = config_.match_method ;
93+ NODELET_WARN_STREAM (" Change Mathing Method to " << match_method_);
94+ }
8595 }
8696
8797 const std::string & frameWithDefault (const std::string & frame, const std::string & image_frame)
@@ -118,32 +128,25 @@ namespace match_template
118128 int result_rows = frame.rows - templ_.rows + 1 ;
119129 cv::Mat result (result_rows, result_cols, CV_32FC1);
120130
121- // -- Show template
122- if (debug_view_)
123- {
124- cv::imshow (" Template" , templ_);
125- int c = cv::waitKey (1 );
126- }
127-
128131 // ! [match_template]
129132 // / Do the Matching and Normalize
130133 bool method_accepts_mask = (match_method_ == CV_TM_SQDIFF || match_method_ == CV_TM_CCORR_NORMED);
134+ #if (CV_MAJOR_VERSION >= 3 && CV_MINOR_VERSION >= 2)
131135 if (use_mask_ && method_accepts_mask)
132136 {
133137 matchTemplate (frame, templ_, result, match_method_, mask_);
134138 }
135139 else
140+ #endif
136141 {
137142 matchTemplate (frame, templ_, result, match_method_);
138143 }
139- // ! [normalize]
140- // normalize (result, result, 0, 255, cv::NORM_MINMAX, CV_8UC1, cv::Mat ());
141- normalize (result, result, 0 , 255 , cv::NORM_MINMAX, CV_8UC1, cv::Mat ());
142144
143145 // ! [best_match]
144146 // / Localizing the best match with minMaxLoc
145147 double minVal;
146148 double maxVal;
149+ double matchVal;
147150 cv::Point minLoc;
148151 cv::Point maxLoc;
149152 cv::Point matchLoc;
@@ -154,23 +157,57 @@ namespace match_template
154157 if (match_method_ == CV_TM_SQDIFF || match_method_ == CV_TM_SQDIFF_NORMED || match_method_ == CV_TM_CCORR)
155158 {
156159 matchLoc = minLoc;
160+ matchVal = minVal;
157161 }
158162 else
159163 {
160164 matchLoc = maxLoc;
165+ matchVal = maxVal;
161166 }
167+ NODELET_DEBUG_STREAM (std::fixed << std::setw (12 ) << minVal << " " << maxVal << " min " << matchVal);
168+
169+ // ! [normalize] for visualization
170+ normalize (result, result, 0 , 255 , cv::NORM_MINMAX, CV_8UC1, cv::Mat ());
171+
162172 rectangle (frame, matchLoc, cv::Point (matchLoc.x + templ_.cols , matchLoc.y + templ_.rows ), cv::Scalar::all (0 ),
163173 2 , 8 , 0 );
164- rectangle (result, matchLoc, cv::Point (matchLoc.x + templ_.cols , matchLoc.y + templ_.rows ),
174+ std::stringstream ss;
175+ ss << std::fixed << std::setw (12 ) << std::setprecision (0 ) << matchVal;
176+ cv::putText (frame, ss.str (), cv::Point (0 ,20 ), cv::FONT_HERSHEY_PLAIN, 1.5 , cv::Scalar (255.0 , 255.0 , 255.0 ), 1 , CV_AA);
177+ rectangle (result, cv::Point (matchLoc.x - templ_.cols /2 , matchLoc.y - templ_.rows /2 ), cv::Point (matchLoc.x + templ_.cols /2 , matchLoc.y + templ_.rows /2 ),
165178 cv::Scalar::all (0 ), 2 , 8 , 0 );
166179
180+ // -- Show template and result
181+ if (debug_view_)
182+ {
183+ cv::imshow (" Template" , templ_);
184+ cv::imshow (" Soure Image" , frame);
185+ cv::imshow (" Result window" , result);
186+ int c = cv::waitKey (1 );
187+ }
188+
167189 // Publish the image.
168190 sensor_msgs::Image::Ptr out_img =
169191 cv_bridge::CvImage (msg->header , sensor_msgs::image_encodings::BGR8, frame).toImageMsg ();
170192 sensor_msgs::Image::Ptr match_img =
171193 cv_bridge::CvImage (msg->header , sensor_msgs::image_encodings::MONO8, result).toImageMsg ();
172194 img_pub_.publish (out_img);
173195 matched_img_pub_.publish (match_img);
196+
197+ // Publish the result.
198+ opencv_apps::RectArrayStamped matched_rect_msg;
199+ matched_rect_msg.header = msg->header ;
200+ opencv_apps::Rect rect_msg;
201+ rect_msg.x = matchLoc.x ;
202+ rect_msg.y = matchLoc.y ;
203+ rect_msg.width = templ_.cols ;
204+ rect_msg.height = templ_.rows ;
205+ matched_rect_msg.rects .push_back (rect_msg);
206+ matched_rect_pub_.publish (matched_rect_msg);
207+
208+ std_msgs::Float64 matched_val_msg;
209+ matched_val_msg.data = matchVal;
210+ matched_val_pub_.publish (matched_val_msg);
174211 }
175212 catch (cv::Exception & e)
176213 {
@@ -204,34 +241,35 @@ namespace match_template
204241
205242 pnh_->param (" debug_view" , debug_view_, false );
206243 pnh_->param (" match_method" , match_method_, (int ) CV_TM_SQDIFF);
244+ #if (CV_MAJOR_VERSION >= 3 && CV_MINOR_VERSION >= 2)
207245 pnh_->param (" use_mask" , use_mask_, false );
208- std::string templ_file, mask_file;
246+ #endif
247+ std::string templ_file;
209248 pnh_->param (" template_file" , templ_file, std::string (" template.png" ));
249+ #if (CV_MAJOR_VERSION >= 3 && CV_MINOR_VERSION >= 2)
250+ std::string mask_file;
210251 pnh_->param (" mask_file" , mask_file, std::string (" mask.png" ));
252+ #endif
211253
212254 NODELET_INFO (" template_file: %s" , templ_file.c_str ());
213255
214256 if (debug_view_)
215257 {
216258 always_subscribe_ = true ;
217259 }
260+ #if (CV_MAJOR_VERSION >= 3 && CV_MINOR_VERSION >= 2)
218261 if (use_mask_)
219262 {
220263 mask_ = imread (mask_file, cv::IMREAD_COLOR);
221264 }
222- if (templ_file.empty ())
223- {
224- NODELET_ERROR (" Cannot open template file %s" , templ_file.c_str ());
225- exit (0 );
226- }
227- // templ_ = imread(templ_file, cv::IMREAD_COLOR);
265+ #endif
228266 templ_ = imread (templ_file, cv::IMREAD_COLOR);
229-
230- if (debug_view_)
267+ if (!templ_.data )
231268 {
232- cv::imshow (" Match Template " , templ_ );
233- int c = cv::waitKey ( 1 );
269+ NODELET_ERROR (" Cannot open template file (%s) " , templ_file. c_str () );
270+ exit (- 1 );
234271 }
272+
235273 prev_stamp_ = ros::Time (0 , 0 );
236274
237275 reconfigure_server_ = boost::make_shared < dynamic_reconfigure::Server < Config > >(*pnh_);
@@ -241,7 +279,8 @@ namespace match_template
241279
242280 img_pub_ = advertiseImage (*pnh_, " image" , 1 );
243281 matched_img_pub_ = advertiseImage (*pnh_, " matched_image" , 1 );
244- msg_pub_ = advertise < opencv_apps::RectArrayStamped > (*pnh_, " matched_rectangle" , 1 );
282+ matched_val_pub_ = advertise< std_msgs::Float64 > (*pnh_, " matched_value" , 1 );
283+ matched_rect_pub_ = advertise < opencv_apps::RectArrayStamped > (*pnh_, " matched_rectangle" , 1 );
245284
246285 onInitPostProcess ();
247286 }
0 commit comments