python - Why does my script that converts a grayscale image mask of my map into 1px wide lines make line wider than 1px? - Stack

Script outputGrayscale rivermaskMy main problem is my script is still making parts of the river more

Script output

Grayscale rivermask

My main problem is my script is still making parts of the river more than 1px wide, particularly junctions and what i guess would be curves of 1px radius. Here is the script:

from PIL import Image
import numpy as np
from skimage import morphology
from scipy.ndimage import label

# File paths (update these to match your files)
RIVER_MASK_PATH = "river_mask.png"  # e.g., "river_mask.png"
OUTPUT_PATH = "river_map_output.png"  # e.g., "river_map_output.png"

# Load river mask as grayscale
river_img = Image.open(RIVER_MASK_PATH).convert("I")  # 16-bit grayscale (0-65535)
river_array = np.array(river_img, dtype=np.uint16)

# For 8-bit grayscale, use this instead:
# river_img = Image.open(RIVER_MASK_PATH).convert("L")  # 8-bit grayscale (0-255)
# river_array = np.array(river_img, dtype=np.uint8)

# Threshold to create a binary mask (river = True, background = False)
river_binary = river_array > 0

# Skeletonize to make rivers 1px wide
river_skeleton = morphology.skeletonize(river_binary)

# Function to convert to 4-directional connectivity
def convert_to_4connected(skeleton):
    height, width = skeleton.shape
    river_4dir = skeleton.copy()
    for y in range(height - 1):
        for x in range(width - 1):
            if skeleton[y, x]:
                # Check for diagonal connections
                if skeleton[y + 1, x + 1] and not (skeleton[y + 1, x] or skeleton[y, x + 1]):
                    # Break diagonal by adding an intermediate pixel
                    river_4dir[y + 1, x] = True  # Add vertical connection
                if skeleton[y + 1, x - 1] and not (skeleton[y + 1, x] or skeleton[y, x - 1]):
                    river_4dir[y + 1, x] = True
    return river_4dir

# Apply 4-directional connectivity
river_4dir = convert_to_4connected(river_skeleton)

# Remove small isolated rivers (≤5 pixels)
labeled_rivers, _ = label(river_4dir)
river_sizes = np.bincount(labeled_rivers.ravel())
small_rivers = np.where((river_sizes <= 5) & (river_sizes > 0))[0]
for label_id in small_rivers:
    river_4dir[labeled_rivers == label_id] = False

# Define CK3 river colors and width thresholds
def get_river_color(value, max_value=255):
    if max_value == 255:  # 8-bit
        if value <= 85:
            return (0, 255, 255)  # Narrow: Cyan
        elif value <= 170:
            return (0, 128, 255)  # Medium: Medium blue
        else:
            return (0, 0, 255)    # Wide: Pure blue
    else:  # 16-bit
        if value <= 10542:
            return (0, 255, 255)
        elif value <= 41720:
            return (0, 128, 255)
        else:
            return (0, 0, 255)

# Create a 3-channel color image
height, width = river_4dir.shape
river_map_color = np.zeros((height, width, 3), dtype=np.uint8)

# Assign colors to river pixels
max_value = 255 if river_array.dtype == np.uint8 else 65535
for y in range(height):
    for x in range(width):
        if river_4dir[y, x]:
            value = river_array[y, x]
            river_map_color[y, x] = get_river_color(value, max_value)

# Save the output as an RGB image
output_img = Image.fromarray(river_map_color, mode="RGB")
output_img.save(OUTPUT_PATH)

print(f"River map saved to {OUTPUT_PATH}")

Here is the link to the wiki page talking about rivermaps:

I've been stuck trying to fix this for a week now using all the ais (chatgpt, deepseek and grok) but can't really fix this issue.

Edit: I'm sorry if the question is not clear, let me clarify, essentially I need the resulting image to abide by ck3 rivermap rules. Specifically the perfect pixel rule. If you check the resulting image you'll see that there are parts of the rivers that are more than 2 pixels wide, particularly junctions. In the wiki there is an image example of how a rivermap should look (Ireland and part of Great Britain). I'm not a programmer by any means and it's my first time posting here so yeah my bad for not explaining the question better.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744222801a4563864.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信