$search
00001 /* 00002 * Copyright (c) 2008, Willow Garage, Inc. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * * Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * * Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * * Neither the name of the Willow Garage, Inc. nor the names of its 00014 * contributors may be used to endorse or promote products derived from 00015 * this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00018 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00021 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00022 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00023 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00025 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00026 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00027 * POSSIBILITY OF SUCH DAMAGE. 00028 */ 00029 00030 /* 00031 * This file contains helper functions for loading images as maps. 00032 * 00033 * Author: Brian Gerkey 00034 */ 00035 00036 #include <cstring> 00037 #include <stdexcept> 00038 00039 #include <stdlib.h> 00040 #include <stdio.h> 00041 00042 // We use SDL_image to load the image from disk 00043 #include <SDL/SDL_image.h> 00044 00045 #include "map_server/image_loader.h" 00046 #include "LinearMath/btMatrix3x3.h" 00047 00048 // compute linear index for given map coords 00049 #define MAP_IDX(sx, i, j) ((sx) * (j) + (i)) 00050 00051 namespace map_server 00052 { 00053 00054 void 00055 loadMapFromFile(nav_msgs::GetMap::Response* resp, 00056 const char* fname, double res, bool negate, 00057 double occ_th, double free_th, double* origin) 00058 { 00059 SDL_Surface* img; 00060 00061 unsigned char* pixels; 00062 unsigned char* p; 00063 int rowstride, n_channels; 00064 unsigned int i,j; 00065 int k; 00066 double occ; 00067 int color_sum; 00068 double color_avg; 00069 00070 // Load the image using SDL. If we get NULL back, the image load failed. 00071 if(!(img = IMG_Load(fname))) 00072 { 00073 std::string errmsg = std::string("failed to open image file \"") + 00074 std::string(fname) + std::string("\""); 00075 throw std::runtime_error(errmsg); 00076 } 00077 00078 // Copy the image data into the map structure 00079 resp->map.info.width = img->w; 00080 resp->map.info.height = img->h; 00081 resp->map.info.resolution = res; 00082 resp->map.info.origin.position.x = *(origin); 00083 resp->map.info.origin.position.y = *(origin+1); 00084 resp->map.info.origin.position.z = 0.0; 00085 btQuaternion q; 00086 q.setRPY(0,0, *(origin+2)); 00087 resp->map.info.origin.orientation.x = q.x(); 00088 resp->map.info.origin.orientation.y = q.y(); 00089 resp->map.info.origin.orientation.z = q.z(); 00090 resp->map.info.origin.orientation.w = q.w(); 00091 00092 // Allocate space to hold the data 00093 resp->map.data.resize(resp->map.info.width * resp->map.info.height); 00094 00095 // Get values that we'll need to iterate through the pixels 00096 rowstride = img->pitch; 00097 n_channels = img->format->BytesPerPixel; 00098 00099 // Copy pixel data into the map structure 00100 pixels = (unsigned char*)(img->pixels); 00101 for(j = 0; j < resp->map.info.height; j++) 00102 { 00103 for (i = 0; i < resp->map.info.width; i++) 00104 { 00105 // Compute mean of RGB for this pixel 00106 p = pixels + j*rowstride + i*n_channels; 00107 color_sum = 0; 00108 for(k=0;k<n_channels;k++) 00109 color_sum += *(p + (k)); 00110 color_avg = color_sum / (double)n_channels; 00111 00112 // If negate is true, we consider blacker pixels free, and whiter 00113 // pixels free. Otherwise, it's vice versa. 00114 if(negate) 00115 occ = color_avg / 255.0; 00116 else 00117 occ = (255 - color_avg) / 255.0; 00118 00119 // Apply thresholds to RGB means to determine occupancy values for 00120 // map. Note that we invert the graphics-ordering of the pixels to 00121 // produce a map with cell (0,0) in the lower-left corner. 00122 if(occ > occ_th) 00123 resp->map.data[MAP_IDX(resp->map.info.width,i,resp->map.info.height - j - 1)] = +100; 00124 else if(occ < free_th) 00125 resp->map.data[MAP_IDX(resp->map.info.width,i,resp->map.info.height - j - 1)] = 0; 00126 else 00127 resp->map.data[MAP_IDX(resp->map.info.width,i,resp->map.info.height - j - 1)] = -1; 00128 } 00129 } 00130 00131 SDL_FreeSurface(img); 00132 } 00133 00134 }