text: # Input: a bunch of files with prefix "{X}_{scene_id}_{row}_{col}"
  # (e.g., those generated by visualize_labels.py or visualize_outputs.py).
  # Output: crop of another scene that overlaps that chip.
  
  import json
  import numpy
  import os, os.path
  import rasterio
  import skimage.io, skimage.transform
  import sys
  
  in_path = sys.argv[1]
  scene_path = sys.argv[2]
  chip_path = sys.argv[3]
  
  chip_size = 800
  
  # Get bounds and CRS for each scene.
  # Also get chip offsets.
  scene_info = {}
  for scene_id in os.listdir(scene_path):
      im = rasterio.open(os.path.join(scene_path, scene_id, 'VH_dB.tif'))
      with open(os.path.join(chip_path, scene_id, 'coords.json'), 'r') as f:
          chip_offsets = json.load(f)['offsets']
      scene_info[scene_id] = {
          'crs': im.crs,
          'bounds': [
              int(im.bounds.left/10),
              int(-im.bounds.top/10),
              int(im.bounds.right/10),
              int(-im.bounds.bottom/10),
          ],
          'chip_offsets': chip_offsets,
      }
  
  def get_chip_bounds(im_bounds, chip_col, chip_row):
      left = im_bounds[0] + chip_col
      top = im_bounds[1] + chip_row
      return [left, top, left + chip_size, top + chip_size]
  
  def intersects(bounds1, bounds2):
      return bounds1[2] > bounds2[0] and bounds1[3] > bounds2[1] and bounds1[0] < bounds2[2] and bounds1[1] < bounds2[3]
  
  for fname in os.listdir(in_path):
      # Extract details from filename.
      parts = fname.split('.png')[0].split('_')
      file_scene_id = parts[1]
      file_chip_row = int(parts[2])
      file_chip_col = int(parts[3])
  
      # Get bounds of this chip.
      file_info = scene_info[file_scene_id]
      file_chip_bounds = get_chip_bounds(file_info['bounds'], file_chip_col, file_chip_row)
  
      success = False
  
      # Find a scene that fully contains this chip.
      for other_scene_id, other_info in scene_info.items():
          if other_scene_id == file_scene_id:
              continue
          if other_info['crs'] != file_info['crs']:
              continue
          if file_chip_bounds[0] < other_info['bounds'][0]:
              continue
          if file_chip_bounds[1] < other_info['bounds'][1]:
              continue
          if file_chip_bounds[2] > other_info['bounds'][2]:
              continue
          if file_chip_bounds[3] > other_info['bounds'][3]:
              continue
  
          # Create the image by combining chips.
          im = numpy.zeros((chip_size, chip_size), dtype='uint8')
          bad = False
  
          for chip_idx, (chip_col, chip_row) in enumerate(other_info['chip_offsets']):
              chip_bounds = get_chip_bounds(other_info['bounds'], chip_col, chip_row)
              if not intersects(file_chip_bounds, chip_bounds):
                  continue
  
              col_overlap = chip_size - abs(chip_bounds[0]-file_chip_bounds[0])
              row_overlap = chip_size - abs(chip_bounds[1]-file_chip_bounds[1])
              src_col_offset = max(file_chip_bounds[0]-chip_bounds[0], 0)
              src_row_offset = max(file_chip_bounds[1]-chip_bounds[1], 0)
              dst_col_offset = max(chip_bounds[0]-file_chip_bounds[0], 0)
              dst_row_offset = max(chip_bounds[1]-file_chip_bounds[1], 0)
  
              vh = numpy.load(os.path.join(chip_path, other_scene_id, 'vh/{}_vh.npy'.format(chip_idx)))
              if vh.min() < -30000:
                  bad = True
                  break
  
              vh = numpy.clip((vh+50)*(255/55), 0, 255).astype('uint8')
              im[dst_row_offset:dst_row_offset+row_overlap, dst_col_offset:dst_col_offset+col_overlap] = vh[src_row_offset:src_row_offset+row_overlap, src_col_offset:src_col_offset+col_overlap]
  
          if bad:
              continue
  
          im = numpy.stack([im]*3, axis=2)
          skimage.io.imsave(os.path.join(in_path, fname.replace('.png', '-2.png')), im)
  
          success = True
          break
  
      if not success:
          print('failed to find an overlapping image for {}'.format(fname))
          continue
  