I have mapped my Gazebo environment using the slam_gmapping node. On running map_server map_saver -f map_1.pgm, I am able to save the map to my local disk.

This is how the saved map looks - map_1.pgm

As we can see, there is a lot of grey space arond the map. How do I eliminate this? I need to do this because I intend to run some OpenCV algorithms over this map.

This is my map_1.yaml looks like -

image: map_1.pgm
resolution: 0.050000
origin: [-100.000000, -100.000000, 0.000000]
negate: 0
occupied_thresh: 0.65
free_thresh: 0.196
  • $\begingroup$ The documentation says the field origin in the yaml file is for "2-D pose of the lower-left pixel in the map". Does changing the origin reduce the surrounding grey space? $\endgroup$ – MorganStark47 Mar 9 at 6:32
  • $\begingroup$ How do we change the origin? $\endgroup$ – skpro19 Mar 9 at 8:28

Maybe you are looking to crop the occupancy grid. Map server provides some api's for cropping. This sample script from their documentation would shed some light

#!/usr/bin/env python

import sys
import yaml
from PIL import Image
import math

def find_bounds(map_image):
    x_min = map_image.size[0]
    x_end = 0
    y_min = map_image.size[1]
    y_end = 0
    pix = map_image.load()
    for x in range(map_image.size[0]):
        for y in range(map_image.size[1]):
            val = pix[x, y]
            if val != 205:  # not unknown
                x_min = min(x, x_min)
                x_end = max(x, x_end)
                y_min = min(y, y_min)
                y_end = max(y, y_end)
    return x_min, x_end, y_min, y_end

def computed_cropped_origin(map_image, bounds, resolution, origin):
00025     """ Compute the image for the cropped map when map_image is cropped by bounds and had origin  """
    ox = origin[0]
    oy = origin[1]
    oth = origin[2]

    # First figure out the delta we have to translate from the lower left corner (which is the origin)
    # in the image system
    dx = bounds[0] * resolution
    dy = (map_image.size[1] - bounds[3]) * resolution

    # Next rotate this by the theta and add to the old origin

    new_ox = ox + dx * math.cos(oth) - dy * math.sin(oth)
    new_oy = oy + dx * math.sin(oth) + dy * math.cos(oth)

    return [new_ox, new_oy, oth]

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print >> sys.stderr, "Usage: %s map.yaml [cropped.yaml]" % sys.argv[0]

    with open(sys.argv[1]) as f:
        map_data = yaml.safe_load(f)

    if len(sys.argv) > 2:
        crop_name = sys.argv[2]
        if crop_name.endswith(".yaml"):
            crop_name = crop_name[:-5]
        crop_yaml = crop_name + ".yaml"
        crop_image = crop_name + ".pgm"
        crop_yaml = "cropped.yaml"
        crop_image = "cropped.pgm"

    map_image_file = map_data["image"]
    resolution = map_data["resolution"]
    origin = map_data["origin"]

    map_image = Image.open(map_image_file)

    bounds = find_bounds(map_image)

    # left, upper, right, lower
    cropped_image = map_image.crop((bounds[0], bounds[2], bounds[1] + 1, bounds[3] + 1))

    map_data["image"] = crop_image
    map_data["origin"] = computed_cropped_origin(map_image, bounds, resolution, origin)
    with open(crop_yaml, "w") as f:
        yaml.dump(map_data, f)
  • 1
    $\begingroup$ Welcome to Robotics Akhil Kurup. Thanks for your answer but we prefer answers to be self contained where possible. Links tend to rot so answers which rely on a link can be rendered useless if the linked content disappears. If you add more context from the link, it is more likely that people will find your answer useful. See How to Answer for more info. $\endgroup$ – Ben Mar 9 at 12:37
  • $\begingroup$ Thanks! I have edited my answer to include the code snippet $\endgroup$ – Akhil Kurup Mar 9 at 16:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.