| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- #!/usr/bin/python
- # Analyze the rectangular bounding boxes in a greyscale bitmap to create
- # dungeon room pack configs.
- import argparse
- import cv2
- from dataclasses import dataclass
- SUBDIVISIONS = 128
- MIN_VALUE = 1
- MAX_VALUE = 256
- assert(MAX_VALUE % SUBDIVISIONS == 0)
- @dataclass
- class Box2:
- left: int
- bottom: int
- right: int
- top: int
- @dataclass
- class RoomPackBitmap:
- width: int
- height: int
- rooms: list
- def analyze_bitmap(fname, centered = False, offset_x = 0, offset_y = 0):
- image = cv2.imread(fname, cv2.IMREAD_GRAYSCALE)
- contours = []
- for i in range(0, 1 + SUBDIVISIONS):
- lower = MAX_VALUE / SUBDIVISIONS * (i - 1)
- upper = MAX_VALUE / SUBDIVISIONS * i - 1
- lower = max(MIN_VALUE, lower)
- upper = min(MAX_VALUE - 1, upper)
- image_slice = cv2.inRange(image, lower, upper)
- image_mask = cv2.threshold(image_slice, 0, 255, cv2.THRESH_TOZERO)[1]
- new_contours = cv2.findContours(image_mask, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
- if len(new_contours[0]) == 0:
- continue
- contours += new_contours[0:-1]
- image_height = len(image)
- image_width = len(image[0])
- rooms = []
- if centered:
- offset_x -= image_width // 2
- offset_y -= image_height // 2
- for contour in contours:
- for subcontour in contour:
- x, y, w, h = cv2.boundingRect(subcontour)
- box = Box2(offset_x + x,
- offset_y + y,
- offset_x + x + w,
- offset_y + y + h)
- rooms.append(box)
- return RoomPackBitmap(image_width, image_height, rooms)
- def main():
- parser = argparse.ArgumentParser(description='Calculate rooms from a greyscale bitmap')
- parser.add_argument('file', type=str,
- help='a greyscale bitmap')
- parser.add_argument('--center', action=argparse.BooleanOptionalAction,
- default=False,
- help='center the output coordinates')
- parser.add_argument('--offset', type=int,
- nargs=2,
- default=[0, 0],
- help='offset the output coordinates')
- args = parser.parse_args()
- result = analyze_bitmap(args.file, args.center, args.offset[0], args.offset[1])
- print(f" size: {result.width},{result.height}")
- print(" rooms:")
- for room in result.rooms:
- print(f" - {room.left},{room.bottom},{room.right},{room.top}")
- print("")
- print(f"Generated {len(result.rooms)} rooms.")
- if __name__ == "__main__":
- main()
|