00001
00007 #ifndef VSLAM_VIS_H_INCLUDED
00008 #define VSLAM_VIS_H_INCLUDED
00009
00010
00011 #include "utils.h"
00012 #include "pose_graph.h"
00013
00014
00016 void drawRaysOnEpipolarPlane(
00017 const Matrix3d & E,
00018 const ImageMatchVec & matches,
00019 cv::Mat & img1,
00020 cv::Mat & img2);
00021
00022
00023
00024
00025 namespace vslam{
00026
00034
00035
00036
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00075 template<class G> void edgeVisualization(const cv::Mat& img1, const cv::Mat& img2, G& graph,
00076 typename graph_traits<G>::vertex_descriptor vd1,
00077 typename graph_traits<G>::vertex_descriptor vd2){
00078 cv::Mat image1, image2;
00079 image1=img1.clone();
00080 image2=img2.clone();
00081 SE3 computedT = get(edge_transform, graph, edge(vd1, vd2, graph).first);
00082 drawMatchedNodeKeypoints(image1, vd1, vd2, graph, image1);
00083 drawMatchedNodeKeypoints(image2, vd2, vd1, graph, image2);
00084 ImageMatchVec matches = computeMatches(vd1, vd2, graph);
00085 drawRaysOnEpipolarPlane(sE3ToE(computedT), matches, image1, image2);
00086 cv::imwrite(seqencedName(get(vertex_seq, graph, vd1), "epilines.jpg"), image1);
00087 cv::imwrite(seqencedName(get(vertex_seq, graph, vd2), "epilines.jpg"), image2);
00088 }
00089
00090
00091
00092
00093
00094 template<class G> void drawNodeKeypoints( typename graph_traits<G>::vertex_descriptor vd,
00095 const G& g, const cv::Mat& image, cv::Mat& out_image){
00096 cv::drawKeypoints(image, get(vertex_kp, g, vd), out_image, cv::Scalar(0,255,0));
00097 }
00098
00099
00106 template<class G> void drawMatchedNodeKeypoints(
00107 const cv::Mat& image,
00108 typename graph_traits<G>::vertex_descriptor vd_img,
00109 typename graph_traits<G>::vertex_descriptor matched_vd,
00110 const G& g,
00111 cv::Mat out_image){
00112 const vector<cv::KeyPoint>& kpts = get(vertex_kp, g, vd_img);
00113 list<int> mkp_idxs = transformF<int>(
00114 mapToList(get(edge_kp_idx_map,g,edge(vd_img, matched_vd, g).first)),
00115 getFirst);
00116 list<int> mkp_inv_idxs= inverse_idxs(mkp_idxs, makeSeq(0, (int)kpts.size() - 1, 1));
00117 vector<cv::KeyPoint> mkpts = switchCont<vector>(transformF<cv::KeyPoint>(
00118 getByIdx(indexBy(makeSeq(0, (int)kpts.size() - 1, 1), kpts), mkp_idxs),
00119 getSecond));
00120 vector<cv::KeyPoint> nkpts = switchCont<vector>(transformF<cv::KeyPoint>(
00121 getByIdx(indexBy(makeSeq(0, (int)kpts.size() - 1, 1), kpts), mkp_inv_idxs),
00122 getSecond));
00123
00124 cv::drawKeypoints(image, mkpts, out_image, cv::Scalar(0,255,0));
00125
00126 cv::drawKeypoints(image, nkpts, out_image, cv::Scalar(150,150,150));
00127
00128 }
00129
00130 template<class G>
00131 void drawMatches(const cv::Mat & srci, typename graph_traits<G>::vertex_descriptor srcv,
00132 const cv::Mat & desti, typename graph_traits<G>::vertex_descriptor destv, const G& g){
00133 cv::Mat imageMatches;
00134
00135 vector<cv::DMatch> dmatches;
00136 const map<int, int> & src_dst_map = get(edge_kp_idx_map, g, edge(srcv, destv, g).first);
00137 std::transform(src_dst_map.begin(), src_dst_map.end(), back_inserter(dmatches), dmatchFromPair);
00138
00139 cv::drawMatches(
00140 srci, get(vertex_kp, g, srcv),
00141 desti, get(vertex_kp, g, destv),
00142 dmatches,
00143 imageMatches,
00144 cv::Scalar(255,255,255));
00145 std::ostringstream s;
00146 s << get(vertex_seq, g, srcv) << "to" << get(vertex_seq, g, destv) << "_" << "matches.jpg";
00147 cv::imwrite(s.str(), imageMatches);
00148 }
00149
00150 template<class G>
00151 void drawMatches2(cv::Mat & srci, typename graph_traits<G>::vertex_descriptor srcv,
00152 cv::Mat & desti, typename graph_traits<G>::vertex_descriptor destv, const G& g){
00153
00154 vector<cv::DMatch> dmatches;
00155 const map<int, int> & src_dst_map = get(edge_kp_idx_map, g, edge(srcv, destv, g).first);
00156 std::transform(src_dst_map.begin(), src_dst_map.end(), back_inserter(dmatches), dmatchFromPair);
00157
00158 typename property_map<G, vertex_kp_t>::const_type vkpmap = get(vertex_kp, g);
00159
00160 for(size_t i=0; i<dmatches.size(); i++){
00161 cv::Point2d pt1 = vkpmap[srcv][dmatches[i].queryIdx].pt;
00162 cv::Point2d pt2 = vkpmap[destv][dmatches[i].trainIdx].pt;
00163 cv::line(srci, pt1, pt2, CV_RGB(0,0,255), 1, 4);
00164 cv::line(desti, pt1, pt2, CV_RGB(0,0,255), 1, 4);
00165 }
00166 }
00167
00168 template<class G>
00169 void drawMatches3(cv::Mat & srci, typename graph_traits<G>::vertex_descriptor srcv,
00170 cv::Mat & desti, typename graph_traits<G>::vertex_descriptor destv, const G& g,
00171 const Points<G>& points){
00172
00173 vector<cv::DMatch> dmatches;
00174 const map<int, int> & src_dst_map = get(edge_kp_idx_map, g, edge(srcv, destv, g).first);
00175 std::transform(src_dst_map.begin(), src_dst_map.end(), back_inserter(dmatches), dmatchFromPair);
00176
00177 typename property_map<G, vertex_kp_t>::const_type vkpmap = get(vertex_kp, g);
00178 typename property_map<G, vertex_fix_idx_t>::const_type vfixmap = get(vertex_fix_idx, g);
00179
00180 for(size_t i=0; i<dmatches.size(); i++){
00181 int v1idx = dmatches[i].queryIdx;
00182 int v2idx = dmatches[i].trainIdx;
00183 if(vfixmap[srcv][v1idx]!=BAD_INDEX && points.getPoint(vfixmap[srcv][v1idx]).initialized){
00184 if(vfixmap[destv][v2idx]!=BAD_INDEX && points.getPoint(vfixmap[destv][v2idx]).initialized){
00185 cv::Point2d pt1 = vkpmap[srcv][v1idx].pt;
00186 cv::Point2d pt2 = vkpmap[destv][v2idx].pt;
00187 cv::line(srci, pt1, pt2, CV_RGB(0,0,255), 1, 4);
00188 cv::line(desti, pt1, pt2, CV_RGB(0,0,255), 1, 4);
00189 }
00190 }
00191 }
00192 }
00193
00194
00195 inline void drawMyKpt(cv::Mat & image, cv::Point pt, cv::Scalar color){
00196 cv::circle(image,pt,3,cv::Scalar(255,255,255),1, CV_AA);
00197 cv::circle(image,pt,2,cv::Scalar(255,255,255),2, CV_AA);
00198 cv::circle(image,pt,2,color, 1, CV_AA);
00199 cv::circle(image,pt,1,color, 2, CV_AA);
00200 }
00201
00202
00203 template<class G>
00204 void drawLandmarkReprojections(
00205 cv::Mat & image,
00206 typename graph_traits<G>::vertex_descriptor vd,
00207 const G& g,
00208 const Points<G>& points){
00209 typedef std::vector<cv::KeyPoint> TKP;
00210 typedef std::vector<int> TIDX;
00211 const TKP& kpts = get(vertex_kp, g, vd);
00212 const TIDX& landmark_indexes = get(vertex_fix_idx, g, vd);
00213
00214 TKP::const_iterator kp_it = kpts.begin();
00215 TIDX::const_iterator li_it = landmark_indexes.begin();
00216 while(kp_it != kpts.end()){
00217 assert(li_it!=landmark_indexes.end());
00218 if(*li_it!=BAD_INDEX){
00219 Point<G> pt = points.getPoint(*li_it);
00220 if(pt.initialized){
00221 drawMyKpt(image, kp_it->pt, cv::Scalar(255,255,255));
00222 const SE3& T_wc = get(vertex_transform, g, vd);
00223 Vector2d reproj_pt0 = PanoImCoord::fromHomogenous(T_wc*pt.global).getPixel();
00224 cv::Point reproj_pt(reproj_pt0(0), reproj_pt0(1));
00225
00226 cv::line(image, kp_it->pt, reproj_pt,cv::Scalar(255, 255, 255), 2, CV_AA);
00227 cv::line(image, kp_it->pt, reproj_pt,cv::Scalar(0, 0, 0), 1, CV_AA);
00228 } else{
00229 drawMyKpt(image, kp_it->pt, cv::Scalar(255,0,0));
00230 }
00231 }
00232 kp_it++; li_it++;
00233 }
00234 }
00236 }
00237 #endif