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$
    – abhishek47
    Commented Mar 9, 2021 at 6:32
  • $\begingroup$ How do we change the origin? $\endgroup$
    – skpro19
    Commented Mar 9, 2021 at 8:28

1 Answer 1


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
    Commented Mar 9, 2021 at 12:37
  • $\begingroup$ Thanks! I have edited my answer to include the code snippet $\endgroup$ Commented Mar 9, 2021 at 16:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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